3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "aes_enc_round.h"
40 #define INDEX(c,r) ((c)*16*4+(r)*16)
42 #define GF256MUL_1(a) (a)
43 #define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
44 #define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
46 static void mixcol(uint8_t *s){
53 t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
55 GF256MUL_2(tmp[0]^tmp[1])
59 GF256MUL_2(tmp[1]^tmp[2])
63 GF256MUL_2(tmp[2]^tmp[3])
67 GF256MUL_2(tmp[3]^tmp[0])
73 static void dump_state(void *s){
75 for(col=0; col<4; col++){
76 for(row=0; row<4; row++){
77 cli_putstr_P(PSTR("\r\nrow "));
79 cli_putstr_P(PSTR(", col "));
81 cli_putstr_P(PSTR(": "));
82 cli_hexdump((uint8_t*)s+col*16*4+row*16, 4);
84 cli_hexdump((uint8_t*)s+col*16*4+row*16+ 4, 4);
86 cli_hexdump((uint8_t*)s+col*16*4+row*16+ 8, 4);
88 cli_hexdump((uint8_t*)s+col*16*4+row*16+12, 4);
94 static void echo_compress(uint8_t *s, uint8_t iterations, uint64_t *c, void *salt){
104 memset(k.v8+8, 0, 8);
108 cli_putstr_P(PSTR("\r\n === ROUND "));
110 cli_putstr_P(PSTR(" ==="));
111 if(round<DEBUG_DEPTH){
116 aes_enc_round((aes_cipher_state_t*)(s+16*i), (aes_roundkey_t*)k.v8);
117 aes_enc_round((aes_cipher_state_t*)(s+16*i), (aes_roundkey_t*)salt);
121 if(round<DEBUG_DEPTH){
122 cli_putstr_P(PSTR("\r\nAfter SubWords"));
129 memcpy(t, s+INDEX(0, 1), 16);
130 memcpy(s+INDEX(0, 1), s+INDEX(1, 1), 16);
131 memcpy(s+INDEX(1, 1), s+INDEX(2, 1), 16);
132 memcpy(s+INDEX(2, 1), s+INDEX(3, 1), 16);
133 memcpy(s+INDEX(3, 1), t, 16);
135 memcpy(t, s+INDEX(0, 2), 16);
136 memcpy(s+INDEX(0, 2), s+INDEX(2, 2), 16);
137 memcpy(s+INDEX(2, 2), t, 16);
138 memcpy(t, s+INDEX(1, 2), 16);
139 memcpy(s+INDEX(1, 2), s+INDEX(3, 2), 16);
140 memcpy(s+INDEX(3, 2), t, 16);
142 memcpy(t, s+INDEX(0, 3), 16);
143 memcpy(s+INDEX(0, 3), s+INDEX(3, 3), 16);
144 memcpy(s+INDEX(3, 3), s+INDEX(2, 3), 16);
145 memcpy(s+INDEX(2, 3), s+INDEX(1, 3), 16);
146 memcpy(s+INDEX(1, 3), t, 16);
148 if(round<DEBUG_DEPTH){
149 cli_putstr_P(PSTR("\r\nAfter ShiftRows"));
160 if(round<DEBUG_DEPTH){
161 cli_putstr_P(PSTR("\r\nAfter MixColumns"));
166 }while(--iterations);
170 /******************************************************************************/
172 static void compress512(void *v, void *m, uint64_t *c, void *salt){
175 memcpy(s, v, 16*4); /* load v into state */
176 memcpy(s+16*4, m, 16*12); /* load m into state */
178 echo_compress(s, 8, c, salt);
182 memxor(v, (uint8_t*)m+4*16*i, 4*16);
185 memxor(v, s+4*16*i, 4*16);
189 static void compress1024(void *v, void *m, uint64_t *c, void *salt){
191 memcpy(s, v, 16*8); /* load v into state */
192 memcpy(s+16*8, m, 16*8); /* load m into state */
194 echo_compress(s, 10, c, salt);
199 memxor(v, s+16*8, 16*8);
202 /******************************************************************************/
204 void echo_small_nextBlock(echo_small_ctx_t *ctx, void *block){
205 ctx->counter += ECHO_SMALL_BLOCKSIZE;
206 compress512(ctx->v, block, &(ctx->counter), ctx->salt);
209 void echo_small_lastBlock(echo_small_ctx_t *ctx, void *block, uint16_t length_b){
210 while(length_b>=ECHO_SMALL_BLOCKSIZE){
211 echo_small_nextBlock(ctx, block);
212 block = (uint8_t*)block + ECHO_SMALL_BLOCKSIZE_B;
213 length_b -= ECHO_SMALL_BLOCKSIZE;
215 uint8_t buffer[ECHO_SMALL_BLOCKSIZE_B];
217 memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
218 memcpy(buffer, block, (length_b+7)/8);
219 buffer[length_b/8] |= 0x80 >> (length_b&7);
220 total_len = (ctx->counter += length_b);
221 if(length_b>=ECHO_SMALL_BLOCKSIZE-144){
222 compress512(ctx->v, buffer, &total_len, ctx->salt);
223 memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
229 memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-18, &(ctx->id), 2);
230 memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-16, &total_len, 8);
231 compress512(ctx->v, buffer, &(ctx->counter), ctx->salt);
234 /******************************************************************************/
236 void echo_large_nextBlock(echo_large_ctx_t *ctx, void *block){
237 ctx->counter += ECHO_LARGE_BLOCKSIZE;
238 compress1024(ctx->v, block, &(ctx->counter), ctx->salt);
241 void echo_large_lastBlock(echo_large_ctx_t *ctx, void *block, uint16_t length_b){
242 while(length_b>=ECHO_LARGE_BLOCKSIZE){
243 echo_large_nextBlock(ctx, block);
244 block = (uint8_t*)block + ECHO_LARGE_BLOCKSIZE_B;
245 length_b -= ECHO_LARGE_BLOCKSIZE;
247 uint8_t buffer[ECHO_LARGE_BLOCKSIZE_B];
249 memset(buffer, 0, ECHO_LARGE_BLOCKSIZE_B);
250 memcpy(buffer, block, (length_b+7)/8);
251 buffer[length_b/8] |= 0x80 >> (length_b&7);
252 total_len = (ctx->counter += length_b);
253 if(length_b>=ECHO_LARGE_BLOCKSIZE-144){
254 compress1024(ctx->v, buffer, &total_len, ctx->salt);
255 memset(buffer, 0, ECHO_LARGE_BLOCKSIZE_B);
261 memcpy(buffer+ECHO_LARGE_BLOCKSIZE_B-18, &(ctx->id), 2);
262 memcpy(buffer+ECHO_LARGE_BLOCKSIZE_B-16, &total_len, 8);
263 compress1024(ctx->v, buffer, &(ctx->counter), ctx->salt);
265 /******************************************************************************/
267 void echo_ctx2hash(void *dest, uint16_t length_b, echo_small_ctx_t *ctx){
268 memcpy(dest, ctx->v, (length_b+7)/8);
271 void echo224_ctx2hash(void *dest, echo_small_ctx_t *ctx){
272 memcpy(dest, ctx->v, 224/8);
275 void echo256_ctx2hash(void *dest, echo_small_ctx_t *ctx){
276 memcpy(dest, ctx->v, 256/8);
279 /******************************************************************************/
281 void echo384_ctx2hash(void *dest, echo_large_ctx_t *ctx){
282 memcpy(dest, ctx->v, 384/8);
285 void echo512_ctx2hash(void *dest, echo_large_ctx_t *ctx){
286 memcpy(dest, ctx->v, 512/8);
289 /******************************************************************************/
291 void echo224_init(echo_small_ctx_t *ctx){
292 memset(ctx->v, 0, 4*16);
294 memset(ctx->salt, 0, 16);
296 ctx->v[0+16*0] = 0xE0;
297 ctx->v[0+16*1] = 0xE0;
298 ctx->v[0+16*2] = 0xE0;
299 ctx->v[0+16*3] = 0xE0;
302 void echo256_init(echo_small_ctx_t *ctx){
303 memset(ctx->v, 0, 4*16);
305 memset(ctx->salt, 0, 16);
307 ctx->v[1+16*0] = 0x01;
308 ctx->v[1+16*1] = 0x01;
309 ctx->v[1+16*2] = 0x01;
310 ctx->v[1+16*3] = 0x01;
313 /******************************************************************************/
315 void echo384_init(echo_large_ctx_t *ctx){
317 memset(ctx->v, 0, 8*16);
319 memset(ctx->salt, 0, 16);
322 ctx->v[0+16*i] = 0x80;
323 ctx->v[1+16*i] = 0x01;
327 void echo512_init(echo_large_ctx_t *ctx){
329 memset(ctx->v, 0, 8*16);
331 memset(ctx->salt, 0, 16);
334 ctx->v[1+16*i] = 0x02;
338 /******************************************************************************/