1
(* $Id: netauth.ml 1543 2011-02-08 02:08:35Z gerd $ *)
4
let s_len = String.length s in
5
let u_len = String.length u in
7
let x = String.create s_len in
8
for k = 0 to s_len-1 do
9
x.[k] <- Char.chr ((Char.code s.[k]) lxor (Char.code u.[k]))
13
let hmac ~h ~b ~l ~k ~message =
14
if String.length k > b then
15
failwith "Netauth.hmac: key too long";
17
let k_padded = k ^ String.make (b - String.length k) '\000' in
18
let ipad = String.make b '\x36' in
19
let opad = String.make b '\x5c' in
20
h((xor_s k_padded opad) ^ (h ((xor_s k_padded ipad) ^ message)))
22
let add_1_complement s1 s2 =
23
(* Add two bitstrings s1 and s2 (in big-endian order) with one's complement
26
let l1 = String.length s1 in
27
let l2 = String.length s2 in
29
invalid_arg "Netauth.add_1_complement";
30
let r = String.make l1 '\000' in
32
for k = l1-1 downto 0 do
33
let i1 = Char.code s1.[k] in
34
let i2 = Char.code s2.[k] in
35
let sum = i1 + i2 + !carry in
36
r.[k] <- Char.chr (sum land 0xff);
37
carry := if sum > 0xff then 1 else 0;
40
for k = l1-1 downto 0 do
41
let i = Char.code r.[k] in
42
let sum = i + !carry in
43
r.[k] <- Char.chr (sum land 0xff);
44
carry := if sum > 0xff then 1 else 0;
50
let rotate_right n s =
51
(* Rotate the (big-endian) bitstring s to the right by n bits *)
52
let l = String.length s in
53
let b = 8 * l in (* bit length of s *)
55
let n' = if n' < 0 then b+n' else n' in
56
let u = String.create l in
57
(* First byte-shift the string, then bit-shift the remaining 0-7 bits *)
58
let bytes = n' lsr 3 in
59
let bits = n' land 7 in
60
String.blit s 0 u bytes (l-bytes);
62
String.blit s (l-bytes) u 0 bytes;
73
| _ -> assert false in
75
if bits > 0 && l > 0 then (
77
let x = Char.code u.[k] in
78
u.[k] <- Char.chr ((x lsr bits) lor (!carry lsl (8-bits)));
81
u.[0] <- Char.chr((Char.code u.[0]) lor (!carry lsl (8-bits)));
86
(** n-fold the number given by the bitstring s. The length of the number
87
is taken as the byte-length of s. n must be divisible by 8.
89
if n=0 || n mod 8 <> 0 then
90
invalid_arg "Netauth.n_fold";
92
let buf = Buffer.create (String.length s) in
93
let rec add_rot u len =
94
if len > 0 && len mod p = 0 then
97
Buffer.add_string buf u;
98
add_rot (rotate_right 13 u) (len+String.length u)
101
let blen = Buffer.length buf in
102
let s = ref (Buffer.sub buf 0 p) in
103
for k = 1 to (blen / p) - 1 do
104
s := add_1_complement !s (Buffer.sub buf (k*p) p)
116
let derive_key_rfc3961_simplified
117
~encrypt ~random_to_key ~block_size ~k ~usage ~key_type =
118
if block_size < 40 then
119
invalid_arg "Netauth.derive_key_rfc3961: bad block_size";
120
if k <= 0 || k mod 8 <> 0 then
121
invalid_arg "Netauth.derive_key_rfc3961: bad k";
122
if usage < 0 || usage > 255 then
123
invalid_arg "Netauth.derive_key_rfc3961: bad usage (only 0-255 allowed)";
125
String.make 3 '\000' ^ String.make 1 (Char.chr usage) ^
131
let usage_exp = n_fold block_size usage_s in
132
let kbuf = Buffer.create 80 in
133
let ki = ref (encrypt usage_exp) in
134
Buffer.add_string kbuf !ki;
135
while 8*(Buffer.length kbuf) < k do
137
Buffer.add_string kbuf !ki
139
let derived_random = k_truncate k (Buffer.contents kbuf) in
140
random_to_key derived_random