25 #include "utility/RotateUtil.h" 
   26 #include "utility/EndianUtil.h" 
   63 #define USE_AVR_INLINE_ASM 1 
   94 #define pack64(data, value) \ 
   96         uint64_t v = htobe64((value)); \ 
   97         memcpy((data), &v, sizeof(uint64_t)); \ 
   99 #define unpack64(value, data) \ 
  101         memcpy(&(value), (data), sizeof(uint64_t)); \ 
  102         (value) = be64toh((value)); \ 
  107 #if USE_AVR_INLINE_ASM 
  114     } 
else if (len == 24) {
 
  117     } 
else if (len == 16) {
 
  124     uint8_t r = rounds - 1;
 
  125     __asm__ __volatile__ (
 
  126         "ld __tmp_reg__,-X\n" 
  127         "st Z+,__tmp_reg__\n" 
  128         "ld __tmp_reg__,-X\n" 
  129         "st Z+,__tmp_reg__\n" 
  130         "ld __tmp_reg__,-X\n" 
  131         "st Z+,__tmp_reg__\n" 
  132         "ld __tmp_reg__,-X\n" 
  133         "st Z+,__tmp_reg__\n" 
  134         "ld __tmp_reg__,-X\n" 
  135         "st Z+,__tmp_reg__\n" 
  136         "ld __tmp_reg__,-X\n" 
  137         "st Z+,__tmp_reg__\n" 
  138         "ld __tmp_reg__,-X\n" 
  139         "st Z+,__tmp_reg__\n" 
  140         "ld __tmp_reg__,-X\n" 
  141         "st Z+,__tmp_reg__\n" 
  147         "ld __tmp_reg__,-X\n" 
  148         "st Z+,__tmp_reg__\n" 
  166         "adc r27,__zero_reg__\n" 
  176         "sbc r27,__zero_reg__\n" 
  188         "adc r27,__zero_reg__\n" 
  198         "sbc r27,__zero_reg__\n" 
  208         "adc r16, __zero_reg__\n" 
  217         "adc r16, __zero_reg__\n" 
  226         "adc r16, __zero_reg__\n" 
  257         "st X+,__zero_reg__\n" 
  260         : : 
"z"(k), 
"x"(key + len), 
"r"(l), 
"Q"(mb), 
"Q"(r)
 
  261         : 
"r8", 
"r9", 
"r10", 
"r11", 
"r12", 
"r13", 
"r14", 
"r15",
 
  262           "r16", 
"r17", 
"r18", 
"r19", 
"r20", 
"r21", 
"r22", 
"r23", 
"memory" 
  272         unpack64(l[1], key + 8);
 
  273         unpack64(l[0], key + 16);
 
  274         unpack64(k[0], key + 24);
 
  275     } 
else if (len == 24) {
 
  278         unpack64(l[0], key + 8);
 
  279         unpack64(k[0], key + 16);
 
  280     } 
else if (len == 16) {
 
  283         unpack64(k[0], key + 8);
 
  289     uint8_t li_out = m - 1;
 
  290     for (uint8_t i = 0; i < (rounds - 1); ++i) {
 
  291         l[li_out] = (k[i] + rightRotate8_64(l[li_in])) ^ i;
 
  292         k[i + 1] = leftRotate3_64(k[i]) ^ l[li_out];
 
  305 #if USE_AVR_INLINE_ASM 
  307     __asm__ __volatile__ (
 
  333         "ld __tmp_reg__,Z+\n" 
  334         "eor __tmp_reg__,r9\n" 
  349         "mov r8,__tmp_reg__\n" 
  358         "adc r16, __zero_reg__\n" 
  367         "adc r16, __zero_reg__\n" 
  376         "adc r16, __zero_reg__\n" 
  407         : : 
"x"(input), 
"z"(k), 
"r"(rounds), 
"Q"(output)
 
  408         : 
"r8", 
"r9", 
"r10", 
"r11", 
"r12", 
"r13", 
"r14", 
"r15",
 
  409           "r16", 
"r17", 
"r18", 
"r19", 
"r20", 
"r21", 
"r22", 
"r23", 
"memory" 
  413     const uint64_t *s = k;
 
  415     unpack64(y, input + 8);
 
  416     for (uint8_t round = rounds; round > 0; --round, ++s) {
 
  417         x = (rightRotate8_64(x) + y) ^ s[0];
 
  418         y = leftRotate3_64(y) ^ x;
 
  421     pack64(output + 8, y);
 
  427 #if USE_AVR_INLINE_ASM 
  429     __asm__ __volatile__ (
 
  485         "ld __tmp_reg__,-Z\n" 
  486         "eor __tmp_reg__,r15\n" 
  501         "mov r8,__tmp_reg__\n" 
  532         : : 
"x"(input), 
"z"(k + rounds), 
"r"(rounds), 
"Q"(output)
 
  533         : 
"r8", 
"r9", 
"r10", 
"r11", 
"r12", 
"r13", 
"r14", 
"r15",
 
  534           "r16", 
"r17", 
"r18", 
"r19", 
"r20", 
"r21", 
"r22", 
"r23", 
"memory" 
  538     const uint64_t *s = k + rounds - 1;
 
  540     unpack64(y, input + 8);
 
  541     for (uint8_t round = rounds; round > 0; --round, --s) {
 
  542         y = rightRotate3_64(x ^ y);
 
  543         x = leftRotate8_64((x ^ s[0]) - y);
 
  546     pack64(output + 8, y);
 
Speck()
Constructs a Speck block cipher with no initial key.
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
void clear()
Clears all security-sensitive state from this block cipher.
size_t blockSize() const
Size of a single block processed by this cipher, in bytes.
size_t keySize() const
Default size of the key for this block cipher, in bytes.
void decryptBlock(uint8_t *output, const uint8_t *input)
Decrypts a single block using this cipher.
void encryptBlock(uint8_t *output, const uint8_t *input)
Encrypts a single block using this cipher.