3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * \brief SEED parts in assembler for AVR
28 #include "avr-asm-macros.S"
30 /******************************************************************************/
37 #define X3 (((uint8_t*)(&x))[0])
38 #define X2 (((uint8_t*)(&x))[1])
39 #define X1 (((uint8_t*)(&x))[2])
40 #define X0 (((uint8_t*)(&x))[3])
42 #define Z3 (((uint8_t*)(&z))[0])
43 #define Z2 (((uint8_t*)(&z))[1])
44 #define Z1 (((uint8_t*)(&z))[2])
45 #define Z0 (((uint8_t*)(&z))[3])
47 uint32_t g_function(uint32_t x){
49 / * sbox substitution * /
50 X3 = pgm_read_byte(&(seed_sbox2[X3]));
51 X2 = pgm_read_byte(&(seed_sbox1[X2]));
52 X1 = pgm_read_byte(&(seed_sbox2[X1]));
53 X0 = pgm_read_byte(&(seed_sbox1[X0]));
54 / * now the permutation * /
55 Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
56 Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
57 Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
58 Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
86 ldi r30, lo8(seed_sbox1)
87 ldi r31, hi8(seed_sbox1)
96 inc r27 /* switch X to point to sbox2 */
105 /* now the secound part */
117 ; mov T3, X1 /* T3 = X1 */
153 .byte 169, 133, 214, 211, 84, 29, 172, 37
154 .byte 93, 67, 24, 30, 81, 252, 202, 99
155 .byte 40, 68, 32, 157, 224, 226, 200, 23
156 .byte 165, 143, 3, 123, 187, 19, 210, 238
157 .byte 112, 140, 63, 168, 50, 221, 246, 116
158 .byte 236, 149, 11, 87, 92, 91, 189, 1
159 .byte 36, 28, 115, 152, 16, 204, 242, 217
160 .byte 44, 231, 114, 131, 155, 209, 134, 201
161 .byte 96, 80, 163, 235, 13, 182, 158, 79
162 .byte 183, 90, 198, 120, 166, 18, 175, 213
163 .byte 97, 195, 180, 65, 82, 125, 141, 8
164 .byte 31, 153, 0, 25, 4, 83, 247, 225
165 .byte 253, 118, 47, 39, 176, 139, 14, 171
166 .byte 162, 110, 147, 77, 105, 124, 9, 10
167 .byte 191, 239, 243, 197, 135, 20, 254, 100
168 .byte 222, 46, 75, 26, 6, 33, 107, 102
169 .byte 2, 245, 146, 138, 12, 179, 126, 208
170 .byte 122, 71, 150, 229, 38, 128, 173, 223
171 .byte 161, 48, 55, 174, 54, 21, 34, 56
172 .byte 244, 167, 69, 76, 129, 233, 132, 151
173 .byte 53, 203, 206, 60, 113, 17, 199, 137
174 .byte 117, 251, 218, 248, 148, 89, 130, 196
175 .byte 255, 73, 57, 103, 192, 207, 215, 184
176 .byte 15, 142, 66, 35, 145, 108, 219, 164
177 .byte 52, 241, 72, 194, 111, 61, 45, 64
178 .byte 190, 62, 188, 193, 170, 186, 78, 85
179 .byte 59, 220, 104, 127, 156, 216, 74, 86
180 .byte 119, 160, 237, 70, 181, 43, 101, 250
181 .byte 227, 185, 177, 159, 94, 249, 230, 178
182 .byte 49, 234, 109, 95, 228, 240, 205, 136
183 .byte 22, 58, 88, 212, 98, 41, 7, 51
184 .byte 232, 27, 5, 121, 144, 106, 42, 154
188 .byte 56, 232, 45, 166, 207, 222, 179, 184
189 .byte 175, 96, 85, 199, 68, 111, 107, 91
190 .byte 195, 98, 51, 181, 41, 160, 226, 167
191 .byte 211, 145, 17, 6, 28, 188, 54, 75
192 .byte 239, 136, 108, 168, 23, 196, 22, 244
193 .byte 194, 69, 225, 214, 63, 61, 142, 152
194 .byte 40, 78, 246, 62, 165, 249, 13, 223
195 .byte 216, 43, 102, 122, 39, 47, 241, 114
196 .byte 66, 212, 65, 192, 115, 103, 172, 139
197 .byte 247, 173, 128, 31, 202, 44, 170, 52
198 .byte 210, 11, 238, 233, 93, 148, 24, 248
199 .byte 87, 174, 8, 197, 19, 205, 134, 185
200 .byte 255, 125, 193, 49, 245, 138, 106, 177
201 .byte 209, 32, 215, 2, 34, 4, 104, 113
202 .byte 7, 219, 157, 153, 97, 190, 230, 89
203 .byte 221, 81, 144, 220, 154, 163, 171, 208
204 .byte 129, 15, 71, 26, 227, 236, 141, 191
205 .byte 150, 123, 92, 162, 161, 99, 35, 77
206 .byte 200, 158, 156, 58, 12, 46, 186, 110
207 .byte 159, 90, 242, 146, 243, 73, 120, 204
208 .byte 21, 251, 112, 117, 127, 53, 16, 3
209 .byte 100, 109, 198, 116, 213, 180, 234, 9
210 .byte 118, 25, 254, 64, 18, 224, 189, 5
211 .byte 250, 1, 240, 42, 94, 169, 86, 67
212 .byte 133, 20, 137, 155, 176, 229, 72, 121
213 .byte 151, 252, 30, 130, 33, 140, 27, 95
214 .byte 119, 84, 178, 29, 37, 79, 0, 70
215 .byte 237, 88, 82, 235, 126, 218, 201, 253
216 .byte 48, 149, 101, 60, 182, 228, 187, 124
217 .byte 14, 80, 57, 38, 50, 132, 105, 147
218 .byte 55, 231, 36, 164, 203, 83, 10, 135
219 .byte 217, 76, 131, 143, 206, 59, 74, 183
221 /******************************************************************************/
225 uint64_t f_function(const uint64_t* a, uint32_t k0, uint32_t k1){
228 c = *a & 0x00000000FFFFFFFFLL;
229 d = (*a>>32) & 0x00000000FFFFFFFFLL;
234 c = bigendian_sum32(c,d);
236 d = bigendian_sum32(c,d);
238 c = bigendian_sum32(c,d);
239 return ((uint64_t)d << 32) | c;
278 rcall seed_g_function
288 rcall seed_g_function
298 rcall seed_g_function
317 /******************************************************************************/
319 void seed_init(uint8_t * key, seed_ctx_t * ctx){
320 memcpy(ctx->k, key, 128/8);
335 /******************************************************************************/
341 keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
347 / * ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
348 ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
349 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
350 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
351 ret.k0 = seed_g_function(ret.k0);
352 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
353 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
354 ret.k1 = seed_g_function(ret.k1);
357 / * odd round (1,3,5, ...) * /
358 ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
360 / * even round (0,2,4, ...) * /
361 ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
368 * param keystate: r24:r25
369 * param curround: r22
381 ldi r30, lo8(seed_kc)
382 ldi r31, hi8(seed_kc)
410 rcall seed_g_function
435 rcall seed_g_function
518 /******************************************************************************/
520 keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
527 / * odd round (1,3,5, ..., 15) * /
528 ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
530 / * even round (0,2,4, ..., 14) * /
531 ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
533 / * ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
534 ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
535 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
536 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
537 ret.k0 = seed_g_function(ret.k0);
538 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
539 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
540 ret.k1 = seed_g_function(ret.k1);
546 * param keystate: r24:r25
547 * param curround: r22
624 /******************************************************************************/
644 /******************************************************************************/
646 #define L (((uint64_t*)buffer)[0])
647 #define R (((uint64_t*)buffer)[1])
649 void seed_enc(void * buffer, seed_ctx_t * ctx){
653 k = seed_getnextkeys(ctx->k, 2*r);
655 DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
656 DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
657 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
658 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
660 L ^= seed_f_function(&R,k.k0,k.k1);
662 k = seed_getnextkeys(ctx->k, 2*r+1);
664 DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
665 DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
666 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
667 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
669 R ^= seed_f_function(&L,k.k0,k.k1);
671 / * just an exchange without temp. variable * /
678 * param buffer: r24:r25
701 rcall seed_getnextkeys
703 /* use pen & paper to understand the following permutation */
712 rcall seed_f_function
743 rcall seed_getnextkeys
753 rcall seed_f_function
801 /******************************************************************************/
803 #define L (((uint64_t*)buffer)[0])
804 #define R (((uint64_t*)buffer)[1])
806 void seed_dec(void * buffer, seed_ctx_t * ctx){
810 k = seed_getprevkeys(ctx->k, 2*r+1);
812 DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
813 DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
814 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
815 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
817 L ^= seed_f_function(&R,k.k0,k.k1);
819 k = seed_getprevkeys(ctx->k, 2*r+0);
821 DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
822 DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
823 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
824 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
826 R ^= seed_f_function(&L,k.k0,k.k1);
828 / * just an exchange without temp. variable * /
835 * param buffer: r24:r25
860 rcall seed_getprevkeys
862 /* use pen & paper to understand the following permutation */
871 rcall seed_f_function
901 rcall seed_getprevkeys
911 rcall seed_f_function