Line data Source code
1 : /* SPDX-License-Identifier: GPL-3.0-or-later */
2 : /* Copyright 2026 Peter Csaszar */
3 :
4 : /**
5 : * @file ige_aes.c
6 : * @brief AES-256-IGE implementation built on single-block ECB primitives.
7 : *
8 : * IGE mode for each 16-byte block:
9 : * encrypt: c[i] = aes_encrypt(p[i] XOR iv_prev_c) XOR iv_prev_p
10 : * iv_prev_c = c[i], iv_prev_p = p[i]
11 : * decrypt: p[i] = aes_decrypt(c[i] XOR iv_prev_p) XOR iv_prev_c
12 : * iv_prev_p = p[i], iv_prev_c = c[i]
13 : */
14 :
15 : #include "ige_aes.h"
16 : #include "crypto.h"
17 :
18 : #include <string.h>
19 :
20 : #define BLOCK_SIZE 16
21 :
22 1495 : void aes_ige_encrypt(const uint8_t *plain, size_t len,
23 : const uint8_t *key, const uint8_t *iv,
24 : uint8_t *cipher) {
25 1498 : if (!plain || !key || !iv || !cipher || len == 0) return;
26 1493 : if (len % 16 != 0) return;
27 :
28 : CryptoAesKey schedule;
29 1490 : crypto_aes_set_encrypt_key(key, 256, &schedule);
30 :
31 : /* Split IV: first 16 = iv_c, second 16 = iv_p */
32 : uint8_t iv_c[BLOCK_SIZE], iv_p[BLOCK_SIZE];
33 1490 : memcpy(iv_c, iv, BLOCK_SIZE);
34 1490 : memcpy(iv_p, iv + BLOCK_SIZE, BLOCK_SIZE);
35 :
36 : uint8_t buf[BLOCK_SIZE];
37 :
38 2221192 : for (size_t off = 0; off < len; off += BLOCK_SIZE) {
39 : /* buf = plain[i] XOR iv_c */
40 37734934 : for (int j = 0; j < BLOCK_SIZE; j++)
41 35515232 : buf[j] = plain[off + j] ^ iv_c[j];
42 :
43 : /* encrypt block */
44 2219702 : crypto_aes_encrypt_block(buf, cipher + off, &schedule);
45 :
46 : /* cipher[i] ^= iv_p */
47 37734934 : for (int j = 0; j < BLOCK_SIZE; j++)
48 35515232 : cipher[off + j] ^= iv_p[j];
49 :
50 : /* update IVs */
51 2219702 : memcpy(iv_c, cipher + off, BLOCK_SIZE);
52 2219702 : memcpy(iv_p, plain + off, BLOCK_SIZE);
53 : }
54 : }
55 :
56 1457 : void aes_ige_decrypt(const uint8_t *cipher, size_t len,
57 : const uint8_t *key, const uint8_t *iv,
58 : uint8_t *plain) {
59 1460 : if (!cipher || !key || !iv || !plain || len == 0) return;
60 1455 : if (len % 16 != 0) return;
61 :
62 : CryptoAesKey schedule;
63 1452 : crypto_aes_set_decrypt_key(key, 256, &schedule);
64 :
65 : uint8_t iv_c[BLOCK_SIZE], iv_p[BLOCK_SIZE];
66 1452 : memcpy(iv_c, iv, BLOCK_SIZE);
67 1452 : memcpy(iv_p, iv + BLOCK_SIZE, BLOCK_SIZE);
68 :
69 : uint8_t buf[BLOCK_SIZE];
70 :
71 1434009 : for (size_t off = 0; off < len; off += BLOCK_SIZE) {
72 : /* buf = cipher[i] XOR iv_p */
73 24353469 : for (int j = 0; j < BLOCK_SIZE; j++)
74 22920912 : buf[j] = cipher[off + j] ^ iv_p[j];
75 :
76 : /* decrypt block */
77 1432557 : crypto_aes_decrypt_block(buf, plain + off, &schedule);
78 :
79 : /* plain[i] ^= iv_c */
80 24353469 : for (int j = 0; j < BLOCK_SIZE; j++)
81 22920912 : plain[off + j] ^= iv_c[j];
82 :
83 : /* update IVs */
84 1432557 : memcpy(iv_p, plain + off, BLOCK_SIZE);
85 1432557 : memcpy(iv_c, cipher + off, BLOCK_SIZE);
86 : }
87 : }
|