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.