]> git.cryptolib.org Git - avr-crypto-lib.git/blob - camellia/camellia_C.c
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / camellia / camellia_C.c
1 /* camellia_C.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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  * 
21  * 
22  * 
23  * 
24  */
25  
26 #include <stdint.h>
27 #include <avr/io.h>
28 #include <avr/pgmspace.h>
29 #include "camellia.h"
30 #if 0
31  #include "cli.h"
32  #include "debug.h"
33  #include <util/delay.h>
34 #endif 
35 /*****************************************************************************/
36
37 static
38 uint8_t rol(uint8_t a, uint8_t n){
39         return ((a<<n) | (a>>(8-n)));
40 }
41
42 /*****************************************************************************/
43
44 static
45 uint8_t ror(uint8_t a, uint8_t n){
46         return ((a<<(8-n)) | (a>>n));
47 }
48
49 /*****************************************************************************/
50
51 static
52 uint32_t rol32(uint32_t a, uint8_t n){
53         return ((a<<n)|(a>>(32-n)));
54 }
55
56 /*****************************************************************************/
57 /*
58 static
59 uint64_t rol64(uint64_t a, uint8_t n){
60         return ((a<<n)|(a>>(64-n)));
61 }
62 */
63 /*****************************************************************************/
64  
65 static
66 const uint8_t camellia_s1_table[256] PROGMEM = {
67  112, 130,  44, 236, 179,  39, 192, 229, 228, 133,  87,  53, 234,  12, 174,  65,
68   35, 239, 107, 147,  69,  25, 165,  33, 237,  14,  79,  78,  29, 101, 146, 189,
69  134, 184, 175, 143, 124, 235,  31, 206,  62,  48, 220,  95,  94, 197,  11,  26,
70  166, 225,  57, 202, 213,  71,  93,  61, 217,   1,  90, 214,  81,  86, 108,  77,
71  139,  13, 154, 102, 251, 204, 176,  45, 116,  18,  43,  32, 240, 177, 132, 153,
72  223,  76, 203, 194,  52, 126, 118,   5, 109, 183, 169,  49, 209,  23,   4, 215,
73   20,  88,  58,  97, 222,  27,  17,  28,  50,  15, 156,  22,  83,  24, 242,  34,
74  254,  68, 207, 178, 195, 181, 122, 145,  36,   8, 232, 168,  96, 252, 105,  80,
75  170, 208, 160, 125, 161, 137,  98, 151,  84,  91,  30, 149, 224, 255, 100, 210,
76   16, 196,   0,  72, 163, 247, 117, 219, 138,   3, 230, 218,   9,  63, 221, 148,
77  135,  92, 131,   2, 205,  74, 144,  51, 115, 103, 246, 243, 157, 127, 191, 226,
78   82, 155, 216,  38, 200,  55, 198,  59, 129, 150, 111,  75,  19, 190,  99,  46,
79  233, 121, 167, 140, 159, 110, 188, 142,  41, 245, 249, 182,  47, 253, 180,  89,
80  120, 152,   6, 106, 231,  70, 113, 186, 212,  37, 171,  66, 136, 162, 141, 250,
81  114,   7, 185,  85, 248, 238, 172,  10,  54,  73,  42, 104,  60,  56, 241, 164,
82   64,  40, 211, 123, 187, 201,  67, 193,  21, 227, 173, 244, 119, 199, 128, 158
83 };
84
85 /*****************************************************************************/
86
87 static
88 uint8_t camellia_s1(uint8_t b){
89         return pgm_read_byte(&(camellia_s1_table[b]));
90 }
91
92 /*****************************************************************************/
93
94 static
95 uint8_t camellia_s2(uint8_t b){
96         return rol(pgm_read_byte(&(camellia_s1_table[b])),1);
97 }
98
99 /*****************************************************************************/
100
101 static
102 uint8_t camellia_s3(uint8_t b){
103         return ror(pgm_read_byte(&(camellia_s1_table[b])),1);
104 }
105
106 /*****************************************************************************/
107
108 static
109 uint8_t camellia_s4(uint8_t b){
110         return pgm_read_byte(&(camellia_s1_table[rol(b,1)]));
111 }
112
113 /*****************************************************************************/
114
115 static
116 uint64_t camellia_s(uint64_t d){
117 //      cli_putstr("\n\r S von "); cli_hexdump(&(d), 8);
118         #define D ((uint8_t*)(&d))
119         D[7] = camellia_s1(D[7]);
120         D[6] = camellia_s2(D[6]);
121         D[5] = camellia_s3(D[5]);
122         D[4] = camellia_s4(D[4]);
123         
124         D[3] = camellia_s2(D[3]);
125         D[2] = camellia_s3(D[2]);
126         D[1] = camellia_s4(D[1]);
127         D[0] = camellia_s1(D[0]);
128         #undef D
129 //      cli_putstr(" ist "); cli_hexdump(&(d), 8);
130         return d;
131 }
132
133 /*****************************************************************************/
134
135 static
136 uint64_t camellia_p(uint64_t d){
137         uint64_t z=0;
138         #define D ((uint8_t*)(&d))
139         #define Z ((uint8_t*)(&z))
140 /*
141         Z[0] = D[4] ^ D[3] ^ D[1];
142         Z[1] = D[5] ^ D[0] ^ D[2];
143         Z[2] = D[6] ^ D[1] ^ D[3];
144         Z[3] = D[7] ^ D[2] ^ D[0];
145         Z[4] = D[0] ^ D[6] ^ D[5];
146         Z[5] = D[1] ^ D[7] ^ D[6];
147         Z[6] = D[2] ^ D[4] ^ D[7];
148         Z[7] = D[3] ^ D[5] ^ D[4];
149 */
150 //      Z[7] = z1 z3 z4 z6 z7 z8
151 //      cli_putstr("\n\r P von "); cli_hexdump(&(d), 8);
152         
153         Z[7] = D[7] ^        D[5] ^ D[4] ^        D[2] ^ D[1] ^ D[0];
154         Z[6] = D[7] ^ D[6]        ^ D[4] ^ D[3] ^        D[1] ^ D[0];
155         Z[5] = D[7] ^ D[6] ^ D[5] ^        D[3] ^ D[2] ^        D[0];
156         Z[4] =        D[6] ^ D[5] ^ D[4] ^ D[3] ^ D[2] ^ D[1]       ;
157         Z[3] = D[7] ^ D[6] ^                      D[2] ^ D[1] ^ D[0];
158         Z[2] =        D[6] ^ D[5] ^        D[3] ^        D[1] ^ D[0];
159         Z[1] =               D[5] ^ D[4] ^ D[3] ^ D[2] ^        D[0];
160         Z[0] = D[7] ^               D[4] ^ D[3] ^ D[2] ^ D[1]       ;
161         
162 //      cli_putstr(" ist "); cli_hexdump(&(z), 8);
163                         
164         #undef Z
165         #undef D
166         return z;
167 }
168
169 /*****************************************************************************/
170
171 static
172 uint64_t camellia_f(uint64_t x, uint64_t k){
173         uint64_t y;
174         y = camellia_p(camellia_s(x ^ k));
175         return y;
176 }
177
178 /*****************************************************************************/
179
180 static
181 uint64_t camellia_fl(uint64_t x, uint64_t k){
182 //      uint64_t lx, lk, y;
183         uint32_t lx[2], lk[2], yr, yl;
184         lx[0]=(uint32_t)x;
185         lx[1]=(uint32_t)(x>>32); 
186         lk[0]=(uint32_t)k; 
187         lk[1]=(uint32_t)(k>>32); 
188         #define Y ((uint32_t*)y)
189         #define X ((uint32_t*)lx)
190         #define K ((uint32_t*)lk)
191
192         yr = rol32((X[1]) & (K[1]) ,1) ^ (X[0]); /* Yr */
193         yl = (yr | K[0]) ^ (X[1]);           /* Yl */
194         
195 /*      
196         cli_putstr("\r\nFL(");
197         cli_hexdump(&(x), 8);
198         cli_putstr(", ");
199         cli_hexdump(&(k), 8);
200         cli_putstr(") = ");
201         cli_hexdump(y, 8);
202 */
203         #undef K
204         #undef X
205         #undef Y
206         return (((uint64_t)yl)<<32 | yr);       
207 }
208
209 /*****************************************************************************/
210
211 static
212 uint64_t camellia_fl_inv(uint64_t y, uint64_t k){
213 //volatile      uint32_t xl, xr;
214         uint32_t ly[2], lk[2], x[2];
215         ly[0]=(uint32_t)y;
216         ly[1]=(uint32_t)(y>>32);
217         lk[0]=(uint32_t)k; 
218         lk[1]=(uint32_t)(k>>32); 
219         #define Y ((uint32_t*)ly) 
220         #define X ((uint32_t*)x) 
221         #define K ((uint32_t*)lk) 
222         
223         X[1]=(Y[0] | K[0]) ^ Y[1];
224         X[0]=rol32((X[1] & K[1]),1) ^ Y[0];
225         
226 /*      
227         cli_putstr("\r\nFL_inv(");
228         cli_hexdump(&(y), 8);
229         cli_putstr(", ");
230         cli_hexdump(&(k), 8);
231         cli_putstr(") = ");
232 */      
233         #undef K
234         #undef X
235         #undef Y
236         return ((uint64_t)(x[1]))<<32 | x[0];   
237 }
238
239 /*****************************************************************************/
240
241 static
242 const uint64_t camellia_sigma_table[6] PROGMEM = {
243         0xA09E667F3BCC908BLL,
244         0xB67AE8584CAA73B2LL,
245         0xC6EF372FE94F82BELL,
246         0x54FF53A5F1D36F1CLL,
247         0x10E527FADE682D1DLL,
248         0xB05688C2B3E6C1FDLL
249 };      
250
251 /*****************************************************************************/
252 #if 0
253 void camellia128_ctx_dump(camellia128_ctx_t *s){
254         cli_putstr("\r\n==State Dump==");
255         cli_putstr("\n\rKAl: "); cli_hexdump(&(s->kal), 8);
256         cli_putstr("\n\rKAr: "); cli_hexdump(&(s->kar), 8);
257         cli_putstr("\n\rKLl: "); cli_hexdump(&(s->kll), 8);
258         cli_putstr("\n\rKLr: "); cli_hexdump(&(s->klr), 8);     
259         return;
260 }
261 #endif
262 /*****************************************************************************/
263 static
264 uint64_t camellia_sigma(uint8_t idx){
265         union{
266                 uint32_t v32[2];
267                 uint64_t v64;
268         } r;
269         r.v32[0] = pgm_read_dword((uint8_t*)camellia_sigma_table + idx * 8);
270         r.v32[1] = pgm_read_dword((uint8_t*)camellia_sigma_table + idx * 8 + 4);
271         return r.v64;
272 }
273 /*****************************************************************************/
274
275 void camellia128_init(const void *key, camellia128_ctx_t *s){
276         uint8_t i;
277         s->kll = 0; //((uint64_t*)key)[0];
278         
279         /* load the key, endian-adjusted, to kll,klr */
280         for(i=0; i<8; ++i){
281                 s->kll <<= 8;
282                 s->kll |= *((uint8_t*)key);
283                 key = (uint8_t*)key+1;
284         }
285         for(i=0; i<8; ++i){
286                 s->klr <<= 8;
287                 s->klr |= *((uint8_t*)key);
288                 key = (uint8_t*)key+1;
289         }
290         
291         s->kal = s->kll;
292         s->kar = s->klr;
293         
294         s->kar ^= camellia_f(s->kal, camellia_sigma(0));
295         s->kal ^= camellia_f(s->kar, camellia_sigma(1));
296         
297         s->kal ^= s->kll;
298         s->kar ^= s->klr;
299         
300         s->kar ^= camellia_f(s->kal, camellia_sigma(2));
301         s->kal ^= camellia_f(s->kar, camellia_sigma(3));
302         /**/
303 //      cli_putstr("\n\r----------------init finished--------------------");
304 }
305
306 /*****************************************************************************/
307
308 static
309 void camellia128_keyop(camellia128_ctx_t *s, int8_t q){
310         /* first we do 16 bit left-rols for kl and ka (128bit each) */
311         uint32_t temp;
312         
313         temp = (s->kal)>>(64-16-q);
314         s->kal = s->kal<<(16+q) | s->kar>>(64-16-q);
315         s->kar = s->kar<<(16+q) | temp;
316         
317         temp = (s->kll)>>(64-16-q);
318         s->kll = s->kll<<(16+q) | s->klr>>(64-16-q);
319         s->klr = s->klr<<(16+q) | temp;
320         /* after doing the 16-bit rol we have to rol 1 bit left or rigth depending on q */
321 }
322
323 /*****************************************************************************/
324
325 static
326 void camellia128_keyop_inv(camellia128_ctx_t *s, int8_t q){
327         /* first we do 16 bit right-rols for kl and ka (128bit each) */
328         uint32_t temp;
329         
330         temp = (s->kar)&(0xffffff>>(24-16-q));
331         s->kar = s->kar>>(16+q) | s->kal<<(64-16-q);
332         s->kal = s->kal>>(16+q) | ((uint64_t)temp)<<(64-16-q);
333         
334         temp = (s->klr)&(0xffffff>>(24-16-q));
335         s->klr = s->klr>>(16+q) | s->kll<<(64-16-q);
336         s->kll = s->kll>>(16+q) | ((uint64_t)temp)<<(64-16-q);
337         /* after doing the 16-bit rol we have to rol 1 bit left or rigth depending on q */
338 }
339
340 /*****************************************************************************/
341
342 #define SEL_KA 1
343 #define SEL_KL 0
344
345 #define KEY_POSTC1              0x00
346 #define KEY_POSTC2              0x01
347 #define KEY_INC2                0x02
348
349 #define KEY_DIR                 0x04
350 #define KEY_DIR_NORM            0x00
351 #define KEY_DIR_INV             0x04
352
353 #define KEY_AMMOUNT             0x08 
354 #define KEY_ROL17               0x08
355 #define KEY_ROL15               0x00
356
357 static
358 void camellia_6rounds(const camellia128_ctx_t *s, uint64_t *bl, uint64_t *br, uint8_t roundop, uint8_t keychoice){
359         uint8_t i;
360         uint64_t *k[4];
361         k[0] = &(((camellia128_ctx_t*)s)->kll);
362         k[1] = &(((camellia128_ctx_t*)s)->klr);
363         k[2] = &(((camellia128_ctx_t*)s)->kal);
364         k[3] = &(((camellia128_ctx_t*)s)->kar);
365         for(i=0; i<3; ++i){ /* each cycle */
366                 br[0] ^= camellia_f(bl[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?1:0)]));
367                 keychoice >>= 1;
368                 
369                 if((i == 1) && (roundop&KEY_INC2)){
370                         ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(((camellia128_ctx_t*)s),(roundop&KEY_AMMOUNT)?1:-1);
371                 }
372                 
373                 bl[0] ^= camellia_f(br[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?0:1)]));
374                 keychoice >>= 1;
375                 
376                 /* check if we should do some keyop */
377                 if((i == (roundop&1)) && (!(roundop&KEY_INC2)) ){
378                         ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(((camellia128_ctx_t*)s),(roundop&KEY_AMMOUNT)?1:-1);
379                         /* isn't it fuckin nice what we can do in C?! */
380                 }
381         }
382 }
383
384 /*****************************************************************************/
385
386 static
387 void change_endian(void *data, uint8_t length){
388         uint8_t i,a;
389         for(i=0; i<length/2; ++i){
390                 a = ((uint8_t*)data)[i];
391                 ((uint8_t*)data)[i] = ((uint8_t*)data)[length-i-1];
392                 ((uint8_t*)data)[length-i-1] = a;
393         }
394 }
395
396 /*****************************************************************************/
397
398 void camellia128_enc(void *block, const camellia128_ctx_t *s){
399
400         #define BL (((uint64_t*)block)[0])
401         #define BR (((uint64_t*)block)[1])
402         /* endian adjustment */
403          /*BL*/
404          /* 1 2 3 4 5 6 7 8
405           *     8 7 6 5 4 3 2 1
406           */
407          
408         uint64_t temp64;
409         
410         change_endian(&BL, 64/8);       
411         change_endian(&BR, 64/8);
412         
413         /* Prewhitening */
414         BL ^= s->kll;
415         BR ^= s->klr;
416         
417         /* the first 6 */
418         camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
419         /* FL injection  */
420    camellia128_keyop((camellia128_ctx_t*)s, -1);
421         BL = camellia_fl(BL, s->kal);
422         BR = camellia_fl_inv(BR, s->kar);
423    camellia128_keyop((camellia128_ctx_t*)s, -1);
424         /* middle 6 */
425         camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
426         /* FL injection  */
427    camellia128_keyop((camellia128_ctx_t*)s, 1);
428         BL = camellia_fl(BL, s->kll);
429         BR = camellia_fl_inv(BR, s->klr);
430    camellia128_keyop((camellia128_ctx_t*)s, 1);
431    /* last 6 */
432         camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
433         /* Postwhitening */
434         BR ^= s->kal;
435         BL ^= s->kar;
436         
437         temp64 = BR;
438         BR = BL;
439         BL = temp64;
440
441         camellia128_keyop((camellia128_ctx_t*)s,1);
442         
443         change_endian(&BL, 64/8);       
444         change_endian(&BR, 64/8);
445                 
446         #undef BL
447         #undef BR       
448 }
449
450 /*****************************************************************************/
451
452 void camellia128_dec(void *block, const camellia128_ctx_t *s){
453
454         #define BL (((uint64_t*)block)[1])
455         #define BR (((uint64_t*)block)[0])
456         /* endian adjustment */
457          /*BL*/
458          /* 1 2 3 4 5 6 7 8
459           * 8 7 6 5 4 3 2 1
460           */
461          
462         uint64_t temp64;
463         change_endian(&BL, 64/8);       
464         change_endian(&BR, 64/8);
465                 
466         camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
467         /* Prewhitening */
468         BR ^= s->kal; /* kw3 */
469         BL ^= s->kar; /* kw4 */
470         /* the first 6 */
471         camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
472         /* FL injection  */
473    camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
474         BR = camellia_fl(BR, s->klr);
475         BL = camellia_fl_inv(BL, s->kll);
476    camellia128_keyop_inv((camellia128_ctx_t*)s, 1);
477         /* middle 6 */  
478         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
479         /* FL injection  */
480    camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
481         BR = camellia_fl(BR, s->kar);
482         BL = camellia_fl_inv(BL, s->kal);
483    camellia128_keyop_inv((camellia128_ctx_t*)s, -1);
484    /* last 6 */
485         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
486         
487         /* Postwhitening */
488         BL ^= s->kll; /* kw1 */ 
489         BR ^= s->klr; /* kw2 */
490         
491         temp64 = BR;
492         BR = BL;
493         BL = temp64;
494         
495         change_endian(&BL, 64/8);       
496         change_endian(&BR, 64/8);
497                 
498 }
499
500
501
502 /*****************************************************************************/
503 /*****************************************************************************/
504
505
506
507 /* EOF */