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.