25 #include "utility/EndianUtil.h"
93 #define CA_0 ((uint32_t)0x00000000)
94 #define CA_1 ((uint32_t)0xFFFFFFFF)
95 #define CB_0 ((uint32_t)0x00000000)
96 #define CB_1 ((uint32_t)0xFFFFFFFF)
97 #define CA_0_BYTE ((uint8_t)0x00)
98 #define CA_1_BYTE ((uint8_t)0xFF)
99 #define CB_0_BYTE ((uint8_t)0x00)
100 #define CB_1_BYTE ((uint8_t)0xFF)
102 #if defined(CRYPTO_ACORN128_DEFAULT) || defined(CRYPTO_DOC)
105 #define maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
106 #define ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
118 static uint8_t acornEncrypt8
119 (Acorn128State *state, uint8_t plaintext, uint8_t ca, uint8_t cb)
122 #define s_extract_8(name, shift) \
123 ((uint8_t)(state->name##_l >> (shift)))
124 uint8_t s244 = s_extract_8(s6, 14);
125 uint8_t s235 = s_extract_8(s6, 5);
126 uint8_t s196 = s_extract_8(s5, 3);
127 uint8_t s160 = s_extract_8(s4, 6);
128 uint8_t s111 = s_extract_8(s3, 4);
129 uint8_t s66 = s_extract_8(s2, 5);
130 uint8_t s23 = s_extract_8(s1, 23);
131 uint8_t s12 = s_extract_8(s1, 12);
134 uint8_t s7_l = state->s7 ^ s235 ^ state->s6_l;
135 state->s6_l ^= s196 ^ ((uint8_t)(state->s5_l));
136 state->s5_l ^= s160 ^ ((uint8_t)(state->s4_l));
137 state->s4_l ^= s111 ^ ((uint8_t)(state->s3_l));
138 state->s3_l ^= s66 ^ ((uint8_t)(state->s2_l));
139 state->s2_l ^= s23 ^ ((uint8_t)(state->s1_l));
144 uint8_t ks = s12 ^ state->s4_l ^
145 maj(s235, state->s2_l, state->s5_l) ^
146 ch(state->s6_l, s111, s66);
152 uint8_t f = state->s1_l ^ (~state->s3_l) ^
153 maj(s244, s23, s160) ^ (ca & s196) ^ (cb & ks);
157 #define s_shift_8(name1, name2, shift) \
158 (state->name1##_l = (state->name1##_l >> 8) | \
159 (((uint32_t)(state->name1##_h)) << 24), \
160 state->name1##_h = (state->name1##_h >> 8) | \
161 ((state->name2##_l & 0xFF) << ((shift) - 40)))
162 #define s_shift_8_mixed(name1, name2, shift) \
163 (state->name1##_l = (state->name1##_l >> 8) | \
164 (((uint32_t)(state->name1##_h)) << 24) | \
165 (state->name2##_l << ((shift) - 8)), \
166 state->name1##_h = ((state->name2##_l & 0xFF) >> (40 - (shift))))
169 s_shift_8(s1, s2, 61);
170 s_shift_8(s2, s3, 46);
171 s_shift_8(s3, s4, 47);
172 s_shift_8_mixed(s4, s5, 39);
173 s_shift_8_mixed(s5, s6, 37);
174 state->s6_l = (state->s6_l >> 8) | (state->s6_h << 24);
175 state->s6_h = (state->s6_h >> 8) | (((uint32_t)s7_l) << 19);
178 return plaintext ^ ks;
191 static uint32_t acornEncrypt32
192 (Acorn128State *state, uint32_t plaintext, uint32_t ca, uint32_t cb)
195 #define s_extract_32(name, shift) \
196 ((state->name##_l >> (shift)) | \
197 (((uint32_t)(state->name##_h)) << (32 - (shift))))
198 uint32_t s244 = s_extract_32(s6, 14);
199 uint32_t s235 = s_extract_32(s6, 5);
200 uint32_t s196 = s_extract_32(s5, 3);
201 uint32_t s160 = s_extract_32(s4, 6);
202 uint32_t s111 = s_extract_32(s3, 4);
203 uint32_t s66 = s_extract_32(s2, 5);
204 uint32_t s23 = s_extract_32(s1, 23);
205 uint32_t s12 = s_extract_32(s1, 12);
208 uint32_t s7_l = state->s7 ^ s235 ^ state->s6_l;
209 state->s6_l ^= s196 ^ state->s5_l;
210 state->s5_l ^= s160 ^ state->s4_l;
211 state->s4_l ^= s111 ^ state->s3_l;
212 state->s3_l ^= s66 ^ state->s2_l;
213 state->s2_l ^= s23 ^ state->s1_l;
218 uint32_t ks = s12 ^ state->s4_l ^
219 maj(s235, state->s2_l, state->s5_l) ^
220 ch(state->s6_l, s111, s66);
226 uint32_t f = state->s1_l ^ (~state->s3_l) ^
227 maj(s244, s23, s160) ^ (ca & s196) ^ (cb & ks);
231 #define s_shift_32(name1, name2, shift) \
232 (state->name1##_l = state->name1##_h | (state->name2##_l << (shift)), \
233 state->name1##_h = (state->name2##_l >> (32 - (shift))))
235 state->s7 = (uint8_t)(f >> 28);
236 s_shift_32(s1, s2, 29);
237 s_shift_32(s2, s3, 14);
238 s_shift_32(s3, s4, 15);
239 s_shift_32(s4, s5, 7);
240 s_shift_32(s5, s6, 5);
241 state->s6_l = state->s6_h | (s7_l << 27);
242 state->s6_h = s7_l >> 5;
245 return plaintext ^ ks;
258 static inline uint32_t acornEncrypt32Fast
259 (Acorn128State *state, uint32_t plaintext)
262 #define s_extract_32(name, shift) \
263 ((state->name##_l >> (shift)) | \
264 (((uint32_t)(state->name##_h)) << (32 - (shift))))
265 uint32_t s244 = s_extract_32(s6, 14);
266 uint32_t s235 = s_extract_32(s6, 5);
267 uint32_t s196 = s_extract_32(s5, 3);
268 uint32_t s160 = s_extract_32(s4, 6);
269 uint32_t s111 = s_extract_32(s3, 4);
270 uint32_t s66 = s_extract_32(s2, 5);
271 uint32_t s23 = s_extract_32(s1, 23);
272 uint32_t s12 = s_extract_32(s1, 12);
275 uint32_t s7_l = state->s7 ^ s235 ^ state->s6_l;
276 state->s6_l ^= s196 ^ state->s5_l;
277 state->s5_l ^= s160 ^ state->s4_l;
278 state->s4_l ^= s111 ^ state->s3_l;
279 state->s3_l ^= s66 ^ state->s2_l;
280 state->s2_l ^= s23 ^ state->s1_l;
285 uint32_t ks = s12 ^ state->s4_l ^
286 maj(s235, state->s2_l, state->s5_l) ^
287 ch(state->s6_l, s111, s66);
294 uint32_t f = state->s1_l ^ (~state->s3_l) ^ maj(s244, s23, s160) ^ s196;
298 #define s_shift_32(name1, name2, shift) \
299 (state->name1##_l = state->name1##_h | (state->name2##_l << (shift)), \
300 state->name1##_h = (state->name2##_l >> (32 - (shift))))
302 state->s7 = (uint8_t)(f >> 28);
303 s_shift_32(s1, s2, 29);
304 s_shift_32(s2, s3, 14);
305 s_shift_32(s3, s4, 15);
306 s_shift_32(s4, s5, 7);
307 s_shift_32(s5, s6, 5);
308 state->s6_l = state->s6_h | (s7_l << 27);
309 state->s6_h = s7_l >> 5;
312 return plaintext ^ ks;
323 static inline uint8_t acornDecrypt8(Acorn128State *state, uint8_t ciphertext)
326 #define s_extract_8(name, shift) \
327 ((uint8_t)(state->name##_l >> (shift)))
328 uint8_t s244 = s_extract_8(s6, 14);
329 uint8_t s235 = s_extract_8(s6, 5);
330 uint8_t s196 = s_extract_8(s5, 3);
331 uint8_t s160 = s_extract_8(s4, 6);
332 uint8_t s111 = s_extract_8(s3, 4);
333 uint8_t s66 = s_extract_8(s2, 5);
334 uint8_t s23 = s_extract_8(s1, 23);
335 uint8_t s12 = s_extract_8(s1, 12);
338 uint8_t s7_l = state->s7 ^ s235 ^ state->s6_l;
339 state->s6_l ^= s196 ^ ((uint8_t)(state->s5_l));
340 state->s5_l ^= s160 ^ ((uint8_t)(state->s4_l));
341 state->s4_l ^= s111 ^ ((uint8_t)(state->s3_l));
342 state->s3_l ^= s66 ^ ((uint8_t)(state->s2_l));
343 state->s2_l ^= s23 ^ ((uint8_t)(state->s1_l));
348 uint8_t ks = s12 ^ state->s4_l ^
349 maj(s235, state->s2_l, state->s5_l) ^
350 ch(state->s6_l, s111, s66);
351 uint8_t plaintext = ciphertext ^ ks;
358 uint8_t f = state->s1_l ^ (~state->s3_l) ^ maj(s244, s23, s160) ^ s196;
362 #define s_shift_8(name1, name2, shift) \
363 (state->name1##_l = (state->name1##_l >> 8) | \
364 (((uint32_t)(state->name1##_h)) << 24), \
365 state->name1##_h = (state->name1##_h >> 8) | \
366 ((state->name2##_l & 0xFF) << ((shift) - 40)))
367 #define s_shift_8_mixed(name1, name2, shift) \
368 (state->name1##_l = (state->name1##_l >> 8) | \
369 (((uint32_t)(state->name1##_h)) << 24) | \
370 (state->name2##_l << ((shift) - 8)), \
371 state->name1##_h = ((state->name2##_l & 0xFF) >> (40 - (shift))))
374 s_shift_8(s1, s2, 61);
375 s_shift_8(s2, s3, 46);
376 s_shift_8(s3, s4, 47);
377 s_shift_8_mixed(s4, s5, 39);
378 s_shift_8_mixed(s5, s6, 37);
379 state->s6_l = (state->s6_l >> 8) | (state->s6_h << 24);
380 state->s6_h = (state->s6_h >> 8) | (((uint32_t)s7_l) << 19);
394 static inline uint32_t acornDecrypt32(Acorn128State *state, uint32_t ciphertext)
397 #define s_extract_32(name, shift) \
398 ((state->name##_l >> (shift)) | \
399 (((uint32_t)(state->name##_h)) << (32 - (shift))))
400 uint32_t s244 = s_extract_32(s6, 14);
401 uint32_t s235 = s_extract_32(s6, 5);
402 uint32_t s196 = s_extract_32(s5, 3);
403 uint32_t s160 = s_extract_32(s4, 6);
404 uint32_t s111 = s_extract_32(s3, 4);
405 uint32_t s66 = s_extract_32(s2, 5);
406 uint32_t s23 = s_extract_32(s1, 23);
407 uint32_t s12 = s_extract_32(s1, 12);
410 uint32_t s7_l = state->s7 ^ s235 ^ state->s6_l;
411 state->s6_l ^= s196 ^ state->s5_l;
412 state->s5_l ^= s160 ^ state->s4_l;
413 state->s4_l ^= s111 ^ state->s3_l;
414 state->s3_l ^= s66 ^ state->s2_l;
415 state->s2_l ^= s23 ^ state->s1_l;
420 uint32_t ks = s12 ^ state->s4_l ^
421 maj(s235, state->s2_l, state->s5_l) ^
422 ch(state->s6_l, s111, s66);
423 uint32_t plaintext = ciphertext ^ ks;
430 uint32_t f = state->s1_l ^ (~state->s3_l) ^ maj(s244, s23, s160) ^ s196;
434 #define s_shift_32(name1, name2, shift) \
435 (state->name1##_l = state->name1##_h | (state->name2##_l << (shift)), \
436 state->name1##_h = (state->name2##_l >> (32 - (shift))))
438 state->s7 = (uint8_t)(f >> 28);
439 s_shift_32(s1, s2, 29);
440 s_shift_32(s2, s3, 14);
441 s_shift_32(s3, s4, 15);
442 s_shift_32(s4, s5, 7);
443 s_shift_32(s5, s6, 5);
444 state->s6_l = state->s6_h | (s7_l << 27);
445 state->s6_h = s7_l >> 5;
451 #elif defined(CRYPTO_ACORN128_AVR)
454 extern uint32_t acornEncrypt32
455 (Acorn128State *state, uint32_t plaintext, uint32_t ca, uint32_t cb);
465 void acornPad(Acorn128State *state, uint32_t cb)
467 acornEncrypt32(state, 1, CA_1, cb);
468 acornEncrypt32(state, 0, CA_1, cb);
469 acornEncrypt32(state, 0, CA_1, cb);
470 acornEncrypt32(state, 0, CA_1, cb);
471 acornEncrypt32(state, 0, CA_0, cb);
472 acornEncrypt32(state, 0, CA_0, cb);
473 acornEncrypt32(state, 0, CA_0, cb);
474 acornEncrypt32(state, 0, CA_0, cb);
482 memcpy(state.k, key, 16);
483 #if !defined(CRYPTO_LITTLE_ENDIAN)
484 state.k[0] = le32toh(state.k[0]);
485 state.k[1] = le32toh(state.k[1]);
486 state.k[2] = le32toh(state.k[2]);
487 state.k[3] = le32toh(state.k[3]);
502 memcpy(ivwords, iv, 16);
503 #if !defined(CRYPTO_LITTLE_ENDIAN)
504 ivwords[0] = le32toh(ivwords[0]);
505 ivwords[1] = le32toh(ivwords[1]);
506 ivwords[2] = le32toh(ivwords[2]);
507 ivwords[3] = le32toh(ivwords[3]);
528 acornEncrypt32(&state, state.k[0], CA_1, CB_1);
529 acornEncrypt32(&state, state.k[1], CA_1, CB_1);
530 acornEncrypt32(&state, state.k[2], CA_1, CB_1);
531 acornEncrypt32(&state, state.k[3], CA_1, CB_1);
532 acornEncrypt32(&state, ivwords[0], CA_1, CB_1);
533 acornEncrypt32(&state, ivwords[1], CA_1, CB_1);
534 acornEncrypt32(&state, ivwords[2], CA_1, CB_1);
535 acornEncrypt32(&state, ivwords[3], CA_1, CB_1);
536 acornEncrypt32(&state, state.k[0] ^ 0x00000001, CA_1, CB_1);
537 acornEncrypt32(&state, state.k[1], CA_1, CB_1);
538 acornEncrypt32(&state, state.k[2], CA_1, CB_1);
539 acornEncrypt32(&state, state.k[3], CA_1, CB_1);
540 for (uint8_t i = 0; i < 11; ++i) {
541 acornEncrypt32(&state, state.k[0], CA_1, CB_1);
542 acornEncrypt32(&state, state.k[1], CA_1, CB_1);
543 acornEncrypt32(&state, state.k[2], CA_1, CB_1);
544 acornEncrypt32(&state, state.k[3], CA_1, CB_1);
552 #if defined(CRYPTO_ACORN128_DEFAULT) || defined(CRYPTO_DOC)
556 if (!state.authDone) {
557 acornPad(&state, CB_1);
561 uint32_t temp = ((uint32_t)input[0]) |
562 (((uint32_t)input[1]) << 8) |
563 (((uint32_t)input[2]) << 16) |
564 (((uint32_t)input[3]) << 24);
565 temp = acornEncrypt32Fast(&state, temp);
566 output[0] = (uint8_t)temp;
567 output[1] = (uint8_t)(temp >> 8);
568 output[2] = (uint8_t)(temp >> 16);
569 output[3] = (uint8_t)(temp >> 24);
575 *output++ = acornEncrypt8(&state, *input++, CA_1_BYTE, CB_0_BYTE);
582 if (!state.authDone) {
583 acornPad(&state, CB_1);
587 uint32_t temp = ((uint32_t)input[0]) |
588 (((uint32_t)input[1]) << 8) |
589 (((uint32_t)input[2]) << 16) |
590 (((uint32_t)input[3]) << 24);
591 temp = acornDecrypt32(&state, temp);
592 output[0] = (uint8_t)temp;
593 output[1] = (uint8_t)(temp >> 8);
594 output[2] = (uint8_t)(temp >> 16);
595 output[3] = (uint8_t)(temp >> 24);
601 *output++ = acornDecrypt8(&state, *input++);
613 const uint8_t *input = (
const uint8_t *)data;
615 uint32_t temp = ((uint32_t)input[0]) |
616 (((uint32_t)input[1]) << 8) |
617 (((uint32_t)input[2]) << 16) |
618 (((uint32_t)input[3]) << 24);
619 acornEncrypt32(&state, temp, CA_1, CB_1);
624 acornEncrypt8(&state, *input++, CA_1_BYTE, CB_1_BYTE);
635 acornPad(&state, CB_1);
636 acornPad(&state, CB_0);
640 for (uint8_t i = 0; i < 20; ++i)
641 acornEncrypt32(&state, 0, CA_1, CB_1);
642 temp[0] = acornEncrypt32(&state, 0, CA_1, CB_1);
643 temp[1] = acornEncrypt32(&state, 0, CA_1, CB_1);
644 temp[2] = acornEncrypt32(&state, 0, CA_1, CB_1);
645 temp[3] = acornEncrypt32(&state, 0, CA_1, CB_1);
646 #if !defined(CRYPTO_LITTLE_ENDIAN)
647 temp[0] = htole32(temp[0]);
648 temp[1] = htole32(temp[1]);
649 temp[2] = htole32(temp[2]);
650 temp[3] = htole32(temp[3]);
656 memcpy(tag, temp, len);
669 bool equal = secure_compare(temp, tag, len);
bool checkTag(const void *tag, size_t len)
Finalizes the decryption process and checks the authentication tag.
virtual ~Acorn128()
Destroys this Acorn128 authenticated cipher.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
void computeTag(void *tag, size_t len)
Finalizes the encryption process and computes the authentication tag.
void encrypt(uint8_t *output, const uint8_t *input, size_t len)
Encrypts an input buffer and writes the ciphertext to an output buffer.
size_t keySize() const
Gets the size of the Acorn128 key in bytes.
void decrypt(uint8_t *output, const uint8_t *input, size_t len)
Decrypts an input buffer and writes the plaintext to an output buffer.
size_t tagSize() const
Gets the size of the Acorn128 authentication tag in bytes.
void addAuthData(const void *data, size_t len)
Adds extra data that will be authenticated but not encrypted.
void clear()
Clears all security-sensitive state from this cipher object.
bool setIV(const uint8_t *iv, size_t len)
Sets the initialization vector to use for future encryption and decryption operations.
size_t ivSize() const
Gets the size of the Acorn128 initialization vector in bytes.
Acorn128()
Constructs a new Acorn128 authenticated cipher.