3 This file is part of the Crypto-avr-lib/microcrypt-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 .global bigendian_sum32
31 ; === bigendian_sum32 ===
32 ; function that adds two 32-bit words in the bigendian way and returns the result
33 ; param1: the first 32-bit word
34 ; given in r25,r24,r23,22 (r25 is most significant for little endian)
35 ; param2: the second 32-bit word
36 ; given in r21,r20,r19,18 (r21 is most significant for little endian)
45 .global bigendian_sub32
46 ; === bigendian_sub32 ===
47 ; function that subtracts a 32-bit words from another in the bigendian way and returns the result
48 ; param1: the minuend 32-bit word
49 ; given in r25,r24,r23,22 (r25 is most significant for little endian)
50 ; param2: the subtrahend 32-bit word
51 ; given in r21,r20,r19,18 (r21 is most significant for little endian)
60 /******************************************************************************/
67 #define X3 (((uint8_t*)(&x))[0])
68 #define X2 (((uint8_t*)(&x))[1])
69 #define X1 (((uint8_t*)(&x))[2])
70 #define X0 (((uint8_t*)(&x))[3])
72 #define Z3 (((uint8_t*)(&z))[0])
73 #define Z2 (((uint8_t*)(&z))[1])
74 #define Z1 (((uint8_t*)(&z))[2])
75 #define Z0 (((uint8_t*)(&z))[3])
77 uint32_t g_function(uint32_t x){
79 / * sbox substitution * /
80 X3 = pgm_read_byte(&(seed_sbox2[X3]));
81 X2 = pgm_read_byte(&(seed_sbox1[X2]));
82 X1 = pgm_read_byte(&(seed_sbox2[X1]));
83 X0 = pgm_read_byte(&(seed_sbox1[X0]));
84 / * now the permutation * /
85 Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
86 Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
87 Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
88 Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
115 .global seed_g_function
117 ldi r30, lo8(seed_sbox1)
118 ldi r31, hi8(seed_sbox1)
127 inc r27 /* switch X to point to sbox2 */
136 /* now the secound part */
148 ; mov T3, X1 /* T3 = X1 */
184 .byte 169, 133, 214, 211, 84, 29, 172, 37
185 .byte 93, 67, 24, 30, 81, 252, 202, 99
186 .byte 40, 68, 32, 157, 224, 226, 200, 23
187 .byte 165, 143, 3, 123, 187, 19, 210, 238
188 .byte 112, 140, 63, 168, 50, 221, 246, 116
189 .byte 236, 149, 11, 87, 92, 91, 189, 1
190 .byte 36, 28, 115, 152, 16, 204, 242, 217
191 .byte 44, 231, 114, 131, 155, 209, 134, 201
192 .byte 96, 80, 163, 235, 13, 182, 158, 79
193 .byte 183, 90, 198, 120, 166, 18, 175, 213
194 .byte 97, 195, 180, 65, 82, 125, 141, 8
195 .byte 31, 153, 0, 25, 4, 83, 247, 225
196 .byte 253, 118, 47, 39, 176, 139, 14, 171
197 .byte 162, 110, 147, 77, 105, 124, 9, 10
198 .byte 191, 239, 243, 197, 135, 20, 254, 100
199 .byte 222, 46, 75, 26, 6, 33, 107, 102
200 .byte 2, 245, 146, 138, 12, 179, 126, 208
201 .byte 122, 71, 150, 229, 38, 128, 173, 223
202 .byte 161, 48, 55, 174, 54, 21, 34, 56
203 .byte 244, 167, 69, 76, 129, 233, 132, 151
204 .byte 53, 203, 206, 60, 113, 17, 199, 137
205 .byte 117, 251, 218, 248, 148, 89, 130, 196
206 .byte 255, 73, 57, 103, 192, 207, 215, 184
207 .byte 15, 142, 66, 35, 145, 108, 219, 164
208 .byte 52, 241, 72, 194, 111, 61, 45, 64
209 .byte 190, 62, 188, 193, 170, 186, 78, 85
210 .byte 59, 220, 104, 127, 156, 216, 74, 86
211 .byte 119, 160, 237, 70, 181, 43, 101, 250
212 .byte 227, 185, 177, 159, 94, 249, 230, 178
213 .byte 49, 234, 109, 95, 228, 240, 205, 136
214 .byte 22, 58, 88, 212, 98, 41, 7, 51
215 .byte 232, 27, 5, 121, 144, 106, 42, 154
219 .byte 56, 232, 45, 166, 207, 222, 179, 184
220 .byte 175, 96, 85, 199, 68, 111, 107, 91
221 .byte 195, 98, 51, 181, 41, 160, 226, 167
222 .byte 211, 145, 17, 6, 28, 188, 54, 75
223 .byte 239, 136, 108, 168, 23, 196, 22, 244
224 .byte 194, 69, 225, 214, 63, 61, 142, 152
225 .byte 40, 78, 246, 62, 165, 249, 13, 223
226 .byte 216, 43, 102, 122, 39, 47, 241, 114
227 .byte 66, 212, 65, 192, 115, 103, 172, 139
228 .byte 247, 173, 128, 31, 202, 44, 170, 52
229 .byte 210, 11, 238, 233, 93, 148, 24, 248
230 .byte 87, 174, 8, 197, 19, 205, 134, 185
231 .byte 255, 125, 193, 49, 245, 138, 106, 177
232 .byte 209, 32, 215, 2, 34, 4, 104, 113
233 .byte 7, 219, 157, 153, 97, 190, 230, 89
234 .byte 221, 81, 144, 220, 154, 163, 171, 208
235 .byte 129, 15, 71, 26, 227, 236, 141, 191
236 .byte 150, 123, 92, 162, 161, 99, 35, 77
237 .byte 200, 158, 156, 58, 12, 46, 186, 110
238 .byte 159, 90, 242, 146, 243, 73, 120, 204
239 .byte 21, 251, 112, 117, 127, 53, 16, 3
240 .byte 100, 109, 198, 116, 213, 180, 234, 9
241 .byte 118, 25, 254, 64, 18, 224, 189, 5
242 .byte 250, 1, 240, 42, 94, 169, 86, 67
243 .byte 133, 20, 137, 155, 176, 229, 72, 121
244 .byte 151, 252, 30, 130, 33, 140, 27, 95
245 .byte 119, 84, 178, 29, 37, 79, 0, 70
246 .byte 237, 88, 82, 235, 126, 218, 201, 253
247 .byte 48, 149, 101, 60, 182, 228, 187, 124
248 .byte 14, 80, 57, 38, 50, 132, 105, 147
249 .byte 55, 231, 36, 164, 203, 83, 10, 135
250 .byte 217, 76, 131, 143, 206, 59, 74, 183
252 /******************************************************************************/
256 uint64_t f_function(const uint64_t* a, uint32_t k0, uint32_t k1){
259 c = *a & 0x00000000FFFFFFFFLL;
260 d = (*a>>32) & 0x00000000FFFFFFFFLL;
265 c = bigendian_sum32(c,d);
267 d = bigendian_sum32(c,d);
269 c = bigendian_sum32(c,d);
270 return ((uint64_t)d << 32) | c;
286 .global seed_f_function
310 rcall seed_g_function
320 rcall seed_g_function
330 rcall seed_g_function
349 /******************************************************************************/
351 void seed_init(uint8_t * key, seed_ctx_t * ctx){
352 memcpy(ctx->k, key, 128/8);
367 /******************************************************************************/
373 keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
379 / * ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
380 ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
381 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
382 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
383 ret.k0 = seed_g_function(ret.k0);
384 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
385 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
386 ret.k1 = seed_g_function(ret.k1);
389 / * odd round (1,3,5, ...) * /
390 ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
392 / * even round (0,2,4, ...) * /
393 ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
400 * param keystate: r24:r25
401 * param curround: r22
413 ldi r30, lo8(seed_kc)
414 ldi r31, hi8(seed_kc)
442 rcall seed_g_function
467 rcall seed_g_function
475 .global seed_getnextkeys
551 /******************************************************************************/
553 keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
560 / * odd round (1,3,5, ..., 15) * /
561 ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
563 / * even round (0,2,4, ..., 14) * /
564 ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
566 / * ret.k0 = seed_g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
567 ret.k1 = seed_g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); * /
568 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
569 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
570 ret.k0 = seed_g_function(ret.k0);
571 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
572 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
573 ret.k1 = seed_g_function(ret.k1);
579 * param keystate: r24:r25
580 * param curround: r22
583 .global seed_getprevkeys
658 /******************************************************************************/
679 /******************************************************************************/
681 #define L (((uint64_t*)buffer)[0])
682 #define R (((uint64_t*)buffer)[1])
684 void seed_enc(void * buffer, seed_ctx_t * ctx){
688 k = seed_getnextkeys(ctx->k, 2*r);
690 DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
691 DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
692 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
693 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
695 L ^= seed_f_function(&R,k.k0,k.k1);
697 k = seed_getnextkeys(ctx->k, 2*r+1);
699 DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
700 DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
701 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
702 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
704 R ^= seed_f_function(&L,k.k0,k.k1);
706 / * just an exchange without temp. variable * /
713 * param buffer: r24:r25
736 rcall seed_getnextkeys
738 /* use pen & paper to understand the following permutation */
747 rcall seed_f_function
778 rcall seed_getnextkeys
788 rcall seed_f_function