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 /* 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) )) )
40 /*****************************************************************************/
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);
51 /*****************************************************************************/
52 /* extern prog_uint64_t camellia_sigma[6]; */
54 void camellia128_init(camellia128_ctx_t* s, uint8_t* key){
56 s->kll = 0; /* ((uint64_t*)key)[0]; */
58 /* load the key, endian-adjusted, to kll,klr */
71 s->kar ^= camellia_f(s->kal, SIGMA(0));
72 s->kal ^= camellia_f(s->kar, SIGMA(1));
77 s->kar ^= camellia_f(s->kal, SIGMA(2));
78 s->kal ^= camellia_f(s->kar, SIGMA(3));
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 /*****************************************************************************/
90 #define KEY_POSTC1 0x00
91 #define KEY_POSTC2 0x01
95 #define KEY_DIR_NORM 0x00
96 #define KEY_DIR_INV 0x04
98 #define KEY_AMMOUNT 0x08
99 #define KEY_ROL17 0x08
100 #define KEY_ROL15 0x00
102 void camellia_6rounds(camellia128_ctx_t* s, uint64_t* bl, uint64_t* br, uint8_t roundop, uint8_t keychoice);
103 /*****************************************************************************/
106 void camellia128_enc(camellia128_ctx_t* s, void* block){
108 #define BL (((uint64_t*)block)[0])
109 #define BR (((uint64_t*)block)[1])
110 /* endian adjustment */
118 change_endian(&BL, 64/8);
119 change_endian(&BR, 64/8);
126 camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_POSTC1 , 0x33);
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);
133 camellia_6rounds(s, &BL, &BR, KEY_ROL15 | KEY_DIR_NORM | KEY_INC2 , 0x34);
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);
140 camellia_6rounds(s, &BL, &BR, KEY_ROL17 | KEY_DIR_NORM | KEY_POSTC2 , 0x0C);
149 camellia128_keyop(s,1);
151 change_endian(&BL, 64/8);
152 change_endian(&BR, 64/8);
158 /*****************************************************************************/
160 void camellia128_dec(camellia128_ctx_t* s, void* block){
162 #define BL (((uint64_t*)block)[1])
163 #define BR (((uint64_t*)block)[0])
164 /* endian adjustment */
172 change_endian(&BL, 64/8);
173 change_endian(&BR, 64/8);
175 camellia128_keyop_inv(s, 1);
177 BR ^= s->kal; /* kw3 */
178 BL ^= s->kar; /* kw4 */
180 camellia_6rounds(s, &BR, &BL, KEY_ROL17 | KEY_DIR_INV | KEY_POSTC1 , 0x0C);
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);
187 camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_INC2 , 0x0B);
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);
194 camellia_6rounds(s, &BR, &BL, KEY_ROL15 | KEY_DIR_INV | KEY_POSTC2 , 0x33);
197 BL ^= s->kll; /* kw1 */
198 BR ^= s->klr; /* kw2 */
204 change_endian(&BL, 64/8);
205 change_endian(&BR, 64/8);
209 /*****************************************************************************/
210 /*****************************************************************************/