3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2009 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/>.
21 * \email daniel.otte@rub.de
23 * \license GPLv3 or later
26 #include "avr-asm-macros.S"
28 /******************************************************************************/
30 void skein512_init(skein512_ctx_t* ctx, uint16_t outsize_b){
32 uint8_t null[UBI512_BLOCKSIZE_B];
33 memset(null, 0, UBI512_BLOCKSIZE_B);
34 memset(&conf, 0, sizeof(skein_config_t));
40 conf.out_length = outsize_b;
41 ctx->outsize_b = outsize_b;
42 ubi512_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
43 ubi512_lastBlock(&(ctx->ubictx), &conf, 256);
44 ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
49 * param outsize_b: r22:r23
58 stack_alloc_large 32+64-22 ; |<- 22 ->|
59 adiw r30, 1 ; | CONF (32) |
60 movw CONF0, r30 ; | null (64) |
91 /* call ubi512_lastBlock*/
96 rcall ubi512_lastBlock
104 stack_free_large 32+64-22
108 /******************************************************************************/
109 .global skein512_nextBlock
112 rjmp ubi512_nextBlock
114 /******************************************************************************/
115 .global skein512_lastBlock
118 rjmp ubi512_lastBlock
120 /******************************************************************************/
122 void skein512_ctx2hash(void* dest, skein512_ctx_t* ctx){
127 uint8_t outbuffer[UBI512_BLOCKSIZE_B];
128 ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
130 outsize_b = ctx->outsize_b;
132 memcpy(&uctx, &(ctx->ubictx), sizeof(ubi512_ctx_t));
133 ubi512_lastBlock(&uctx, &counter, 64);
134 ubi512_ctx2hash(outbuffer, &uctx);
135 if(outsize_b<=UBI512_BLOCKSIZE){
136 memcpy(dest, outbuffer, (ctx->outsize_b+7)/8);
139 memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
140 dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
141 outsize_b -= UBI512_BLOCKSIZE;
148 * param dest: r24:r25
159 .global skein512_ctx2hash
163 stack_alloc_large 80+8+64 /* uctx || counter || outbuffer */
181 /* call ubi512_init */
190 /* copy ubictx in uctx*/
198 /* call ubi512_lastBlock */
206 rcall ubi512_lastBlock
207 /* copy uctx->g to outbuffer */
218 /* compare outsize_b with 512*/
225 5: /* copy outbuffer to dest */
237 /* adjust counter and outsize_b*/
253 3: /* last iteraton */
272 stack_free_large2 80+8+64
276 /******************************************************************************/
278 void skein512(void* dest, uint16_t outlength_b,const void* msg, uint32_t length_b){
280 skein512_init(&ctx, outlength_b);
281 while(length_b>SKEIN512_BLOCKSIZE){
282 skein512_nextBlock(&ctx, msg);
283 msg = (uint8_t*)msg + SKEIN512_BLOCKSIZE_B;
284 length_b -= SKEIN512_BLOCKSIZE;
286 skein512_lastBlock(&ctx, msg, length_b);
287 skein512_ctx2hash(dest, &ctx);
291 * param dest: r24:r25
292 * param outlength_b: r22:r23
294 * param length_b: r16:r19
316 /* call skein512_init */
323 /* call skein512_lastBlock */
327 rcall skein512_lastBlock
328 /* call skein512_ctx2hash */
331 rcall skein512_ctx2hash
337 4: /* process preceeding blocks */
340 rcall skein512_nextBlock