]> git.cryptolib.org Git - avr-crypto-lib.git/blob - camellia.c
+fix camellia-encrytion bug (state was modifyed by encryption routine)
[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         
150         change_endian(&BL, 64/8);       
151         change_endian(&BR, 64/8);
152                 
153         #undef BL
154         #undef BR       
155 }
156
157 /*****************************************************************************/
158
159 void camellia128_dec(camellia128_ctx_t* s, void* block){
160
161         #define BL (((uint64_t*)block)[1])
162         #define BR (((uint64_t*)block)[0])
163         /* endian adjustment */
164          /*BL*/
165          /*     1 2 3 4 5 6 7 8
166           *             8 7 6 5 4 3 2 1
167           */
168          
169         uint64_t temp64;
170                 
171         change_endian(&BL, 64/8);       
172         change_endian(&BR, 64/8);
173                 
174         camellia128_keyop_inv(s, 1);
175         /* Prewhitening */
176         BR ^= s->kal; /* kw3 */
177         BL ^= s->kar; /* kw4 */
178         /* the first 6 */
179         camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
180         /* FL injection  */
181    camellia128_keyop_inv(s, 1);
182         BR = camellia_fl(BR, s->klr);
183         BL = camellia_fl_inv(BL, s->kll);
184    camellia128_keyop_inv(s, 1);
185         /* middle 6 */  
186         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
187         /* FL injection  */
188    camellia128_keyop_inv(s, -1);
189         BR = camellia_fl(BR, s->kar);
190         BL = camellia_fl_inv(BL, s->kal);
191    camellia128_keyop_inv(s, -1);
192    /* last 6 */
193         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
194         
195         /* Postwhitening */
196         BL ^= s->kll; /* kw1 */ 
197         BR ^= s->klr; /* kw2 */
198         
199         temp64 = BR;
200         BR = BL;
201         BL = temp64;
202         
203         change_endian(&BL, 64/8);       
204         change_endian(&BR, 64/8);
205                 
206 }
207
208 /*****************************************************************************/
209 /*****************************************************************************/
210
211
212
213 /* EOF */