17#include <mbedtls/aes.h>
33 mbedtls_aes_context
c;
37 mbedtls_aes_init(&b->
c);
38 mbedtls_aes_setkey_enc(&b->
c, key, 128);
42 mbedtls_aes_crypt_ecb(&b->
c, MBEDTLS_AES_ENCRYPT, in, out);
46 mbedtls_aes_free(&b->
c);
58inline void blk_init(AesBlk *b,
const uint8_t key[16])
62inline void blk_enc(AesBlk *b,
const uint8_t in[16], uint8_t out[16])
80uint8_t shl1(
const uint8_t in[16], uint8_t out[16])
83 for (
int i = 15; i >= 0; i--)
85 uint8_t next = (uint8_t)(in[i] >> 7);
86 out[i] = (uint8_t)((in[i] << 1) | carry);
93void subkeys(AesBlk *blk, uint8_t k1[16], uint8_t k2[16])
95 static constexpr uint8_t RB = 0x87;
96 uint8_t zero[16] = {0};
116 subkeys(&blk, k1, k2);
119 const size_t n = msg_len == 0 ? 1 : (msg_len + 15) / 16;
120 const bool complete = msg_len != 0 && (msg_len % 16) == 0;
126 for (
int i = 0; i < 16; i++)
128 last[i] = (uint8_t)(msg[(n - 1) * 16 + i] ^ k1[i]);
133 const size_t rem = msg_len - (n - 1) * 16;
134 for (
size_t i = 0; i < 16; i++)
136 uint8_t m = i < rem ? msg[(n - 1) * 16 + i] : (i == rem ? 0x80 : 0x00);
137 last[i] = (uint8_t)(m ^ k2[i]);
144 for (
size_t i = 0; i + 1 < n; i++)
146 for (
int j = 0; j < 16; j++)
148 y[j] = (uint8_t)(x[j] ^ msg[i * 16 + j]);
152 for (
int j = 0; j < 16; j++)
154 y[j] = (uint8_t)(x[j] ^ last[j]);
156 blk_enc(&blk, y, mac);
Compact table-free software AES key schedule + single-block encrypt (FIPS 197) - one source of truth.
void pc_aes_key_expand(const uint8_t *key, int nk, uint32_t *rk)
AES key expansion (FIPS 197 sec 5.2). nk key words (4=AES-128, 8=AES-256); rk receives 4*(nk + 7) rou...
void pc_aes_encrypt_block(const uint32_t *rk, int nr, const uint8_t in[16], uint8_t out[16])
AES single-block encrypt (FIPS 197 sec 5.1), nr rounds (10=AES-128, 14=AES-256). State is column-majo...
void pc_aes_cmac(const uint8_t key[16], const uint8_t *msg, size_t msg_len, uint8_t mac[PC_AES_CMAC_LEN])
Compute the AES-128-CMAC of msg under key (RFC 4493).
AES-128-CMAC (RFC 4493 / NIST SP800-38B) one-shot MAC.
#define PC_AES_CMAC_LEN
AES-128-CMAC output length (one AES block).
Per-translation-unit optimization override for hot, pure-integer crypto.
void blk_enc(AesBlk *b, const uint8_t in[16], uint8_t out[16])
void blk_init(AesBlk *b, const uint8_t key[16])