This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,175 @@
let pitable = [|
0xd9; 0x78; 0xf9; 0xc4; 0x19; 0xdd; 0xb5; 0xed; 0x28; 0xe9; 0xfd; 0x79; 0x4a; 0xa0; 0xd8; 0x9d;
0xc6; 0x7e; 0x37; 0x83; 0x2b; 0x76; 0x53; 0x8e; 0x62; 0x4c; 0x64; 0x88; 0x44; 0x8b; 0xfb; 0xa2;
0x17; 0x9a; 0x59; 0xf5; 0x87; 0xb3; 0x4f; 0x13; 0x61; 0x45; 0x6d; 0x8d; 0x09; 0x81; 0x7d; 0x32;
0xbd; 0x8f; 0x40; 0xeb; 0x86; 0xb7; 0x7b; 0x0b; 0xf0; 0x95; 0x21; 0x22; 0x5c; 0x6b; 0x4e; 0x82;
0x54; 0xd6; 0x65; 0x93; 0xce; 0x60; 0xb2; 0x1c; 0x73; 0x56; 0xc0; 0x14; 0xa7; 0x8c; 0xf1; 0xdc;
0x12; 0x75; 0xca; 0x1f; 0x3b; 0xbe; 0xe4; 0xd1; 0x42; 0x3d; 0xd4; 0x30; 0xa3; 0x3c; 0xb6; 0x26;
0x6f; 0xbf; 0x0e; 0xda; 0x46; 0x69; 0x07; 0x57; 0x27; 0xf2; 0x1d; 0x9b; 0xbc; 0x94; 0x43; 0x03;
0xf8; 0x11; 0xc7; 0xf6; 0x90; 0xef; 0x3e; 0xe7; 0x06; 0xc3; 0xd5; 0x2f; 0xc8; 0x66; 0x1e; 0xd7;
0x08; 0xe8; 0xea; 0xde; 0x80; 0x52; 0xee; 0xf7; 0x84; 0xaa; 0x72; 0xac; 0x35; 0x4d; 0x6a; 0x2a;
0x96; 0x1a; 0xd2; 0x71; 0x5a; 0x15; 0x49; 0x74; 0x4b; 0x9f; 0xd0; 0x5e; 0x04; 0x18; 0xa4; 0xec;
0xc2; 0xe0; 0x41; 0x6e; 0x0f; 0x51; 0xcb; 0xcc; 0x24; 0x91; 0xaf; 0x50; 0xa1; 0xf4; 0x70; 0x39;
0x99; 0x7c; 0x3a; 0x85; 0x23; 0xb8; 0xb4; 0x7a; 0xfc; 0x02; 0x36; 0x5b; 0x25; 0x55; 0x97; 0x31;
0x2d; 0x5d; 0xfa; 0x98; 0xe3; 0x8a; 0x92; 0xae; 0x05; 0xdf; 0x29; 0x10; 0x67; 0x6c; 0xba; 0xc9;
0xd3; 0x00; 0xe6; 0xcf; 0xe1; 0x9e; 0xa8; 0x2c; 0x63; 0x16; 0x01; 0x3f; 0x58; 0xe2; 0x89; 0xa9;
0x0d; 0x38; 0x34; 0x1b; 0xab; 0x33; 0xff; 0xb0; 0xbb; 0x48; 0x0c; 0x5f; 0xb9; 0xb1; 0xcd; 0x2e;
0xc5; 0xf3; 0xdb; 0x47; 0xe5; 0xa5; 0x9c; 0x77; 0x0a; 0xa6; 0x20; 0x68; 0xfe; 0x7f; 0xc1; 0xad
|]
(* effective is sometimes named t1 *)
let tm effective =
let t8 = (effective + 7) / 8 in
(* RFC says (TM = 255 MOD 2^(8 + effective - 8*T8)) *)
let bits = 8 + effective - 8 * t8 in
(* likely there's a smarter way to do this *)
let rec c acc = function
| 0 -> acc
| n -> c ((acc lsl 1) + 1) (pred n)
in
t8, c 0 bits
(* L[i] is the i-th byte of the key; K[i] is the i-th 16-bit-word of the key *)
let key_expansion effective key =
(* result is a 128 byte key, where we need the words.. *)
let t = String.length key in
let l = Array.init 128 (fun idx -> if idx < t then String.get_uint8 key idx else 0) in
let t8, tm = tm effective in
for i = t to 127 do
l.(i) <- pitable.((l.(i - 1) + l.(i - t)) mod 256)
done;
l.(128 - t8) <- pitable.(l.(128 - t8) land tm);
for i = 127 - t8 downto 0 do
l.(i) <- pitable.(l.(i + 1) lxor l.(i + t8));
done;
Array.init 64 (fun idx -> l.(2 * idx) + 256 * l.(2 * idx + 1))
let mod16 f = 0xFFFF land f
let rol16 x k = mod16 ((x lsl k) lor (x lsr (16 - k)))
let ror16 x k = mod16 ((x lsr k) lor (x lsl (16 - k)))
let not16 x = mod16 (lnot x)
let s = Array.init 4 (function 0 -> 1 | 1 -> 2 | 2 -> 3 | 3 -> 5 | _ -> assert false)
let pmod a =
let b = 4 in
let r = a mod b in
if r < 0 then (r + b) mod b else r
(* only used for encryption which we don't support
let mix r i k j =
r.(i) <- mod16 (r.(i) + k.(j) + r.(pmod (i - 1)) land r.(pmod (i - 2)) +
(not16 r.(pmod (i - 1))) land r.(pmod (i - 3)));
let j = succ j in
r.(i) <- rol16 r.(i) s.(i);
j
let mix_round r k j =
let j' = mix r 0 k j in
let j'' = mix r 1 k j' in
let j''' = mix r 2 k j'' in
let j'''' = mix r 3 k j''' in
j''''
let mash r i k =
r.(i) <- mod16 (r.(i) + k.(r.(pmod (i - 1)) land 63))
let mash_round r k =
mash r 0 k;
mash r 1 k;
mash r 2 k;
mash r 3 k
let encrypt_one ~key ~data =
let r = Array.init 4 (fun idx -> Cstruct.LE.get_uint16 data (idx * 2)) in
let j = 0 in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
mash_round r key;
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
mash_round r key;
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let j = mix_round r key j in
let _j = mix_round r key j in
let out = Cstruct.create 8 in
Cstruct.LE.set_uint16 out 0 r.(0);
Cstruct.LE.set_uint16 out 2 r.(1);
Cstruct.LE.set_uint16 out 4 r.(2);
Cstruct.LE.set_uint16 out 6 r.(3);
out
*)
let r_mix r i k j =
r.(i) <- ror16 r.(i) s.(i);
r.(i) <- mod16 (r.(i) - k.(j) -
(r.(pmod (i - 1)) land r.(pmod (i - 2))) -
(not16 r.(pmod (i - 1)) land (r.(pmod (i - 3)))));
pred j
let r_mix_round r k j =
let j' = r_mix r 3 k j in
let j'' = r_mix r 2 k j' in
let j''' = r_mix r 1 k j'' in
let j'''' = r_mix r 0 k j''' in
j''''
let r_mash r i k =
r.(i) <- mod16 (r.(i) - k.(r.(pmod (i - 1)) land 63))
let r_mash_round r k =
r_mash r 3 k;
r_mash r 2 k;
r_mash r 1 k;
r_mash r 0 k
let decrypt_one ~key ~data ?(off = 0) dst =
let r = Array.init 4 (fun idx -> String.get_uint16_le data (off + idx * 2)) in
let j = 63 in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
r_mash_round r key;
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
r_mash_round r key;
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let j = r_mix_round r key j in
let _j = r_mix_round r key j in
Bytes.set_uint16_le dst (off + 0) r.(0);
Bytes.set_uint16_le dst (off + 2) r.(1);
Bytes.set_uint16_le dst (off + 4) r.(2);
Bytes.set_uint16_le dst (off + 6) r.(3)
let decrypt_cbc ?(effective = 128) ~key ~iv data =
let block = 8 in
let key = key_expansion effective key in
let l = String.length data in
let dst = Bytes.create l in
for i = 0 to pred ((l + pred block) / block) do
decrypt_one ~key ~data ~off:(i * block) dst
done;
Mirage_crypto.Uncommon.unsafe_xor_into iv ~src_off:0 dst ~dst_off:0 block;
Mirage_crypto.Uncommon.unsafe_xor_into data ~src_off:0 dst ~dst_off:block (l - block);
Bytes.unsafe_to_string dst