| ... | ... | @@ -49,54 +49,47 @@ fn AesGcmSiv(comptime Aes: anytype) type { |
| 49 | 49 | |
| 50 | 50 | // Derive authentication and message keys per RFC 8452 Section 4 |
| 51 | 51 | // Each encryption produces 16 bytes, but we only use first 8 bytes of each block |
| 52 | | var key_block: [16]u8 = undefined; |
| 53 | | var cipher_out: [16]u8 = undefined; |
| 54 | | |
| 55 | | // Generate authentication key (128 bits = 2 * 8 bytes) |
| 56 | | // Block 0: counter = 0 with nonce |
| 57 | | mem.writeInt(u32, key_block[0..4], 0, .little); |
| 58 | | key_block[4..16].* = nonce; |
| 59 | | aes.encrypt(&cipher_out, &key_block); |
| 60 | | @memcpy(auth_key[0..8], cipher_out[0..8]); |
| 61 | | |
| 62 | | // Block 1: counter = 1 with nonce |
| 63 | | mem.writeInt(u32, key_block[0..4], 1, .little); |
| 64 | | aes.encrypt(&cipher_out, &key_block); |
| 65 | | @memcpy(auth_key[8..16], cipher_out[0..8]); |
| 66 | | |
| 67 | | // Generate message encryption key |
| 52 | |
| 68 | 53 | if (key_length == 16) { |
| 69 | | // AES-128-GCM-SIV: 128-bit message key = 2 * 8 bytes |
| 70 | | // Block 2: counter = 2 with nonce |
| 71 | | mem.writeInt(u32, key_block[0..4], 2, .little); |
| 72 | | aes.encrypt(&cipher_out, &key_block); |
| 73 | | @memcpy(message_key[0..8], cipher_out[0..8]); |
| 74 | | |
| 75 | | // Block 3: counter = 3 with nonce |
| 76 | | mem.writeInt(u32, key_block[0..4], 3, .little); |
| 77 | | aes.encrypt(&cipher_out, &key_block); |
| 78 | | @memcpy(message_key[8..16], cipher_out[0..8]); |
| 54 | // AES-128-GCM-SIV: Process 4 blocks in parallel |
| 55 | var key_blocks: [4 * 16]u8 = undefined; |
| 56 | var cipher_outs: [4 * 16]u8 = undefined; |
| 57 | |
| 58 | // Set up all 4 blocks with counters 0-3 and nonce |
| 59 | inline for (0..4) |i| { |
| 60 | mem.writeInt(u32, key_blocks[i * 16 ..][0..4], @intCast(i), .little); |
| 61 | key_blocks[i * 16 + 4 .. i * 16 + 16].* = nonce; |
| 62 | } |
| 63 | |
| 64 | // Encrypt all 4 blocks in parallel |
| 65 | aes.encryptWide(4, &cipher_outs, &key_blocks); |
| 66 | |
| 67 | // Extract the key material (first 8 bytes of each block) |
| 68 | @memcpy(auth_key[0..8], cipher_outs[0..8]); |
| 69 | @memcpy(auth_key[8..16], cipher_outs[16..24]); |
| 70 | @memcpy(message_key[0..8], cipher_outs[32..40]); |
| 71 | @memcpy(message_key[8..16], cipher_outs[48..56]); |
| 79 | 72 | } else { |
| 80 | | // AES-256-GCM-SIV: 256-bit message key = 4 * 8 bytes |
| 81 | | // Block 2: counter = 2 with nonce |
| 82 | | mem.writeInt(u32, key_block[0..4], 2, .little); |
| 83 | | aes.encrypt(&cipher_out, &key_block); |
| 84 | | @memcpy(message_key[0..8], cipher_out[0..8]); |
| 85 | | |
| 86 | | // Block 3: counter = 3 with nonce |
| 87 | | mem.writeInt(u32, key_block[0..4], 3, .little); |
| 88 | | aes.encrypt(&cipher_out, &key_block); |
| 89 | | @memcpy(message_key[8..16], cipher_out[0..8]); |
| 90 | | |
| 91 | | // Block 4: counter = 4 with nonce |
| 92 | | mem.writeInt(u32, key_block[0..4], 4, .little); |
| 93 | | aes.encrypt(&cipher_out, &key_block); |
| 94 | | @memcpy(message_key[16..24], cipher_out[0..8]); |
| 95 | | |
| 96 | | // Block 5: counter = 5 with nonce |
| 97 | | mem.writeInt(u32, key_block[0..4], 5, .little); |
| 98 | | aes.encrypt(&cipher_out, &key_block); |
| 99 | | @memcpy(message_key[24..32], cipher_out[0..8]); |
| 73 | // AES-256-GCM-SIV: Process 6 blocks in parallel |
| 74 | var key_blocks: [6 * 16]u8 = undefined; |
| 75 | var cipher_outs: [6 * 16]u8 = undefined; |
| 76 | |
| 77 | // Set up all 6 blocks with counters 0-5 and nonce |
| 78 | inline for (0..6) |i| { |
| 79 | mem.writeInt(u32, key_blocks[i * 16 ..][0..4], @intCast(i), .little); |
| 80 | key_blocks[i * 16 + 4 .. i * 16 + 16].* = nonce; |
| 81 | } |
| 82 | |
| 83 | // Encrypt all 6 blocks in parallel |
| 84 | aes.encryptWide(6, &cipher_outs, &key_blocks); |
| 85 | |
| 86 | // Extract the key material (first 8 bytes of each block) |
| 87 | @memcpy(auth_key[0..8], cipher_outs[0..8]); |
| 88 | @memcpy(auth_key[8..16], cipher_outs[16..24]); |
| 89 | @memcpy(message_key[0..8], cipher_outs[32..40]); |
| 90 | @memcpy(message_key[8..16], cipher_outs[48..56]); |
| 91 | @memcpy(message_key[16..24], cipher_outs[64..72]); |
| 92 | @memcpy(message_key[24..32], cipher_outs[80..88]); |
| 100 | 93 | } |
| 101 | 94 | } |
| 102 | 95 | |