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 660 : 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 660 : if (!plain || !key || !iv || !cipher || len == 0) return;
26 660 : if (len % 16 != 0) return;
27 :
28 : CryptoAesKey schedule;
29 660 : 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 660 : memcpy(iv_c, iv, BLOCK_SIZE);
34 660 : memcpy(iv_p, iv + BLOCK_SIZE, BLOCK_SIZE);
35 :
36 : uint8_t buf[BLOCK_SIZE];
37 :
38 716579 : for (size_t off = 0; off < len; off += BLOCK_SIZE) {
39 : /* buf = plain[i] XOR iv_c */
40 12170623 : for (int j = 0; j < BLOCK_SIZE; j++)
41 11454704 : buf[j] = plain[off + j] ^ iv_c[j];
42 :
43 : /* encrypt block */
44 715919 : crypto_aes_encrypt_block(buf, cipher + off, &schedule);
45 :
46 : /* cipher[i] ^= iv_p */
47 12170623 : for (int j = 0; j < BLOCK_SIZE; j++)
48 11454704 : cipher[off + j] ^= iv_p[j];
49 :
50 : /* update IVs */
51 715919 : memcpy(iv_c, cipher + off, BLOCK_SIZE);
52 715919 : memcpy(iv_p, plain + off, BLOCK_SIZE);
53 : }
54 : }
55 :
56 647 : 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 647 : if (!cipher || !key || !iv || !plain || len == 0) return;
60 647 : if (len % 16 != 0) return;
61 :
62 : CryptoAesKey schedule;
63 647 : crypto_aes_set_decrypt_key(key, 256, &schedule);
64 :
65 : uint8_t iv_c[BLOCK_SIZE], iv_p[BLOCK_SIZE];
66 647 : memcpy(iv_c, iv, BLOCK_SIZE);
67 647 : memcpy(iv_p, iv + BLOCK_SIZE, BLOCK_SIZE);
68 :
69 : uint8_t buf[BLOCK_SIZE];
70 :
71 716467 : for (size_t off = 0; off < len; off += BLOCK_SIZE) {
72 : /* buf = cipher[i] XOR iv_p */
73 12168940 : for (int j = 0; j < BLOCK_SIZE; j++)
74 11453120 : buf[j] = cipher[off + j] ^ iv_p[j];
75 :
76 : /* decrypt block */
77 715820 : crypto_aes_decrypt_block(buf, plain + off, &schedule);
78 :
79 : /* plain[i] ^= iv_c */
80 12168940 : for (int j = 0; j < BLOCK_SIZE; j++)
81 11453120 : plain[off + j] ^= iv_c[j];
82 :
83 : /* update IVs */
84 715820 : memcpy(iv_p, plain + off, BLOCK_SIZE);
85 715820 : memcpy(iv_c, cipher + off, BLOCK_SIZE);
86 : }
87 : }
|