10 #include <avr/pgmspace.h>
14 #include <util/delay.h>
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);
25 uint64_t PROGMEM camellia_sigma[6]={ / * 64 byte table * /
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
43 /* an ugly macro to load an entry form the table above */
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))) )
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]))) )
53 /*****************************************************************************/
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);
64 /*****************************************************************************/
65 /* extern prog_uint64_t camellia_sigma[6]; */
67 void camellia128_init(camellia128_ctx_t* s, uint8_t* key){
69 s->kll = 0; /* ((uint64_t*)key)[0]; */
71 /* load the key, endian-adjusted, to kll,klr */
84 s->kar ^= camellia_f(s->kal, SIGMA(0));
85 s->kal ^= camellia_f(s->kar, SIGMA(1));
90 s->kar ^= camellia_f(s->kal, SIGMA(2));
91 s->kal ^= camellia_f(s->kar, SIGMA(3));
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 /*****************************************************************************/
103 #define KEY_POSTC1 0x00
104 #define KEY_POSTC2 0x01
105 #define KEY_INC2 0x02
108 #define KEY_DIR_NORM 0x00
109 #define KEY_DIR_INV 0x04
111 #define KEY_AMMOUNT 0x08
112 #define KEY_ROL17 0x08
113 #define KEY_ROL15 0x00
115 void camellia_6rounds(camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice);
116 /*****************************************************************************/
119 void camellia128_enc(camellia128_ctx_t* s, void* block){
121 #define BL (((uint64_t*)block)[0])
122 #define BR (((uint64_t*)block)[1])
123 /* endian adjustment */
131 change_endian(&BL, 64/8);
132 change_endian(&BR, 64/8);
139 camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
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);
146 camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
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);
153 camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
162 camellia128_keyop(s,1);
164 change_endian(&BL, 64/8);
165 change_endian(&BR, 64/8);
171 /*****************************************************************************/
173 void camellia128_dec(camellia128_ctx_t* s, void* block){
175 #define BL (((uint64_t*)block)[1])
176 #define BR (((uint64_t*)block)[0])
177 /* endian adjustment */
185 change_endian(&BL, 64/8);
186 change_endian(&BR, 64/8);
188 camellia128_keyop_inv(s, 1);
190 BR ^= s->kal; /* kw3 */
191 BL ^= s->kar; /* kw4 */
193 camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
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);
200 camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
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);
207 camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
210 BL ^= s->kll; /* kw1 */
211 BR ^= s->klr; /* kw2 */
217 change_endian(&BL, 64/8);
218 change_endian(&BR, 64/8);
222 /*****************************************************************************/
223 /*****************************************************************************/