18static constexpr uint8_t
round_constants[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
20inline void add_round_key(uint8_t* state,
const uint8_t* round_key,
const size_t round)
22 for (
size_t i = 0; i < 16; i += 4) {
23 for (
size_t j = 0; j < 4; ++j) {
24 state[i + j] ^= round_key[(round * 16U) + i + j];
29inline void xor_with_iv(uint8_t* state,
const uint8_t* iv)
31 for (
size_t i = 0; i < 16; ++i) {
39 for (i = 0; i < 4; ++i) {
40 for (j = 0; j < 4; ++j) {
41 input[j * 4 + i] = bb::crypto::aes128_sbox[input[j * 4 + i]];
46void inverse_sub_bytes(uint8_t* input)
48 for (
size_t i = 0; i < 4; ++i) {
49 for (
size_t j = 0; j < 4; ++j) {
50 input[j * 4 + i] = bb::crypto::aes128_sbox_inverse[input[j * 4 + i]];
59 temp = input[0 * 4 + 1];
60 input[0 * 4 + 1] = input[1 * 4 + 1];
61 input[1 * 4 + 1] = input[2 * 4 + 1];
62 input[2 * 4 + 1] = input[3 * 4 + 1];
63 input[3 * 4 + 1] = temp;
65 temp = input[0 * 4 + 2];
66 input[0 * 4 + 2] = input[2 * 4 + 2];
67 input[2 * 4 + 2] = temp;
69 temp = input[1 * 4 + 2];
70 input[1 * 4 + 2] = input[3 * 4 + 2];
71 input[3 * 4 + 2] = temp;
73 temp = input[0 * 4 + 3];
74 input[0 * 4 + 3] = input[3 * 4 + 3];
75 input[3 * 4 + 3] = input[2 * 4 + 3];
76 input[2 * 4 + 3] = input[1 * 4 + 3];
77 input[1 * 4 + 3] = temp;
80static void inverse_shift_rows(uint8_t* input)
84 temp = input[3 * 4 + 1];
85 input[3 * 4 + 1] = input[2 * 4 + 1];
86 input[2 * 4 + 1] = input[1 * 4 + 1];
87 input[1 * 4 + 1] = input[0 * 4 + 1];
88 input[0 * 4 + 1] = temp;
90 temp = input[0 * 4 + 2];
91 input[0 * 4 + 2] = input[2 * 4 + 2];
92 input[2 * 4 + 2] = temp;
94 temp = input[1 * 4 + 2];
95 input[1 * 4 + 2] = input[3 * 4 + 2];
96 input[3 * 4 + 2] = temp;
98 temp = input[0 * 4 + 3];
99 input[0 * 4 + 3] = input[1 * 4 + 3];
100 input[1 * 4 + 3] = input[2 * 4 + 3];
101 input[2 * 4 + 3] = input[3 * 4 + 3];
102 input[3 * 4 + 3] = temp;
105uint8_t xtime(
const uint8_t x)
107 return static_cast<uint8_t
>((x << 1) ^ (((x >> 7) & 1) * 0x1b));
110uint8_t gf2_8_mul(
const uint8_t x,
const uint8_t y)
112 const uint8_t t0 = (uint8_t)((y & (uint8_t)1) * x);
113 const uint8_t t1 = (uint8_t)(((y >> (uint8_t)1) & (uint8_t)1) * xtime(x));
114 const uint8_t t2 = (uint8_t)(((y >> (uint8_t)2) & (uint8_t)1) * xtime(xtime(x)));
115 const uint8_t t3 = (uint8_t)(((y >> (uint8_t)3) & (uint8_t)1) * xtime(xtime(xtime(x))));
116 const uint8_t t4 = (uint8_t)(((y >> (uint8_t)4) & (uint8_t)1) * xtime(xtime(xtime(xtime(x)))));
118 uint8_t out = t0 ^ t1 ^ t2 ^ t3 ^ t4;
122void mix_columns(uint8_t* input)
124 for (uint8_t i = 0; i < 4; ++i) {
125 uint8_t t = input[i * 4 + 0];
126 uint8_t Tmp = input[i * 4 + 0] ^ input[i * 4 + 1] ^ input[i * 4 + 2] ^ input[i * 4 + 3];
127 uint8_t Tm = input[i * 4 + 0] ^ input[i * 4 + 1];
129 input[i * 4 + 0] ^= Tm ^ Tmp;
130 Tm = input[i * 4 + 1] ^ input[i * 4 + 2];
132 input[i * 4 + 1] ^= Tm ^ Tmp;
133 Tm = input[i * 4 + 2] ^ input[i * 4 + 3];
135 input[i * 4 + 2] ^= Tm ^ Tmp;
136 Tm = input[i * 4 + 3] ^ t;
138 input[i * 4 + 3] ^= Tm ^ Tmp;
142void inverse_mix_columns(uint8_t* input)
144 for (uint8_t i = 0; i < 4; ++i) {
145 uint8_t
a = input[i * 4 + 0];
146 uint8_t
b = input[i * 4 + 1];
147 uint8_t c = input[i * 4 + 2];
148 uint8_t d = input[i * 4 + 3];
150 input[i * 4 + 0] = gf2_8_mul(
a, 0x0e) ^ gf2_8_mul(
b, 0x0b) ^ gf2_8_mul(c, 0x0d) ^ gf2_8_mul(d, 0x09);
151 input[i * 4 + 1] = gf2_8_mul(
a, 0x09) ^ gf2_8_mul(
b, 0x0e) ^ gf2_8_mul(c, 0x0b) ^ gf2_8_mul(d, 0x0d);
152 input[i * 4 + 2] = gf2_8_mul(
a, 0x0d) ^ gf2_8_mul(
b, 0x09) ^ gf2_8_mul(c, 0x0e) ^ gf2_8_mul(d, 0x0b);
153 input[i * 4 + 3] = gf2_8_mul(
a, 0x0b) ^ gf2_8_mul(
b, 0x0d) ^ gf2_8_mul(c, 0x09) ^ gf2_8_mul(d, 0x0e);
164 for (
size_t i = 0; i < 16; i += 4) {
165 round_key[i] =
key[i];
166 round_key[i + 1] =
key[i + 1];
167 round_key[i + 2] =
key[i + 2];
168 round_key[i + 3] =
key[i + 3];
171 for (
size_t i = 4; i < 44; ++i) {
172 size_t k = (i - 1) * 4;
173 temp[0] = round_key[k];
174 temp[1] = round_key[k + 1];
175 temp[2] = round_key[k + 2];
176 temp[3] = round_key[k + 3];
178 if ((i & 0x03) == 0) {
179 const uint8_t t = temp[0];
185 temp[0] = aes128_sbox[temp[0]];
186 temp[1] = aes128_sbox[temp[1]];
187 temp[2] = aes128_sbox[temp[2]];
188 temp[3] = aes128_sbox[temp[3]];
190 temp[0] = temp[0] ^ round_constants[i >> 2];
194 round_key[j] = round_key[k] ^ temp[0];
195 round_key[j + 1] = round_key[k + 1] ^ temp[1];
196 round_key[j + 2] = round_key[k + 2] ^ temp[2];
197 round_key[j + 3] = round_key[k + 3] ^ temp[3];
204 add_round_key(input, round_key, 10);
206 for (
size_t round = 9; round > 0; --round) {
207 inverse_shift_rows(input);
208 inverse_sub_bytes(input);
209 add_round_key(input, round_key, round);
210 inverse_mix_columns(input);
212 inverse_shift_rows(input);
213 inverse_sub_bytes(input);
214 add_round_key(input, round_key, 0);
219 add_round_key(state, round_key, 0);
221 for (uint8_t round = 1; round < 10; ++round) {
225 add_round_key(state, round_key, round);
230 add_round_key(state, round_key, 10);
235 uint8_t round_key[176];
238 uint8_t block_state[16]{};
240 const size_t num_blocks = (
length / 16);
242 for (
size_t i = 0; i < num_blocks; ++i) {
243 memcpy((
void*)block_state, (
void*)(
buffer + (i * 16)), 16);
244 xor_with_iv(block_state, iv);
248 memcpy((
void*)(
buffer + (i * 16)), (
void*)block_state, 16);
249 memcpy((
void*)iv, (
void*)block_state, 16);
255 uint8_t round_key[176];
257 uint8_t block_state[16]{};
258 const size_t num_blocks = (
length / 16);
260 uint8_t next_iv[16]{};
261 for (
size_t i = 0; i < num_blocks; ++i) {
262 memcpy((
void*)block_state, (
void*)(
buffer + (i * 16)), 16);
263 memcpy((
void*)next_iv, (
void*)block_state, 16);
265 xor_with_iv(block_state, iv);
266 memcpy((
void*)(
buffer + (i * 16)), (
void*)block_state, 16);
267 memcpy((
void*)iv, (
void*)next_iv, 16);
uint8_t const size_t length
uint8_t buffer[RANDOM_BUFFER_SIZE]
constexpr uint32_t round_constants[64]
void aes128_inverse_cipher(uint8_t *input, const uint8_t *round_key)
void aes128_decrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
void aes128_expand_key(const uint8_t *key, uint8_t *round_key)
void aes128_cipher(uint8_t *state, const uint8_t *round_key)
void aes128_encrypt_buffer_cbc(uint8_t *buffer, uint8_t *iv, const uint8_t *key, const size_t length)
void xor_with_iv(byte_pair< Builder > *state, field_t< Builder > *iv)
void sub_bytes(Builder *ctx, byte_pair< Builder > *state_pairs)
void add_round_key(byte_pair< Builder > *sparse_state, field_t< Builder > *sparse_round_key, uint64_t round)
void shift_rows(byte_pair< Builder > *state)