]> git.cryptolib.org Git - avr-crypto-lib.git/blob - camellia.c
cfcd561e2811c2a385f5dc928f6125061225fb03
[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 uint32_t PROGMEM camellia_sigma[12]={ /* 64 byte table */
35          0x3BCC908BL, 0xA09E667FL,
36          0x4CAA73B2L, 0xB67AE858L,
37          0xE94F82BEL, 0xC6EF372FL,
38          0xF1D36F1CL, 0x54FF53A5L,
39          0xDE682D1DL, 0x10E527FAL,
40          0xB3E6C1FDL, 0xB05688C2L
41 };
42
43 /* an ugly macro to load an entry form the table above */
44 /*
45 #define SIGMA(p) (( ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+1)))<<32) | \
46                     ((uint64_t)(pgm_read_dword((prog_uint32_t*)camellia_sigma+2*(p)+0))) )
47 */
48 #define SIGMA(p) (( ((uint64_t)(pgm_read_dword(((prog_uint32_t*)camellia_sigma)[2*(p)+1])))<<32) | \
49                     ((uint64_t)(pgm_read_dword(((prog_uint32_t*)camellia_sigma)[2*(p)+0]))) )
50
51
52
53 /*****************************************************************************/
54
55 void camellia128_ctx_dump(camellia128_ctx_t *s){
56         uart_putstr_P(PSTR("\r\n==State Dump=="));
57         uart_putstr_P(PSTR("\n\rKAl: ")); uart_hexdump(&(s->kal), 8);
58         uart_putstr_P(PSTR("\n\rKAr: ")); uart_hexdump(&(s->kar), 8);
59         uart_putstr_P(PSTR("\n\rKLl: ")); uart_hexdump(&(s->kll), 8);
60         uart_putstr_P(PSTR("\n\rKLr: ")); uart_hexdump(&(s->klr), 8);   
61         return;
62 }
63
64 /*****************************************************************************/
65 /* extern prog_uint64_t camellia_sigma[6]; */
66
67 void camellia128_init(camellia128_ctx_t* s, uint8_t* key){
68         uint8_t i;
69         s->kll = 0; /* ((uint64_t*)key)[0]; */
70         
71         /* load the key, endian-adjusted, to kll,klr */
72         for(i=0; i<8; ++i){
73                 s->kll <<= 8;
74                 s->kll |= *key++;
75         }
76         for(i=0; i<8; ++i){
77                 s->klr <<= 8;
78                 s->klr |= *key++;
79         }
80
81         s->kal = s->kll;
82         s->kar = s->klr;
83         
84         s->kar ^= camellia_f(s->kal, SIGMA(0));
85         s->kal ^= camellia_f(s->kar, SIGMA(1));
86         
87         s->kal ^= s->kll;
88         s->kar ^= s->klr;
89         
90         s->kar ^= camellia_f(s->kal, SIGMA(2));
91         s->kal ^= camellia_f(s->kar, SIGMA(3));
92 }
93
94 /*****************************************************************************/
95 void camellia128_keyop(camellia128_ctx_t* s, int8_t q);
96 /*****************************************************************************/
97 void camellia128_keyop_inv(camellia128_ctx_t* s, int8_t q);
98 /*****************************************************************************/
99
100 #define SEL_KA 1
101 #define SEL_KL 0
102
103 #define KEY_POSTC1              0x00
104 #define KEY_POSTC2              0x01
105 #define KEY_INC2                0x02
106
107 #define KEY_DIR                 0x04
108 #define KEY_DIR_NORM    0x00
109 #define KEY_DIR_INV             0x04
110
111 #define KEY_AMMOUNT             0x08 
112 #define KEY_ROL17               0x08
113 #define KEY_ROL15               0x00
114
115 void camellia_6rounds(camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice);
116 /*****************************************************************************/
117
118
119 void camellia128_enc(camellia128_ctx_t* s, void* block){
120
121         #define BL (((uint64_t*)block)[0])
122         #define BR (((uint64_t*)block)[1])
123         /* endian adjustment */
124          /*BL*/
125          /*     1 2 3 4 5 6 7 8
126           *             8 7 6 5 4 3 2 1
127           */
128          
129         uint64_t temp64;
130         
131         change_endian(&BL, 64/8);       
132         change_endian(&BR, 64/8);
133         
134         /* Prewhitening */
135         BL ^= s->kll;
136         BR ^= s->klr;
137         
138         /* the first 6 */
139         camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
140         /* FL injection  */
141    camellia128_keyop(s, -1);
142         BL = camellia_fl(BL, s->kal);
143         BR = camellia_fl_inv(BR, s->kar);
144    camellia128_keyop(s, -1);
145         /* middle 6 */
146         camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
147         /* FL injection  */
148    camellia128_keyop(s, 1);
149         BL = camellia_fl(BL, s->kll);
150         BR = camellia_fl_inv(BR, s->klr);
151    camellia128_keyop(s, 1);
152    /* last 6 */
153         camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
154         /* Postwhitening */
155         BR ^= s->kal;
156         BL ^= s->kar;
157         
158         temp64 = BR;
159         BR = BL;
160         BL = temp64;
161
162         camellia128_keyop(s,1);
163         
164         change_endian(&BL, 64/8);       
165         change_endian(&BR, 64/8);
166                 
167         #undef BL
168         #undef BR       
169 }
170
171 /*****************************************************************************/
172
173 void camellia128_dec(camellia128_ctx_t* s, void* block){
174
175         #define BL (((uint64_t*)block)[1])
176         #define BR (((uint64_t*)block)[0])
177         /* endian adjustment */
178          /*BL*/
179          /*     1 2 3 4 5 6 7 8
180           *             8 7 6 5 4 3 2 1
181           */
182          
183         uint64_t temp64;
184                 
185         change_endian(&BL, 64/8);       
186         change_endian(&BR, 64/8);
187                 
188         camellia128_keyop_inv(s, 1);
189         /* Prewhitening */
190         BR ^= s->kal; /* kw3 */
191         BL ^= s->kar; /* kw4 */
192         /* the first 6 */
193         camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
194         /* FL injection  */
195    camellia128_keyop_inv(s, 1);
196         BR = camellia_fl(BR, s->klr);
197         BL = camellia_fl_inv(BL, s->kll);
198    camellia128_keyop_inv(s, 1);
199         /* middle 6 */  
200         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
201         /* FL injection  */
202    camellia128_keyop_inv(s, -1);
203         BR = camellia_fl(BR, s->kar);
204         BL = camellia_fl_inv(BL, s->kal);
205    camellia128_keyop_inv(s, -1);
206    /* last 6 */
207         camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
208         
209         /* Postwhitening */
210         BL ^= s->kll; /* kw1 */ 
211         BR ^= s->klr; /* kw2 */
212         
213         temp64 = BR;
214         BR = BL;
215         BL = temp64;
216         
217         change_endian(&BL, 64/8);       
218         change_endian(&BR, 64/8);
219                 
220 }
221
222 /*****************************************************************************/
223 /*****************************************************************************/
224
225
226
227 /* EOF */