3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
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/>.
38 void aes_encrypt_round(void* state, void* key);
40 #define INDEX(c,r) ((r)*16*4+(c)*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))
47 static void mixcol_2(uint8_t* s){
50 t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
52 GF256MUL_2(tmp[0]^tmp[1])
56 GF256MUL_2(tmp[1]^tmp[2])
60 GF256MUL_2(tmp[2]^tmp[3])
64 GF256MUL_2(tmp[3]^tmp[0])
70 static void mixcol(uint8_t* a, uint8_t* b, uint8_t* c, uint8_t* d){
77 t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
79 GF256MUL_2(tmp[0]^tmp[1])
83 GF256MUL_2(tmp[1]^tmp[2])
87 GF256MUL_2(tmp[2]^tmp[3])
91 GF256MUL_2(tmp[3]^tmp[0])
97 static void dump_state(void* s){
99 for(col=0; col<4; col++){
100 for(row=0; row<4; row++){
101 cli_putstr_P(PSTR("\r\nrow "));
103 cli_putstr_P(PSTR(", col "));
105 cli_putstr_P(PSTR(": "));
106 cli_hexdump((uint8_t*)s+col*16+row*16*4, 4);
108 cli_hexdump((uint8_t*)s+col*16+row*16*4+ 4, 4);
110 cli_hexdump((uint8_t*)s+col*16+row*16*4+ 8, 4);
112 cli_hexdump((uint8_t*)s+col*16+row*16*4+12, 4);
118 static void compress512(void* v, void* m, uint64_t* c, void* salt){
123 memcpy(s, v, 16*4); / * load v into state * /
124 memcpy(s+16*4, m, 16*12); / * load m into state * /
127 memcpy(s+4*16*i, (uint8_t*)v+16*i, 16);
131 memcpy(s+i*16+j*16*4, m, 16);
132 m = (uint8_t*)m + 16;
140 cli_putstr_P(PSTR("\r\n === ROUND "));
142 cli_putstr_P(PSTR(" ==="));
149 aes_encrypt_round(s+16*l*4+16*j, k);
150 aes_encrypt_round(s+16*l*4+16*j, salt);
151 *((uint64_t*)(k)) += 1;
156 cli_putstr_P(PSTR("\r\nAfter SubWords"));
163 memcpy(t, s+INDEX(0, 1), 16);
164 memcpy(s+INDEX(0, 1), s+INDEX(1, 1), 16);
165 memcpy(s+INDEX(1, 1), s+INDEX(2, 1), 16);
166 memcpy(s+INDEX(2, 1), s+INDEX(3, 1), 16);
167 memcpy(s+INDEX(3, 1), t, 16);
169 memcpy(t, s+INDEX(0, 2), 16);
170 memcpy(s+INDEX(0, 2), s+INDEX(2, 2), 16);
171 memcpy(s+INDEX(2, 2), t, 16);
172 memcpy(t, s+INDEX(1, 2), 16);
173 memcpy(s+INDEX(1, 2), s+INDEX(3, 2), 16);
174 memcpy(s+INDEX(3, 2), t, 16);
176 memcpy(t, s+INDEX(0, 3), 16);
177 memcpy(s+INDEX(0, 3), s+INDEX(3, 3), 16);
178 memcpy(s+INDEX(3, 3), s+INDEX(2, 3), 16);
179 memcpy(s+INDEX(2, 3), s+INDEX(1, 3), 16);
180 memcpy(s+INDEX(1, 3), t, 16);
183 cli_putstr_P(PSTR("\r\nAfter ShiftRows"));
194 mixcol(s+j, s+j+64, s+j+64*2, s+j+64*3);
198 cli_putstr_P(PSTR("\r\nAfter MixColumns"));
207 memxor(v, (uint8_t*)m+4*16*i, 4*16);
210 memxor(v, s+4*16*i, 4*16);
213 m = (uint8_t*)m - ECHO_SMALL_BLOCKSIZE_B;
215 memxor(v, (uint8_t*)m+4*16*i, 4*16);
220 memxor((uint8_t*)v+16*i, s+4*16*i+16*j, 16);
226 void echo_small_nextBlock(echo_small_ctx_t* ctx, void* block){
227 ctx->counter += ECHO_SMALL_BLOCKSIZE;
228 compress512(ctx->v, block, &(ctx->counter), ctx->salt);
231 void echo_small_lastBlock(echo_small_ctx_t* ctx, void* block, uint16_t length_b){
232 while(length_b>=ECHO_SMALL_BLOCKSIZE){
233 echo_small_nextBlock(ctx, block);
234 block = (uint8_t*)block + ECHO_SMALL_BLOCKSIZE_B;
235 length_b -= ECHO_SMALL_BLOCKSIZE;
237 uint8_t buffer[ECHO_SMALL_BLOCKSIZE_B];
239 memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
240 memcpy(buffer, block, (length_b+7)/8);
241 buffer[length_b/8] |= 0x80 >> (length_b&7);
242 total_len = (ctx->counter += length_b);
243 if(length_b>=ECHO_SMALL_BLOCKSIZE-144){
244 compress512(ctx->v, buffer, &total_len, ctx->salt);
245 memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
251 memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-18, &(ctx->id), 2);
252 memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-16, &total_len, 8);
253 compress512(ctx->v, buffer, &(ctx->counter), ctx->salt);
256 /******************************************************************************/
258 void echo_small_ctx2hash(void* dest, uint16_t length_b, echo_small_ctx_t* ctx){
259 memcpy(dest, ctx->v, (length_b+7)/8);
262 void echo224_ctx2hash(void* dest, echo_small_ctx_t* ctx){
263 memcpy(dest, ctx->v, 224/8);
266 void echo256_ctx2hash(void* dest, echo_small_ctx_t* ctx){
267 memcpy(dest, ctx->v, 256/8);
270 /******************************************************************************/
272 void echo224_init(echo_small_ctx_t* ctx){
273 memset(ctx->v, 0, 4*16);
275 memset(ctx->salt, 0, 16);
277 ctx->v[0+16*0] = 0xE0;
278 ctx->v[0+16*1] = 0xE0;
279 ctx->v[0+16*2] = 0xE0;
280 ctx->v[0+16*3] = 0xE0;
283 void echo256_init(echo_small_ctx_t* ctx){
284 memset(ctx->v, 0, 4*16);
286 memset(ctx->salt, 0, 16);
288 ctx->v[1+16*0] = 0x01;
289 ctx->v[1+16*1] = 0x01;
290 ctx->v[1+16*2] = 0x01;
291 ctx->v[1+16*3] = 0x01;
294 /******************************************************************************/