]> git.cryptolib.org Git - avr-crypto-lib.git/blob - seed.c
f0c3a8535cb83f42fd401e8d610c2bad814e61d4
[avr-crypto-lib.git] / seed.c
1  /**
2  * \file        seed.c
3  * \author      Daniel Otte 
4  * \date        2007-06-1
5  * \brief       SEED parts in C for AVR
6  * \par License 
7  * GPL
8  * 
9  */
10 #include <stdint.h>
11 #include <avr/pgmspace.h>
12 #include <string.h>
13 #include "seed_sbox.h"
14 #include "uart.h"
15 #include "debug.h"
16
17
18 static uint64_t f_function(uint64_t a, uint32_t k0, uint32_t k1);
19 static uint32_t g_function(uint32_t x);
20
21 /******************************************************************************/
22 /*
23 void changeendian32(uint32_t * a){
24         *a = (*a & 0x000000FF) << 24 |
25                  (*a & 0x0000FF00) <<  8 |
26                  (*a & 0x00FF0000) >>  8 |
27                  (*a & 0xFF000000) >> 24;
28 }
29 */
30 /******************************************************************************/
31 /*
32 void changeendian64(uint64_t * a){
33         *a = (*a & 0x00000000000000FFLL) << 56 |
34                  (*a & 0x000000000000FF00LL) << 40 |
35                  (*a & 0x0000000000FF0000LL) << 24 |
36                  (*a & 0x00000000FF000000LL) <<  8 |
37                  (*a & 0x000000FF00000000LL) >>  8 |
38                  (*a & 0x0000FF0000000000LL) >> 24 |
39                  (*a & 0x00FF000000000000LL) >> 40 |
40                  (*a & 0xFF00000000000000LL) >> 56 ;
41 }
42 */
43 /******************************************************************************/
44
45 uint32_t bigendian_sum32(uint32_t a, uint32_t b);/*{
46         changeendian32(&a);
47         changeendian32(&b);
48         a += b;
49         changeendian32(&a);
50         return a;
51 }
52 */
53 /******************************************************************************/
54 /* static */
55 uint32_t bigendian_sub32(uint32_t a, uint32_t b);/*{
56         changeendian32(&a);
57         changeendian32(&b);
58         a -= b;
59         changeendian32(&a);
60         return a;
61 }
62 */
63 /******************************************************************************/
64 static inline
65 uint64_t bigendian_rotl8_64(uint64_t a){
66         /*
67         changeendian64(&a);
68         a = (a<<8) | (a>>(64-8));
69         changeendian64(&a);
70         */
71         a = (a>>8) | (a<<(64-8));
72         return a;
73 }
74
75 /******************************************************************************/
76 static inline
77 uint64_t bigendian_rotr8_64(uint64_t a){
78         /*
79         changeendian64(&a);
80         a = (a>>8) | (a<<(64-8));
81         changeendian64(&a);
82         */
83         a = (a<<8) | (a>>(64-8));
84         return a;
85 }
86
87 /******************************************************************************/
88 static
89 uint64_t f_function(uint64_t a, uint32_t k0, uint32_t k1){
90         uint32_t c,d;
91
92         c = a & 0x00000000FFFFFFFFLL;
93         d = (a>>32) & 0x00000000FFFFFFFFLL;
94         
95         c ^= k0;        d ^= k1;
96         d ^= c;
97         d = g_function(d);
98         c = bigendian_sum32(c,d);
99         c = g_function(c);
100         d = bigendian_sum32(c,d);
101         d = g_function(d);
102         c = bigendian_sum32(c,d);
103         a = ((uint64_t)d << 32) | c;
104         return a;
105 }
106
107 /******************************************************************************/
108 #define M0 0xfc
109 #define M1 0xf3
110 #define M2 0xcf
111 #define M3 0x3f
112
113 #define X3 (((uint8_t*)(&x))[0])
114 #define X2 (((uint8_t*)(&x))[1])
115 #define X1 (((uint8_t*)(&x))[2])
116 #define X0 (((uint8_t*)(&x))[3])
117
118 #define Z3 (((uint8_t*)(&z))[0])
119 #define Z2 (((uint8_t*)(&z))[1])
120 #define Z1 (((uint8_t*)(&z))[2])
121 #define Z0 (((uint8_t*)(&z))[3])
122
123 static
124 uint32_t g_function(uint32_t x){
125         uint32_t z;
126         /* sbox substitution */
127         X3 = pgm_read_byte(&(seed_sbox2[X3]));
128         X2 = pgm_read_byte(&(seed_sbox1[X2]));
129         X1 = pgm_read_byte(&(seed_sbox2[X1]));
130         X0 = pgm_read_byte(&(seed_sbox1[X0]));
131         /* now the permutation */
132         Z0 = (X0 & M0) ^ (X1 & M1) ^ (X2 & M2) ^ (X3 & M3);
133         Z1 = (X0 & M1) ^ (X1 & M2) ^ (X2 & M3) ^ (X3 & M0);
134         Z2 = (X0 & M2) ^ (X1 & M3) ^ (X2 & M0) ^ (X3 & M1);
135         Z3 = (X0 & M3) ^ (X1 & M0) ^ (X2 & M1) ^ (X3 & M2);
136         return z;
137 }
138 /******************************************************************************/
139 typedef struct {
140         uint32_t k0, k1;
141 } keypair_t;
142
143 keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
144         keypair_t ret;
145         if (curround>15){
146                 /* ERROR */
147                 ret.k0 = ret.k1 = 0;
148         } else {
149         /*      ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
150                 ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
151                 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
152                 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
153                 ret.k0 = g_function(ret.k0);
154                 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
155                 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
156                 ret.k1 = g_function(ret.k1);
157                 
158                 if (curround & 1){
159                         /* odd round (1,3,5, ...) */
160                         ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
161                 } else {
162                         /* even round (0,2,4, ...) */
163                         ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
164                 }
165         }
166         return ret;
167 }
168
169
170 /******************************************************************************/
171
172 keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
173         keypair_t ret;
174         if (curround>15){
175                 /* ERROR */
176                 ret.k0 = ret.k1 = 0;
177         } else {
178                 if (curround & 1){
179                         /* odd round (1,3,5, ..., 15) */
180                         ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
181                 } else {
182                         /* even round (0,2,4, ..., 14) */
183                         ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
184                 }
185         /*      ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
186                 ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
187                 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
188                 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
189                 ret.k0 = g_function(ret.k0);
190                 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
191                 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
192                 ret.k1 = g_function(ret.k1);
193                 }
194         return ret;
195 }
196
197 /******************************************************************************/
198
199 typedef struct{
200         uint32_t k[4];
201 } seed_ctx_t;
202
203 /******************************************************************************/
204
205 void seed_init(seed_ctx_t * ctx, uint8_t * key){
206         memcpy(ctx->k, key, 128/8);
207 }
208
209 /******************************************************************************/
210
211 #define L (((uint64_t*)buffer)[0])
212 #define R (((uint64_t*)buffer)[1])
213
214 void seed_encrypt(seed_ctx_t * ctx, void * buffer){
215         uint8_t r;
216         keypair_t k;
217         for(r=0; r<8; ++r){
218                         k = getnextkeys(ctx->k, 2*r);
219 /*
220         DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
221         DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
222         DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
223         DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
224 */
225                         L ^= f_function(R,k.k0,k.k1);
226                         
227                         k = getnextkeys(ctx->k, 2*r+1);
228 /*
229         DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
230         DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
231         DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
232         DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
233 */
234                         R ^= f_function(L,k.k0,k.k1);
235         }
236         /* just an exchange without temp. variable */
237         L ^= R;
238         R ^= L;
239         L ^= R;
240 }
241
242 /******************************************************************************/
243
244 #define L (((uint64_t*)buffer)[0])
245 #define R (((uint64_t*)buffer)[1])
246
247 void seed_decrypt(seed_ctx_t * ctx, void * buffer){
248         int8_t r;
249         keypair_t k;
250         for(r=7; r>=0; --r){
251                         k = getprevkeys(ctx->k, 2*r+1);
252 /*
253         DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
254         DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
255         DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
256         DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
257 */
258                         L ^= f_function(R,k.k0,k.k1);
259                         
260                         k = getprevkeys(ctx->k, 2*r+0);
261 /*
262         DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
263         DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
264         DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
265         DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
266 */
267                         R ^= f_function(L,k.k0,k.k1);
268         }
269         /* just an exchange without temp. variable */
270         L ^= R;
271         R ^= L;
272         L ^= R;
273 }
274
275
276
277
278
279
280
281
282
283
284