26 mbedtls_aes_init(&ctx->
_mbed);
27 mbedtls_aes_setkey_enc(&ctx->
_mbed, key, 256);
41 size_t nc_off = ctx->
pos;
43 ctx->
pos = (uint8_t)nc_off;
48 mbedtls_aes_free(&ctx->
_mbed);
49 volatile uint8_t *p = (
volatile uint8_t *)ctx;
67static const uint8_t RCON[11] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
70static inline uint8_t xtime(uint8_t a)
72 return (uint8_t)((a << 1) ^ ((a >> 7) ? 0x1bu : 0x00u));
81static uint32_t aes_sub_word(uint32_t w)
83 return ((uint32_t)DET_AES_SBOX[w >> 24] << 24) | ((uint32_t)DET_AES_SBOX[(w >> 16) & 0xff] << 16) |
84 ((uint32_t)DET_AES_SBOX[(w >> 8) & 0xff] << 8) | (uint32_t)DET_AES_SBOX[w & 0xff];
87static uint32_t aes_rot_word(uint32_t w)
89 return (w << 8) | (w >> 24);
92static void aes256_key_expand(
const uint8_t key[32], uint32_t rk[60])
96 for (
int i = 0; i < 8; i++)
98 rk[i] = ((uint32_t)key[4 * i] << 24) | ((uint32_t)key[4 * i + 1] << 16) | ((uint32_t)key[4 * i + 2] << 8) |
99 (uint32_t)key[4 * i + 3];
105 for (
int i = 8; i < 60; i++)
107 uint32_t t = rk[i - 1];
110 t = aes_sub_word(aes_rot_word(t)) ^ ((uint32_t)RCON[i / 8] << 24);
114 rk[i] = rk[i - 8] ^ t;
123static void aes256_encrypt_block(
const uint32_t rk[60],
const uint8_t in[16], uint8_t out[16])
128 for (
int i = 0; i < 16; i++)
129 s[i] = in[i] ^ (uint8_t)(rk[i / 4] >> (24 - (i % 4) * 8));
132 for (
int r = 1; r <= 13; r++)
135 for (
int i = 0; i < 16; i++)
136 s[i] = DET_AES_SBOX[s[i]];
163 for (
int c = 0; c < 4; c++)
165 uint8_t a = s[c * 4];
166 uint8_t b = s[c * 4 + 1];
167 uint8_t cc = s[c * 4 + 2];
168 uint8_t d = s[c * 4 + 3];
169 uint8_t e = a ^ b ^ cc ^ d;
170 s[c * 4] = a ^ e ^ xtime(a ^ b);
171 s[c * 4 + 1] = b ^ e ^ xtime(b ^ cc);
172 s[c * 4 + 2] = cc ^ e ^ xtime(cc ^ d);
173 s[c * 4 + 3] = d ^ e ^ xtime(d ^ a);
177 for (
int i = 0; i < 16; i++)
178 s[i] ^= (uint8_t)(rk[r * 4 + i / 4] >> (24 - (i % 4) * 8));
182 for (
int i = 0; i < 16; i++)
183 s[i] = DET_AES_SBOX[s[i]];
203 for (
int i = 0; i < 16; i++)
204 s[i] ^= (uint8_t)(rk[56 + i / 4] >> (24 - (i % 4) * 8));
215 aes256_key_expand(key, ctx->rk);
224 for (
int j = 15; j >= 0; j--)
231 for (
size_t i = 0; i < len; i++)
236 ctx->
pos = (uint8_t)((ctx->
pos + 1u) & 0x0fu);
242 volatile uint8_t *p = (
volatile uint8_t *)ctx;
The AES forward S-box (FIPS 197 Figure 7) - one shared copy.
void ssh_aes256ctr_init(SshAesCtrCtx *ctx, const uint8_t key[32], const uint8_t iv[16])
Initialize an AES-256-CTR context.
void ssh_aes256ctr_wipe(SshAesCtrCtx *ctx)
Zero the key schedule and all context fields.
void ssh_aes256ctr_crypt(SshAesCtrCtx *ctx, const uint8_t *in, uint8_t *out, size_t len)
Encrypt or decrypt len bytes in-place (or src→dst).
AES-256-CTR stream cipher context and API.
uint8_t counter[16]
Current CTR block (big-endian 128-bit counter).
uint8_t pos
Next byte position within keystream[].
mbedtls_aes_context _mbed
mbedtls context with pre-expanded key schedule.
uint8_t keystream[16]
Buffered keystream from last AES-ECB call.