]> git.cryptolib.org Git - avr-crypto-lib.git/blob - camellia.c
now the real fix, previous was only a RAMusage-enhancemnet
[avr-crypto-lib.git] / camellia.c
1 /**
2  * 
3  * 
4  * 
5  * 
6  */
7  
8 #include <stdint.h>
9 #include <avr/io.h>
10 #include <avr/pgmspace.h>
11 #include "camellia.h"
12 #include "uart.h"
13 #include "debug.h"
14 #include <util/delay.h>
15  
16 /*****************************************************************************/
17 uint64_t camellia_f(uint64_t x, uint64_t k);
18 /*****************************************************************************/
19 uint64_t camellia_fl(uint64_t x, uint64_t k);
20 /*****************************************************************************/
21 uint64_t camellia_fl_inv(uint64_t y, uint64_t k);
22 /*****************************************************************************/
23 void change_endian(void* data, uint8_t length);
24
25 uint64_t PROGMEM camellia_sigma[6]={ /* 64 byte table */
26         0xA09E667F3BCC908BLL,
27         0xB67AE8584CAA73B2LL,
28         0xC6EF372FE94F82BELL,
29         0x54FF53A5F1D36F1CLL,
30         0x10E527FADE682D1DLL,
31         0xB05688C2B3E6C1FDLL
32 };      
33
34 /* an ugly macro to load an entry form the table above */
35 #define SIGMA(p) (( ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+1)))<<32) + \
36                                     ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+0) )) )
37
38
39
40 /*****************************************************************************/
41
42 void camellia128_ctx_dump(camellia128_ctx_t *s){
43         uart_putstr_P(PSTR("\r\n==State Dump=="));
44         uart_putstr_P(PSTR("\n\rKAl: ")); uart_hexdump(&(s->kal), 8);
45         uart_putstr_P(PSTR("\n\rKAr: ")); uart_hexdump(&(s->kar), 8);
46         uart_putstr_P(PSTR("\n\rKLl: ")); uart_hexdump(&(s->kll), 8);
47         uart_putstr_P(PSTR("\n\rKLr: ")); uart_hexdump(&(s->klr), 8);   
48         return;
49 }
50
51 /*****************************************************************************/
52 /* extern prog_uint64_t camellia_sigma[6]; */
53
54 void camellia128_init(camellia128_ctx_t* s, uint8_t* key){
55         uint8_t i;
56         s->kll = 0; /* ((uint64_t*)key)[0]; */
57         
58         /* load the key, endian-adjusted, to kll,klr */
59         for(i=0; i<8; ++i){
60                 s->kll <<= 8;
61                 s->kll |= *key++;
62         }
63         for(i=0; i<8; ++i){
64                 s->klr <<= 8;
65                 s->klr |= *key++;
66         }
67
68         s->kal = s->kll;
69         s->kar = s->klr;
70         
71         s->kar ^= camellia_f(s->kal, SIGMA(0));
72         s->kal ^= camellia_f(s->kar, SIGMA(1));
73         
74         s->kal ^= s->kll;
75         s->kar ^= s->klr;
76         
77         s->kar ^= camellia_f(s->kal, SIGMA(2));
78         s->kal ^= camellia_f(s->kar, SIGMA(3));
79 }
80
81 /*****************************************************************************/
82 void camellia128_keyop(camellia128_ctx_t* s, int8_t q);
83 /*****************************************************************************/
84 void camellia128_keyop_inv(camellia128_ctx_t* s, int8_t q);
85 /*****************************************************************************/
86
87 #define SEL_KA 1
88 #define SEL_KL 0
89
90 #define KEY_POSTC1              0x00
91 #define KEY_POSTC2              0x01
92 #define KEY_INC2                0x02
93
94 #define KEY_DIR                 0x04
95 #define KEY_DIR_NORM    0x00
96 #define KEY_DIR_INV             0x04
97
98 #define KEY_AMMOUNT             0x08 
99 #define KEY_ROL17               0x08
100 #define KEY_ROL15               0x00
101
102 void camellia_6rounds(camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice);
103 /*****************************************************************************/
104
105
106 void camellia128_enc(camellia128_ctx_t* s, void* block){
107
108         #define BL (((uint64_t*)block)[0])
109         #define BR (((uint64_t*)block)[1])
110         /* endian adjustment */
111          /*BL*/
112          /*     1 2 3 4 5 6 7 8
113           *             8 7 6 5 4 3 2 1
114           */
115          
116         uint64_t temp64;
117         
118         change_endian(&BL, 64/8);       
119         change_endian(&BR, 64/8);
120         
121         /* Prewhitening */
122         BL ^= s->kll;
123         BR ^= s->klr;
124         
125         /* the first 6 */
126         camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
127         /* FL injection  */
128    camellia128_keyop(s, -1);
129         BL = camellia_fl(BL, s->kal);
130         BR = camellia_fl_inv(BR, s->kar);
131    camellia128_keyop(s, -1);
132         /* middle 6 */
133         camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
134         /* FL injection  */
135    camellia128_keyop(s, 1);
136         BL = camellia_fl(BL, s->kll);
137         BR = camellia_fl_inv(BR, s->klr);
138    camellia128_keyop(s, 1);
139    /* last 6 */
140         camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
141         /* Postwhitening */
142         BR ^= s->kal;
143         BL ^= s->kar;
144         
145         temp64 = BR;
146         BR = BL;
147         BL = temp64;
148
149         camellia128_keyop(s,1);
150         
151         change_endian(&BL, 64/8);       
152         change_endian(&BR, 64/8);
153                 
154         #undef BL
155         #undef BR       
156 }
157
158 /*****************************************************************************/
159
160 void camellia128_dec(camellia128_ctx_t* s, void* block){
161
162         #define BL (((uint64_t*)block)[1])
163         #define BR (((uint64_t*)block)[0])
164         /* endian adjustment */
165          /*BL*/
166          /*     1 2 3 4 5 6 7 8
167           *             8 7 6 5 4 3 2 1
168           */
169          
170         uint64_t temp64;
171                 
172         change_endian(&BL, 64/8);       
173         change_endian(&BR, 64/8);
174                 
175         camellia128_keyop_inv(s, 1);
176         /* Prewhitening */
177         BR ^= s->kal; /* kw3 */
178         BL ^= s->kar; /* kw4 */
179         /* the first 6 */
180         camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
181         /* FL injection  */
182    camellia128_keyop_inv(s, 1);
183         BR = camellia_fl(BR, s->klr);
184         BL = camellia_fl_inv(BL, s->kll);
185    camellia128_keyop_inv(s, 1);
186         /* middle 6 */  
187         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
188         /* FL injection  */
189    camellia128_keyop_inv(s, -1);
190         BR = camellia_fl(BR, s->kar);
191         BL = camellia_fl_inv(BL, s->kal);
192    camellia128_keyop_inv(s, -1);
193    /* last 6 */
194         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
195         
196         /* Postwhitening */
197         BL ^= s->kll; /* kw1 */ 
198         BR ^= s->klr; /* kw2 */
199         
200         temp64 = BR;
201         BR = BL;
202         BL = temp64;
203         
204         change_endian(&BL, 64/8);       
205         change_endian(&BR, 64/8);
206                 
207 }
208
209 /*****************************************************************************/
210 /*****************************************************************************/
211
212
213
214 /* EOF */