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