upstream: https://github.com/mirage/mirage-crypto
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove renamed packages, add new CCSDS standards

Remove ocaml-ccsds-122 and ocaml-ccsds-123 (renamed to ocaml-idc and
ocaml-hcomp). Add ocaml-csts, ocaml-mal, ocaml-spacefibre packages.
Update ocaml-xmlt, ocaml-contact, ocaml-crypto (pure AES + JS stubs).

+824
+488
src/aes_pure.ml
··· 1 + (** Pure OCaml AES implementation using T-tables. 2 + 3 + Same algorithm as aes_generic.c (public domain, Philip J. Erdelsky). Uses 4 + Int32 for 32-bit operations so it works on both 64-bit native and 32-bit 5 + targets (js_of_ocaml, wasm_of_ocaml). *) 6 + 7 + (* S-box from FIPS 197 *) 8 + let sbox = 9 + [| 10 + 0x63; 11 + 0x7c; 12 + 0x77; 13 + 0x7b; 14 + 0xf2; 15 + 0x6b; 16 + 0x6f; 17 + 0xc5; 18 + 0x30; 19 + 0x01; 20 + 0x67; 21 + 0x2b; 22 + 0xfe; 23 + 0xd7; 24 + 0xab; 25 + 0x76; 26 + 0xca; 27 + 0x82; 28 + 0xc9; 29 + 0x7d; 30 + 0xfa; 31 + 0x59; 32 + 0x47; 33 + 0xf0; 34 + 0xad; 35 + 0xd4; 36 + 0xa2; 37 + 0xaf; 38 + 0x9c; 39 + 0xa4; 40 + 0x72; 41 + 0xc0; 42 + 0xb7; 43 + 0xfd; 44 + 0x93; 45 + 0x26; 46 + 0x36; 47 + 0x3f; 48 + 0xf7; 49 + 0xcc; 50 + 0x34; 51 + 0xa5; 52 + 0xe5; 53 + 0xf1; 54 + 0x71; 55 + 0xd8; 56 + 0x31; 57 + 0x15; 58 + 0x04; 59 + 0xc7; 60 + 0x23; 61 + 0xc3; 62 + 0x18; 63 + 0x96; 64 + 0x05; 65 + 0x9a; 66 + 0x07; 67 + 0x12; 68 + 0x80; 69 + 0xe2; 70 + 0xeb; 71 + 0x27; 72 + 0xb2; 73 + 0x75; 74 + 0x09; 75 + 0x83; 76 + 0x2c; 77 + 0x1a; 78 + 0x1b; 79 + 0x6e; 80 + 0x5a; 81 + 0xa0; 82 + 0x52; 83 + 0x3b; 84 + 0xd6; 85 + 0xb3; 86 + 0x29; 87 + 0xe3; 88 + 0x2f; 89 + 0x84; 90 + 0x53; 91 + 0xd1; 92 + 0x00; 93 + 0xed; 94 + 0x20; 95 + 0xfc; 96 + 0xb1; 97 + 0x5b; 98 + 0x6a; 99 + 0xcb; 100 + 0xbe; 101 + 0x39; 102 + 0x4a; 103 + 0x4c; 104 + 0x58; 105 + 0xcf; 106 + 0xd0; 107 + 0xef; 108 + 0xaa; 109 + 0xfb; 110 + 0x43; 111 + 0x4d; 112 + 0x33; 113 + 0x85; 114 + 0x45; 115 + 0xf9; 116 + 0x02; 117 + 0x7f; 118 + 0x50; 119 + 0x3c; 120 + 0x9f; 121 + 0xa8; 122 + 0x51; 123 + 0xa3; 124 + 0x40; 125 + 0x8f; 126 + 0x92; 127 + 0x9d; 128 + 0x38; 129 + 0xf5; 130 + 0xbc; 131 + 0xb6; 132 + 0xda; 133 + 0x21; 134 + 0x10; 135 + 0xff; 136 + 0xf3; 137 + 0xd2; 138 + 0xcd; 139 + 0x0c; 140 + 0x13; 141 + 0xec; 142 + 0x5f; 143 + 0x97; 144 + 0x44; 145 + 0x17; 146 + 0xc4; 147 + 0xa7; 148 + 0x7e; 149 + 0x3d; 150 + 0x64; 151 + 0x5d; 152 + 0x19; 153 + 0x73; 154 + 0x60; 155 + 0x81; 156 + 0x4f; 157 + 0xdc; 158 + 0x22; 159 + 0x2a; 160 + 0x90; 161 + 0x88; 162 + 0x46; 163 + 0xee; 164 + 0xb8; 165 + 0x14; 166 + 0xde; 167 + 0x5e; 168 + 0x0b; 169 + 0xdb; 170 + 0xe0; 171 + 0x32; 172 + 0x3a; 173 + 0x0a; 174 + 0x49; 175 + 0x06; 176 + 0x24; 177 + 0x5c; 178 + 0xc2; 179 + 0xd3; 180 + 0xac; 181 + 0x62; 182 + 0x91; 183 + 0x95; 184 + 0xe4; 185 + 0x79; 186 + 0xe7; 187 + 0xc8; 188 + 0x37; 189 + 0x6d; 190 + 0x8d; 191 + 0xd5; 192 + 0x4e; 193 + 0xa9; 194 + 0x6c; 195 + 0x56; 196 + 0xf4; 197 + 0xea; 198 + 0x65; 199 + 0x7a; 200 + 0xae; 201 + 0x08; 202 + 0xba; 203 + 0x78; 204 + 0x25; 205 + 0x2e; 206 + 0x1c; 207 + 0xa6; 208 + 0xb4; 209 + 0xc6; 210 + 0xe8; 211 + 0xdd; 212 + 0x74; 213 + 0x1f; 214 + 0x4b; 215 + 0xbd; 216 + 0x8b; 217 + 0x8a; 218 + 0x70; 219 + 0x3e; 220 + 0xb5; 221 + 0x66; 222 + 0x48; 223 + 0x03; 224 + 0xf6; 225 + 0x0e; 226 + 0x61; 227 + 0x35; 228 + 0x57; 229 + 0xb9; 230 + 0x86; 231 + 0xc1; 232 + 0x1d; 233 + 0x9e; 234 + 0xe1; 235 + 0xf8; 236 + 0x98; 237 + 0x11; 238 + 0x69; 239 + 0xd9; 240 + 0x8e; 241 + 0x94; 242 + 0x9b; 243 + 0x1e; 244 + 0x87; 245 + 0xe9; 246 + 0xce; 247 + 0x55; 248 + 0x28; 249 + 0xdf; 250 + 0x8c; 251 + 0xa1; 252 + 0x89; 253 + 0x0d; 254 + 0xbf; 255 + 0xe6; 256 + 0x42; 257 + 0x68; 258 + 0x41; 259 + 0x99; 260 + 0x2d; 261 + 0x0f; 262 + 0xb0; 263 + 0x54; 264 + 0xbb; 265 + 0x16; 266 + |] 267 + 268 + (* GF(2^8) multiply by 2 *) 269 + let xtime x = 270 + let x2 = (x lsl 1) land 0xff in 271 + if x land 0x80 <> 0 then x2 lxor 0x1b else x2 272 + 273 + (* Build T-table entry: [x2, x, x, x3] as Int32 *) 274 + let te0 = 275 + Array.init 256 (fun i -> 276 + let s = sbox.(i) in 277 + let x2 = xtime s in 278 + let x3 = x2 lxor s in 279 + Int32.logor 280 + (Int32.logor 281 + (Int32.shift_left (Int32.of_int x2) 24) 282 + (Int32.shift_left (Int32.of_int s) 16)) 283 + (Int32.logor (Int32.shift_left (Int32.of_int s) 8) (Int32.of_int x3))) 284 + 285 + (* Rotate T-table entries for Te1, Te2, Te3 *) 286 + let rot8 x = 287 + Int32.logor 288 + (Int32.shift_right_logical x 8) 289 + (Int32.shift_left (Int32.logand x 0xffl) 24) 290 + 291 + let te1 = Array.map rot8 te0 292 + let te2 = Array.map rot8 te1 293 + let te3 = Array.map rot8 te2 294 + 295 + (* Round constant *) 296 + let rcon = [| 0x01; 0x02; 0x04; 0x08; 0x10; 0x20; 0x40; 0x80; 0x1b; 0x36 |] 297 + 298 + (* Key schedule: returns round keys as Int32 array *) 299 + let expand_key key = 300 + let klen = String.length key in 301 + let nk = klen / 4 in 302 + let rounds = 303 + match klen with 304 + | 16 -> 10 305 + | 24 -> 12 306 + | 32 -> 14 307 + | _ -> invalid_arg "AES key" 308 + in 309 + let nb = 4 in 310 + let rk = Array.make (nb * (rounds + 1)) 0l in 311 + for i = 0 to nk - 1 do 312 + rk.(i) <- 313 + Int32.logor 314 + (Int32.logor 315 + (Int32.shift_left (Int32.of_int (Char.code key.[i * 4])) 24) 316 + (Int32.shift_left (Int32.of_int (Char.code key.[(i * 4) + 1])) 16)) 317 + (Int32.logor 318 + (Int32.shift_left (Int32.of_int (Char.code key.[(i * 4) + 2])) 8) 319 + (Int32.of_int (Char.code key.[(i * 4) + 3]))) 320 + done; 321 + let ri = ref 0 in 322 + for i = nk to (nb * (rounds + 1)) - 1 do 323 + let prev = rk.(i - 1) in 324 + let t = 325 + if i mod nk = 0 then begin 326 + let r = !ri in 327 + incr ri; 328 + let b0 = 329 + Int32.of_int 330 + (sbox.(Int32.to_int 331 + (Int32.logand (Int32.shift_right_logical prev 16) 0xffl)) 332 + lxor rcon.(r)) 333 + in 334 + let b1 = 335 + Int32.of_int 336 + sbox.(Int32.to_int 337 + (Int32.logand (Int32.shift_right_logical prev 8) 0xffl)) 338 + in 339 + let b2 = Int32.of_int sbox.(Int32.to_int (Int32.logand prev 0xffl)) in 340 + let b3 = 341 + Int32.of_int 342 + sbox.(Int32.to_int 343 + (Int32.logand (Int32.shift_right_logical prev 24) 0xffl)) 344 + in 345 + Int32.logor 346 + (Int32.logor (Int32.shift_left b0 24) (Int32.shift_left b1 16)) 347 + (Int32.logor (Int32.shift_left b2 8) b3) 348 + end 349 + else if nk > 6 && i mod nk = 4 then begin 350 + let b0 = 351 + Int32.of_int 352 + sbox.(Int32.to_int 353 + (Int32.logand (Int32.shift_right_logical prev 24) 0xffl)) 354 + in 355 + let b1 = 356 + Int32.of_int 357 + sbox.(Int32.to_int 358 + (Int32.logand (Int32.shift_right_logical prev 16) 0xffl)) 359 + in 360 + let b2 = 361 + Int32.of_int 362 + sbox.(Int32.to_int 363 + (Int32.logand (Int32.shift_right_logical prev 8) 0xffl)) 364 + in 365 + let b3 = Int32.of_int sbox.(Int32.to_int (Int32.logand prev 0xffl)) in 366 + Int32.logor 367 + (Int32.logor (Int32.shift_left b0 24) (Int32.shift_left b1 16)) 368 + (Int32.logor (Int32.shift_left b2 8) b3) 369 + end 370 + else prev 371 + in 372 + rk.(i) <- Int32.logxor rk.(i - nk) t 373 + done; 374 + (rk, rounds) 375 + 376 + (* Encrypt one 16-byte block *) 377 + let encrypt_block rk rounds src soff dst doff = 378 + let ( lxor ) = Int32.logxor in 379 + let ( land ) = Int32.logand in 380 + let ( lsr ) = Int32.shift_right_logical in 381 + let get_byte32 w shift = Int32.to_int ((w lsr shift) land 0xffl) in 382 + let get32 buf off = 383 + Int32.logor 384 + (Int32.logor 385 + (Int32.shift_left (Int32.of_int (Char.code buf.[off])) 24) 386 + (Int32.shift_left (Int32.of_int (Char.code buf.[off + 1])) 16)) 387 + (Int32.logor 388 + (Int32.shift_left (Int32.of_int (Char.code buf.[off + 2])) 8) 389 + (Int32.of_int (Char.code buf.[off + 3]))) 390 + in 391 + let put32 buf off w = 392 + Bytes.set buf off (Char.chr (get_byte32 w 24)); 393 + Bytes.set buf (off + 1) (Char.chr (get_byte32 w 16)); 394 + Bytes.set buf (off + 2) (Char.chr (get_byte32 w 8)); 395 + Bytes.set buf (off + 3) (Char.chr (get_byte32 w 0)) 396 + in 397 + let s0 = ref (get32 src soff lxor rk.(0)) in 398 + let s1 = ref (get32 src (soff + 4) lxor rk.(1)) in 399 + let s2 = ref (get32 src (soff + 8) lxor rk.(2)) in 400 + let s3 = ref (get32 src (soff + 12) lxor rk.(3)) in 401 + let rki = ref 4 in 402 + for _ = 1 to rounds - 1 do 403 + let t0 = 404 + te0.(get_byte32 !s0 24) 405 + lxor te1.(get_byte32 !s1 16) 406 + lxor te2.(get_byte32 !s2 8) 407 + lxor te3.(get_byte32 !s3 0) 408 + lxor rk.(!rki) 409 + in 410 + let t1 = 411 + te0.(get_byte32 !s1 24) 412 + lxor te1.(get_byte32 !s2 16) 413 + lxor te2.(get_byte32 !s3 8) 414 + lxor te3.(get_byte32 !s0 0) 415 + lxor rk.(!rki + 1) 416 + in 417 + let t2 = 418 + te0.(get_byte32 !s2 24) 419 + lxor te1.(get_byte32 !s3 16) 420 + lxor te2.(get_byte32 !s0 8) 421 + lxor te3.(get_byte32 !s1 0) 422 + lxor rk.(!rki + 2) 423 + in 424 + let t3 = 425 + te0.(get_byte32 !s3 24) 426 + lxor te1.(get_byte32 !s0 16) 427 + lxor te2.(get_byte32 !s1 8) 428 + lxor te3.(get_byte32 !s2 0) 429 + lxor rk.(!rki + 3) 430 + in 431 + s0 := t0; 432 + s1 := t1; 433 + s2 := t2; 434 + s3 := t3; 435 + rki := !rki + 4 436 + done; 437 + (* Final round: SubBytes + ShiftRows + AddRoundKey, no MixColumns *) 438 + let sb i = Int32.of_int sbox.(i) in 439 + let t0 = 440 + Int32.logor 441 + (Int32.logor 442 + (Int32.shift_left (sb (get_byte32 !s0 24)) 24) 443 + (Int32.shift_left (sb (get_byte32 !s1 16)) 16)) 444 + (Int32.logor 445 + (Int32.shift_left (sb (get_byte32 !s2 8)) 8) 446 + (sb (get_byte32 !s3 0))) 447 + lxor rk.(!rki) 448 + in 449 + let t1 = 450 + Int32.logor 451 + (Int32.logor 452 + (Int32.shift_left (sb (get_byte32 !s1 24)) 24) 453 + (Int32.shift_left (sb (get_byte32 !s2 16)) 16)) 454 + (Int32.logor 455 + (Int32.shift_left (sb (get_byte32 !s3 8)) 8) 456 + (sb (get_byte32 !s0 0))) 457 + lxor rk.(!rki + 1) 458 + in 459 + let t2 = 460 + Int32.logor 461 + (Int32.logor 462 + (Int32.shift_left (sb (get_byte32 !s2 24)) 24) 463 + (Int32.shift_left (sb (get_byte32 !s3 16)) 16)) 464 + (Int32.logor 465 + (Int32.shift_left (sb (get_byte32 !s0 8)) 8) 466 + (sb (get_byte32 !s1 0))) 467 + lxor rk.(!rki + 2) 468 + in 469 + let t3 = 470 + Int32.logor 471 + (Int32.logor 472 + (Int32.shift_left (sb (get_byte32 !s3 24)) 24) 473 + (Int32.shift_left (sb (get_byte32 !s0 16)) 16)) 474 + (Int32.logor 475 + (Int32.shift_left (sb (get_byte32 !s1 8)) 8) 476 + (sb (get_byte32 !s2 0))) 477 + lxor rk.(!rki + 3) 478 + in 479 + put32 dst doff t0; 480 + put32 dst (doff + 4) t1; 481 + put32 dst (doff + 8) t2; 482 + put32 dst (doff + 12) t3 483 + 484 + (* Multi-block encrypt matching the mc_aes_enc_bc interface *) 485 + let encrypt_ecb rk rounds src soff dst doff blocks = 486 + for b = 0 to blocks - 1 do 487 + encrypt_block rk rounds src (soff + (b * 16)) dst (doff + (b * 16)) 488 + done
+334
src/crypto_stubs.js
··· 1 + // js_of_ocaml stubs for mirage-crypto / ocaml-crypto 2 + // 3 + // Pure JavaScript implementations of the C primitives. AES uses 4 + // lookup tables (same algorithm as the C generic path). Performance 5 + // is adequate for small payloads (demo/testing, not production). 6 + 7 + // ---- Helpers ---- 8 + 9 + //Provides: mc_detect_cpu_features 10 + function mc_detect_cpu_features(unit) { return 0; } 11 + 12 + //Provides: mc_entropy_detect 13 + function mc_entropy_detect(unit) { return 0; } 14 + 15 + //Provides: mc_misc_mode 16 + function mc_misc_mode(unit) { return 0; /* generic */ } 17 + 18 + //Provides: mc_aes_mode 19 + function mc_aes_mode(unit) { return 0; /* generic */ } 20 + 21 + //Provides: mc_ghash_mode 22 + function mc_ghash_mode(unit) { return 0; /* generic */ } 23 + 24 + // ---- XOR ---- 25 + 26 + //Provides: mc_xor_into_bytes 27 + function mc_xor_into_bytes(src, soff, dst, doff, len) { 28 + for (var i = 0; i < len; i++) { 29 + dst[doff + i] ^= src.charCodeAt(soff + i) & 0xff; 30 + } 31 + } 32 + 33 + // ---- Counter increment ---- 34 + 35 + //Provides: mc_count_8_be 36 + function mc_count_8_be(ctr, dst, off, blocks) { 37 + for (var b = 0; b < blocks; b++) { 38 + for (var i = 0; i < 8; i++) dst[off + b * 8 + i] = ctr[i]; 39 + for (var i = 7; i >= 0; i--) { 40 + ctr[i] = (ctr[i] + 1) & 0xff; 41 + if (ctr[i] !== 0) break; 42 + } 43 + } 44 + } 45 + 46 + //Provides: mc_count_16_be 47 + function mc_count_16_be(ctr, dst, off, blocks) { 48 + for (var b = 0; b < blocks; b++) { 49 + for (var i = 0; i < 16; i++) dst[off + b * 16 + i] = ctr[i]; 50 + for (var i = 15; i >= 0; i--) { 51 + ctr[i] = (ctr[i] + 1) & 0xff; 52 + if (ctr[i] !== 0) break; 53 + } 54 + } 55 + } 56 + 57 + //Provides: mc_count_16_be_4 58 + function mc_count_16_be_4(ctr, dst, off, blocks) { 59 + // Same as mc_count_16_be but increments only the last 4 bytes 60 + for (var b = 0; b < blocks; b++) { 61 + for (var i = 0; i < 16; i++) dst[off + b * 16 + i] = ctr[i]; 62 + for (var i = 15; i >= 12; i--) { 63 + ctr[i] = (ctr[i] + 1) & 0xff; 64 + if (ctr[i] !== 0) break; 65 + } 66 + } 67 + } 68 + 69 + // ---- AES ---- 70 + // Rijndael S-box and key schedule, standard lookup-table implementation. 71 + 72 + //Provides: _aes_sbox 73 + var _aes_sbox = null; 74 + //Provides: _aes_Te 75 + var _aes_Te = null; 76 + 77 + //Provides: _aes_init_tables 78 + //Requires: _aes_sbox, _aes_Te 79 + function _aes_init_tables() { 80 + if (_aes_sbox) return; 81 + // Generate S-box 82 + var sbox = new Uint8Array(256); 83 + var inv = new Uint8Array(256); 84 + var p = 1, q = 1; 85 + do { 86 + p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0); 87 + p &= 0xff; 88 + q ^= q << 1; q ^= q << 2; q ^= q << 4; 89 + q ^= q & 0x80 ? 0x09 : 0; q &= 0xff; 90 + var v = q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ 91 + ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)); 92 + v = (v ^ 0x63) & 0xff; 93 + sbox[p] = v; inv[v] = p; 94 + } while (p !== 1); 95 + sbox[0] = 0x63; inv[0x63] = 0; 96 + _aes_sbox = sbox; _aes_inv_sbox = inv; 97 + 98 + // Generate T-tables for encryption 99 + var Te0 = new Uint32Array(256), Te1 = new Uint32Array(256); 100 + var Te2 = new Uint32Array(256), Te3 = new Uint32Array(256); 101 + var Td0 = new Uint32Array(256), Td1 = new Uint32Array(256); 102 + var Td2 = new Uint32Array(256), Td3 = new Uint32Array(256); 103 + for (var i = 0; i < 256; i++) { 104 + var s = sbox[i]; 105 + var x2 = ((s << 1) ^ (s & 0x80 ? 0x1b : 0)) & 0xff; 106 + var x3 = x2 ^ s; 107 + Te0[i] = (x2 << 24) | (s << 16) | (s << 8) | x3; 108 + Te1[i] = (x3 << 24) | (x2 << 16) | (s << 8) | s; 109 + Te2[i] = (s << 24) | (x3 << 16) | (x2 << 8) | s; 110 + Te3[i] = (s << 24) | (s << 16) | (x3 << 8) | x2; 111 + 112 + var si = inv[i] || 0; 113 + if (i === 0) si = 0; 114 + var s9 = si, sb = si, sd = si, se = si; 115 + // Multiply in GF(2^8) 116 + function gmul(a, b) { 117 + var r = 0; 118 + for (var j = 0; j < 8; j++) { 119 + if (b & 1) r ^= a; 120 + var hi = a & 0x80; 121 + a = (a << 1) & 0xff; 122 + if (hi) a ^= 0x1b; 123 + b >>= 1; 124 + } 125 + return r; 126 + } 127 + s9 = gmul(si, 9); sb = gmul(si, 0xb); sd = gmul(si, 0xd); se = gmul(si, 0xe); 128 + Td0[i] = (se << 24) | (s9 << 16) | (sd << 8) | sb; 129 + Td1[i] = (sb << 24) | (se << 16) | (s9 << 8) | sd; 130 + Td2[i] = (sd << 24) | (sb << 16) | (se << 8) | s9; 131 + Td3[i] = (s9 << 24) | (sd << 16) | (sb << 8) | se; 132 + } 133 + _aes_Te = [Te0, Te1, Te2, Te3]; 134 + _aes_Td = [Td0, Td1, Td2, Td3]; 135 + } 136 + 137 + //Provides: mc_aes_rk_size 138 + function mc_aes_rk_size(rounds) { 139 + return (rounds + 1) * 16; 140 + } 141 + 142 + //Provides: mc_aes_derive_e_key 143 + //Requires: _aes_init_tables 144 + function mc_aes_derive_e_key(key, rk, rounds) { 145 + _aes_init_tables(); 146 + var nk = key.length / 4; 147 + var nb = 4; 148 + // Copy key into rk as 32-bit words 149 + for (var i = 0; i < nk; i++) { 150 + rk[i*4] = key.charCodeAt(i*4); 151 + rk[i*4+1] = key.charCodeAt(i*4+1); 152 + rk[i*4+2] = key.charCodeAt(i*4+2); 153 + rk[i*4+3] = key.charCodeAt(i*4+3); 154 + } 155 + var rcon = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; 156 + var ri = 0; 157 + for (var i = nk; i < nb * (rounds + 1); i++) { 158 + var t0 = rk[(i-1)*4], t1 = rk[(i-1)*4+1], t2 = rk[(i-1)*4+2], t3 = rk[(i-1)*4+3]; 159 + if (i % nk === 0) { 160 + var tmp = t0; 161 + t0 = _aes_sbox[t1] ^ rcon[ri++]; t1 = _aes_sbox[t2]; 162 + t2 = _aes_sbox[t3]; t3 = _aes_sbox[tmp]; 163 + } else if (nk > 6 && i % nk === 4) { 164 + t0 = _aes_sbox[t0]; t1 = _aes_sbox[t1]; 165 + t2 = _aes_sbox[t2]; t3 = _aes_sbox[t3]; 166 + } 167 + rk[i*4] = rk[(i-nk)*4] ^ t0; 168 + rk[i*4+1] = rk[(i-nk)*4+1] ^ t1; 169 + rk[i*4+2] = rk[(i-nk)*4+2] ^ t2; 170 + rk[i*4+3] = rk[(i-nk)*4+3] ^ t3; 171 + } 172 + } 173 + 174 + //Provides: mc_aes_derive_d_key 175 + //Requires: mc_aes_derive_e_key 176 + function mc_aes_derive_d_key(key, rk, rounds, ekey_opt) { 177 + // For decryption key schedule, first derive encryption then invert 178 + // (simplified: just derive encryption key for now — GCM only uses encrypt) 179 + mc_aes_derive_e_key(key, rk, rounds); 180 + } 181 + 182 + //Provides: mc_aes_enc_bc 183 + //Requires: _aes_init_tables 184 + function mc_aes_enc_bc(src, soff, dst, doff, rk, rounds, blocks) { 185 + _aes_init_tables(); 186 + var Te0 = _aes_Te[0], Te1 = _aes_Te[1], Te2 = _aes_Te[2], Te3 = _aes_Te[3]; 187 + for (var b = 0; b < blocks; b++) { 188 + var bo = b * 16; 189 + // Read input block 190 + var s0 = (src.charCodeAt(soff+bo)<<24)|(src.charCodeAt(soff+bo+1)<<16)| 191 + (src.charCodeAt(soff+bo+2)<<8)|src.charCodeAt(soff+bo+3); 192 + var s1 = (src.charCodeAt(soff+bo+4)<<24)|(src.charCodeAt(soff+bo+5)<<16)| 193 + (src.charCodeAt(soff+bo+6)<<8)|src.charCodeAt(soff+bo+7); 194 + var s2 = (src.charCodeAt(soff+bo+8)<<24)|(src.charCodeAt(soff+bo+9)<<16)| 195 + (src.charCodeAt(soff+bo+10)<<8)|src.charCodeAt(soff+bo+11); 196 + var s3 = (src.charCodeAt(soff+bo+12)<<24)|(src.charCodeAt(soff+bo+13)<<16)| 197 + (src.charCodeAt(soff+bo+14)<<8)|src.charCodeAt(soff+bo+15); 198 + // Add round key 0 199 + var rko = 0; 200 + s0 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 201 + s1 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 202 + s2 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 203 + s3 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 204 + // Rounds 1..Nr-1 205 + for (var r = 1; r < rounds; r++) { 206 + var t0 = Te0[(s0>>>24)&0xff] ^ Te1[(s1>>>16)&0xff] ^ Te2[(s2>>>8)&0xff] ^ Te3[s3&0xff]; 207 + var t1 = Te0[(s1>>>24)&0xff] ^ Te1[(s2>>>16)&0xff] ^ Te2[(s3>>>8)&0xff] ^ Te3[s0&0xff]; 208 + var t2 = Te0[(s2>>>24)&0xff] ^ Te1[(s3>>>16)&0xff] ^ Te2[(s0>>>8)&0xff] ^ Te3[s1&0xff]; 209 + var t3 = Te0[(s3>>>24)&0xff] ^ Te1[(s0>>>16)&0xff] ^ Te2[(s1>>>8)&0xff] ^ Te3[s2&0xff]; 210 + t0 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 211 + t1 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 212 + t2 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 213 + t3 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 214 + s0 = t0; s1 = t1; s2 = t2; s3 = t3; 215 + } 216 + // Final round (no MixColumns) 217 + var t0 = ((_aes_sbox[(s0>>>24)&0xff]<<24)|(_aes_sbox[(s1>>>16)&0xff]<<16)| 218 + (_aes_sbox[(s2>>>8)&0xff]<<8)|_aes_sbox[s3&0xff]); 219 + var t1 = ((_aes_sbox[(s1>>>24)&0xff]<<24)|(_aes_sbox[(s2>>>16)&0xff]<<16)| 220 + (_aes_sbox[(s3>>>8)&0xff]<<8)|_aes_sbox[s0&0xff]); 221 + var t2 = ((_aes_sbox[(s2>>>24)&0xff]<<24)|(_aes_sbox[(s3>>>16)&0xff]<<16)| 222 + (_aes_sbox[(s0>>>8)&0xff]<<8)|_aes_sbox[s1&0xff]); 223 + var t3 = ((_aes_sbox[(s3>>>24)&0xff]<<24)|(_aes_sbox[(s0>>>16)&0xff]<<16)| 224 + (_aes_sbox[(s1>>>8)&0xff]<<8)|_aes_sbox[s2&0xff]); 225 + t0 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 226 + t1 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 227 + t2 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 228 + t3 ^= (rk[rko]<<24)|(rk[rko+1]<<16)|(rk[rko+2]<<8)|rk[rko+3]; rko+=4; 229 + // Write output 230 + dst[doff+bo]=(t0>>>24)&0xff; dst[doff+bo+1]=(t0>>>16)&0xff; 231 + dst[doff+bo+2]=(t0>>>8)&0xff; dst[doff+bo+3]=t0&0xff; 232 + dst[doff+bo+4]=(t1>>>24)&0xff; dst[doff+bo+5]=(t1>>>16)&0xff; 233 + dst[doff+bo+6]=(t1>>>8)&0xff; dst[doff+bo+7]=t1&0xff; 234 + dst[doff+bo+8]=(t2>>>24)&0xff; dst[doff+bo+9]=(t2>>>16)&0xff; 235 + dst[doff+bo+10]=(t2>>>8)&0xff; dst[doff+bo+11]=t2&0xff; 236 + dst[doff+bo+12]=(t3>>>24)&0xff; dst[doff+bo+13]=(t3>>>16)&0xff; 237 + dst[doff+bo+14]=(t3>>>8)&0xff; dst[doff+bo+15]=t3&0xff; 238 + } 239 + } 240 + 241 + //Provides: mc_aes_dec_bc 242 + //Requires: mc_aes_enc_bc 243 + function mc_aes_dec_bc(src, soff, dst, doff, rk, rounds, blocks) { 244 + // TODO: proper AES decryption. For GCM we only need encrypt. 245 + // Stub that prevents crash; actual GCM decrypt uses encrypt direction. 246 + mc_aes_enc_bc(src, soff, dst, doff, rk, rounds, blocks); 247 + } 248 + 249 + // ---- DES (stub only — not used by SDLS/GCM) ---- 250 + 251 + //Provides: mc_des_key_size 252 + function mc_des_key_size(unit) { return 128; } 253 + 254 + //Provides: mc_des_des3key 255 + function mc_des_des3key(key, mode, ek) { /* stub */ } 256 + 257 + //Provides: mc_des_ddes_bc 258 + function mc_des_ddes_bc(key, koff, dst, doff, mode, src) { /* stub */ } 259 + 260 + // ---- ChaCha20 (stub — not used by SDLS/GCM) ---- 261 + 262 + //Provides: mc_chacha_round 263 + function mc_chacha_round(count, state, output, off) { /* stub */ } 264 + 265 + // ---- Poly1305 (stub — not used by AES-GCM) ---- 266 + 267 + //Provides: mc_poly1305_ctx_size 268 + function mc_poly1305_ctx_size(unit) { return 256; } 269 + 270 + //Provides: mc_poly1305_mac_size 271 + function mc_poly1305_mac_size(unit) { return 16; } 272 + 273 + //Provides: mc_poly1305_init 274 + function mc_poly1305_init(ctx, key) { /* stub */ } 275 + 276 + //Provides: mc_poly1305_update 277 + function mc_poly1305_update(ctx, data, off, len) { /* stub */ } 278 + 279 + //Provides: mc_poly1305_finalize 280 + function mc_poly1305_finalize(ctx, mac, off) { /* stub */ } 281 + 282 + // ---- GHASH ---- 283 + 284 + //Provides: mc_ghash_key_size 285 + function mc_ghash_key_size(unit) { return 128; /* 8 * 16-byte entries */ } 286 + 287 + //Provides: mc_ghash_init_key 288 + function mc_ghash_init_key(h_str, htable) { 289 + // Store H as bytes for use in ghash 290 + for (var i = 0; i < 16; i++) { 291 + htable[i] = h_str.charCodeAt(i) & 0xff; 292 + } 293 + } 294 + 295 + //Provides: mc_ghash 296 + //Requires: mc_ghash_init_key 297 + function mc_ghash(htable_str, tag, data, off, len) { 298 + // Simplified GHASH: XOR + GF(2^128) multiply 299 + // H is stored in first 16 bytes of htable 300 + var H = new Uint8Array(16); 301 + for (var i = 0; i < 16; i++) H[i] = htable_str.charCodeAt(i) & 0xff; 302 + 303 + function gf128_mul(x, y) { 304 + var z = new Uint8Array(16); 305 + var v = new Uint8Array(y); 306 + for (var i = 0; i < 128; i++) { 307 + if (x[Math.floor(i/8)] & (0x80 >> (i%8))) { 308 + for (var j = 0; j < 16; j++) z[j] ^= v[j]; 309 + } 310 + var carry = v[15] & 1; 311 + for (var j = 15; j > 0; j--) v[j] = (v[j] >> 1) | ((v[j-1] & 1) << 7); 312 + v[0] >>= 1; 313 + if (carry) v[0] ^= 0xe1; 314 + } 315 + return z; 316 + } 317 + 318 + var blocks = Math.floor(len / 16); 319 + for (var b = 0; b < blocks; b++) { 320 + var x = new Uint8Array(16); 321 + for (var i = 0; i < 16; i++) x[i] = tag[i] ^ (data.charCodeAt(off + b*16 + i) & 0xff); 322 + var r = gf128_mul(x, H); 323 + for (var i = 0; i < 16; i++) tag[i] = r[i]; 324 + } 325 + // Handle partial last block 326 + var rem = len - blocks * 16; 327 + if (rem > 0) { 328 + var x = new Uint8Array(16); 329 + for (var i = 0; i < rem; i++) x[i] = tag[i] ^ (data.charCodeAt(off + blocks*16 + i) & 0xff); 330 + for (var i = rem; i < 16; i++) x[i] = tag[i]; 331 + var r = gf128_mul(x, H); 332 + for (var i = 0; i < 16; i++) tag[i] = r[i]; 333 + } 334 + }
+2
src/dune
··· 1 1 (library 2 2 (name crypto) 3 3 (public_name crypto) 4 + (js_of_ocaml 5 + (javascript_files crypto_stubs.js)) 4 6 (libraries eqaf fmt) 5 7 (private_modules 6 8 aead