17static constexpr uint8_t
round_constants[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
19inline void add_round_key(uint8_t* state,
const uint8_t* round_key,
const size_t round)
21 for (
size_t i = 0; i < 16; i += 4) {
22 for (
size_t j = 0; j < 4; ++j) {
23 state[i + j] ^= round_key[(round * 16U) + i + j];
28inline void xor_with_iv(uint8_t* state,
const uint8_t* iv)
30 for (
size_t i = 0; i < 16; ++i) {
38 for (i = 0; i < 4; ++i) {
39 for (j = 0; j < 4; ++j) {
40 input[j * 4 + i] = bb::crypto::aes128_sbox[input[j * 4 + i]];
45void inverse_sub_bytes(uint8_t* input)
47 for (
size_t i = 0; i < 4; ++i) {
48 for (
size_t j = 0; j < 4; ++j) {
49 input[j * 4 + i] = bb::crypto::aes128_sbox_inverse[input[j * 4 + i]];
58 temp = input[0 * 4 + 1];
59 input[0 * 4 + 1] = input[1 * 4 + 1];
60 input[1 * 4 + 1] = input[2 * 4 + 1];
61 input[2 * 4 + 1] = input[3 * 4 + 1];
62 input[3 * 4 + 1] = temp;
64 temp = input[0 * 4 + 2];
65 input[0 * 4 + 2] = input[2 * 4 + 2];
66 input[2 * 4 + 2] = temp;
68 temp = input[1 * 4 + 2];
69 input[1 * 4 + 2] = input[3 * 4 + 2];
70 input[3 * 4 + 2] = temp;
72 temp = input[0 * 4 + 3];
73 input[0 * 4 + 3] = input[3 * 4 + 3];
74 input[3 * 4 + 3] = input[2 * 4 + 3];
75 input[2 * 4 + 3] = input[1 * 4 + 3];
76 input[1 * 4 + 3] = temp;
79static void inverse_shift_rows(uint8_t* input)
83 temp = input[3 * 4 + 1];
84 input[3 * 4 + 1] = input[2 * 4 + 1];
85 input[2 * 4 + 1] = input[1 * 4 + 1];
86 input[1 * 4 + 1] = input[0 * 4 + 1];
87 input[0 * 4 + 1] = temp;
89 temp = input[0 * 4 + 2];
90 input[0 * 4 + 2] = input[2 * 4 + 2];
91 input[2 * 4 + 2] = temp;
93 temp = input[1 * 4 + 2];
94 input[1 * 4 + 2] = input[3 * 4 + 2];
95 input[3 * 4 + 2] = temp;
97 temp = input[0 * 4 + 3];
98 input[0 * 4 + 3] = input[1 * 4 + 3];
99 input[1 * 4 + 3] = input[2 * 4 + 3];
100 input[2 * 4 + 3] = input[3 * 4 + 3];
101 input[3 * 4 + 3] = temp;
104uint8_t xtime(
const uint8_t x)
106 return static_cast<uint8_t
>((x << 1) ^ (((x >> 7) & 1) * 0x1b));
109uint8_t gf2_8_mul(
const uint8_t x,
const uint8_t y)
111 const uint8_t t0 = (uint8_t)((y & (uint8_t)1) * x);
112 const uint8_t t1 = (uint8_t)(((y >> (uint8_t)1) & (uint8_t)1) * xtime(x));
113 const uint8_t t2 = (uint8_t)(((y >> (uint8_t)2) & (uint8_t)1) * xtime(xtime(x)));
114 const uint8_t t3 = (uint8_t)(((y >> (uint8_t)3) & (uint8_t)1) * xtime(xtime(xtime(x))));
115 const uint8_t t4 = (uint8_t)(((y >> (uint8_t)4) & (uint8_t)1) * xtime(xtime(xtime(xtime(x)))));
117 uint8_t out = t0 ^ t1 ^ t2 ^ t3 ^ t4;
121void mix_columns(uint8_t* input)
123 for (uint8_t i = 0; i < 4; ++i) {
124 uint8_t t = input[i * 4 + 0];
125 uint8_t Tmp = input[i * 4 + 0] ^ input[i * 4 + 1] ^ input[i * 4 + 2] ^ input[i * 4 + 3];
126 uint8_t Tm = input[i * 4 + 0] ^ input[i * 4 + 1];
128 input[i * 4 + 0] ^= Tm ^ Tmp;
129 Tm = input[i * 4 + 1] ^ input[i * 4 + 2];
131 input[i * 4 + 1] ^= Tm ^ Tmp;
132 Tm = input[i * 4 + 2] ^ input[i * 4 + 3];
134 input[i * 4 + 2] ^= Tm ^ Tmp;
135 Tm = input[i * 4 + 3] ^ t;
137 input[i * 4 + 3] ^= Tm ^ Tmp;
141void inverse_mix_columns(uint8_t* input)
143 for (uint8_t i = 0; i < 4; ++i) {
144 uint8_t
a = input[i * 4 + 0];
145 uint8_t
b = input[i * 4 + 1];
146 uint8_t c = input[i * 4 + 2];
147 uint8_t d = input[i * 4 + 3];
149 input[i * 4 + 0] = gf2_8_mul(
a, 0x0e) ^ gf2_8_mul(
b, 0x0b) ^ gf2_8_mul(c, 0x0d) ^ gf2_8_mul(d, 0x09);
150 input[i * 4 + 1] = gf2_8_mul(
a, 0x09) ^ gf2_8_mul(
b, 0x0e) ^ gf2_8_mul(c, 0x0b) ^ gf2_8_mul(d, 0x0d);
151 input[i * 4 + 2] = gf2_8_mul(
a, 0x0d) ^ gf2_8_mul(
b, 0x09) ^ gf2_8_mul(c, 0x0e) ^ gf2_8_mul(d, 0x0b);
152 input[i * 4 + 3] = gf2_8_mul(
a, 0x0b) ^ gf2_8_mul(
b, 0x0d) ^ gf2_8_mul(c, 0x09) ^ gf2_8_mul(d, 0x0e);
163 for (
size_t i = 0; i < 16; i += 4) {
164 round_key[i] =
key[i];
165 round_key[i + 1] =
key[i + 1];
166 round_key[i + 2] =
key[i + 2];
167 round_key[i + 3] =
key[i + 3];
170 for (
size_t i = 4; i < 44; ++i) {
171 size_t k = (i - 1) * 4;
172 temp[0] = round_key[k];
173 temp[1] = round_key[k + 1];
174 temp[2] = round_key[k + 2];
175 temp[3] = round_key[k + 3];
177 if ((i & 0x03) == 0) {
178 const uint8_t t = temp[0];
184 temp[0] = aes128_sbox[temp[0]];
185 temp[1] = aes128_sbox[temp[1]];
186 temp[2] = aes128_sbox[temp[2]];
187 temp[3] = aes128_sbox[temp[3]];
189 temp[0] = temp[0] ^ round_constants[i >> 2];
193 round_key[j] = round_key[k] ^ temp[0];
194 round_key[j + 1] = round_key[k + 1] ^ temp[1];
195 round_key[j + 2] = round_key[k + 2] ^ temp[2];
196 round_key[j + 3] = round_key[k + 3] ^ temp[3];
203 add_round_key(input, round_key, 10);
205 for (
size_t round = 9; round > 0; --round) {
206 inverse_shift_rows(input);
207 inverse_sub_bytes(input);
208 add_round_key(input, round_key, round);
209 inverse_mix_columns(input);
211 inverse_shift_rows(input);
212 inverse_sub_bytes(input);
213 add_round_key(input, round_key, 0);
218 add_round_key(state, round_key, 0);
220 for (uint8_t round = 1; round < 10; ++round) {
224 add_round_key(state, round_key, round);
229 add_round_key(state, round_key, 10);
234 uint8_t round_key[176];
237 uint8_t block_state[16]{};
239 const size_t num_blocks = (
length / 16);
241 for (
size_t i = 0; i < num_blocks; ++i) {
242 memcpy((
void*)block_state, (
void*)(
buffer + (i * 16)), 16);
243 xor_with_iv(block_state, iv);
247 memcpy((
void*)(
buffer + (i * 16)), (
void*)block_state, 16);
248 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
std::unique_ptr< uint8_t[]> buffer
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 secure_erase_bytes(void *ptr, size_t size)
void sub_bytes(Builder *ctx, state_span< Builder > state_pairs)
void shift_rows(state_span< Builder > state)
The SHIFTROW() operation as in FIPS 197, Section 5.1.2.
void add_round_key(state_span< Builder > sparse_state, key_span< Builder > sparse_round_key, size_t round)
void xor_with_iv(state_span< Builder > state, block_span< Builder > iv)