]> git.cryptolib.org Git - avr-crypto-lib.git/blob - skein/skein512_asm.S
bug fixing and support for malloc instead of stack memory (some functions)
[avr-crypto-lib.git] / skein / skein512_asm.S
1 /* skein512_asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
5
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.
10
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.
15
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/>.
18 */
19 /*
20  * \author  Daniel Otte
21  * \email   daniel.otte@rub.de
22  * \date    2009-03-16
23  * \license GPLv3 or later
24  */ 
25
26 #include "avr-asm-macros.S"
27
28 /******************************************************************************/
29 /*
30 void skein512_init(skein512_ctx_t *ctx, uint16_t outsize_b){
31         skein_config_t conf;
32         uint8_t null[UBI512_BLOCKSIZE_B];
33         memset(null, 0, UBI512_BLOCKSIZE_B);
34         memset(&conf, 0, sizeof(skein_config_t));
35         conf.schema[0] = 'S';
36         conf.schema[1] = 'H';
37         conf.schema[2] = 'A';
38         conf.schema[3] = '3';
39         conf.version = 1;
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);
45 }
46 */
47 /*
48  * param ctx:       r24:r25
49  * param outsize_b: r22:r23
50  */
51 UBICTX0 = 2
52 UBICTX1 = 3
53 CONF0   = 4
54 CONF1   = 5
55 .global skein512_init
56 skein512_init:
57         push_range 2, 5
58         stack_alloc_large 32+64-22   ;     |<- 22 ->|
59         adiw r30, 1                  ; | CONF (32)  | 
60         movw CONF0, r30              ;     | null (64)       |   
61         movw r26, r24
62         st X+, r22
63         st X+, r23
64         movw UBICTX0, r26
65         ldi r24, 'S'
66         st Z+, r24
67         ldi r24, 'H'
68         st Z+, r24
69         ldi r24, 'A'
70         st Z+, r24
71         ldi r24, '3'
72         st Z+, r24
73         ldi r24, 1
74         st Z+, r24
75         st Z+, r1
76         st Z+, r1
77         st Z+, r1
78         st Z+, r22
79         st Z+, r23
80         ldi 24, 64
81 1:  st Z+, r1
82         dec r24
83         brne 1b
84         /* call ubi512_init*/
85         sbiw r30, 63
86         sbiw r30,  1
87         movw r24, UBICTX0
88         movw r22, r30
89         ldi r20, 4
90         rcall ubi512_init       
91         /* call ubi512_lastBlock*/
92         movw r24, UBICTX0
93         movw r22, CONF0
94         ldi r21, 1
95         clr r20
96         rcall ubi512_lastBlock
97         /* call ubi512_init*/
98         movw r24, UBICTX0
99         adiw r24, 16
100         movw r22, r24
101         movw r24, UBICTX0
102         ldi r20, 48
103         rcall ubi512_init
104         stack_free_large 32+64-22
105         pop_range 2, 5
106         ret
107         
108 /******************************************************************************/
109 .global skein512_nextBlock
110 skein512_nextBlock:
111         adiw r24, 2
112         rjmp ubi512_nextBlock
113
114 /******************************************************************************/
115 .global skein512_lastBlock
116 skein512_lastBlock:
117         adiw r24, 2
118         rjmp ubi512_lastBlock
119
120 /******************************************************************************/
121 /*
122 void skein512_ctx2hash(void *dest, skein512_ctx_t *ctx){
123         ubi512_ctx_t uctx;
124         uint16_t outsize_b;
125         
126         uint64_t counter=0;
127         uint8_t outbuffer[UBI512_BLOCKSIZE_B];
128         ubi512_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
129         
130         outsize_b = ctx->outsize_b;
131         while(1){
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);
137                         break;
138                 }else{
139                         memcpy(dest, outbuffer, UBI512_BLOCKSIZE_B);
140                         dest = (uint8_t*)dest + UBI512_BLOCKSIZE_B;
141                         outsize_b -= UBI512_BLOCKSIZE;
142                         counter++;
143                 }
144         }
145 }
146 */
147 /*
148  * param dest: r24:r25
149  * param ctx:  r22:r23
150  */
151  OUTSIZE_B0 = 16
152  OUTSIZE_B1 = 17
153  UCTX0      = 14
154  UCTX1      = 15
155  UBICTX0    = 12
156  UBICTX1    = 13
157  DEST0      = 10
158  DEST1      = 11
159 .global skein512_ctx2hash
160 skein512_ctx2hash:
161         push_range 10, 17
162                                    /*  80  ||  8      ||  64       */
163         stack_alloc_large 80+8+64  /* uctx || counter || outbuffer */
164         movw DEST0, r24
165         adiw r30, 1
166         movw UCTX0, r30
167         adiw r30, 63
168         adiw r30, 17
169         st Z+, r1
170         st Z+, r1
171         st Z+, r1
172         st Z+, r1
173         st Z+, r1
174         st Z+, r1
175         st Z+, r1
176         st Z+, r1
177         movw r26, 22
178         ld OUTSIZE_B0, X+
179         ld OUTSIZE_B1, X+
180         movw UBICTX0, r26
181    /* call ubi512_init */
182         movw r24, UBICTX0
183         adiw r24, 16
184         movw r22, r24
185         movw r24, UBICTX0
186         ldi r20, 63
187         rcall ubi512_init
188         
189    /* main loop */
190    /* copy ubictx in uctx*/
191 1:      movw r30, UCTX0
192         movw r26, UBICTX0
193         ldi r24, 80
194 2:      ld r25, X+
195         st Z+, r25
196         dec r24
197         brne 2b
198   /* call ubi512_lastBlock */
199     movw r24, UCTX0
200         adiw r24, 63
201         adiw r24, 17
202         movw r22, r24
203         movw r24, UCTX0
204         clr r21
205         ldi r20, 64
206         rcall ubi512_lastBlock
207   /* copy uctx->g to outbuffer */       
208         movw r26, UCTX0
209         adiw r26, 16
210         movw r30, UCTX0
211         adiw r30, 63
212         adiw r30, 17+8
213         ldi r24, 64
214 2:      ld r25, X+
215     st Z+, r25
216         dec r24
217         brne 2b
218    /* compare outsize_b with 512*/       
219         cpi OUTSIZE_B1, 3
220         brge 5f
221         cpi OUTSIZE_B1, 2
222         brlo 3f
223         tst OUTSIZE_B0
224         breq 3f 
225 5:      /* copy outbuffer to dest */
226         movw r30, DEST0
227         movw r26, UCTX0
228         adiw r26, 63
229         adiw r26, 17+8
230         ldi r24, 64
231 6:      ld r25, X+
232         st Z+, r25
233         dec r24
234         brne 6b
235         /* store new dest */
236         movw DEST0, r30
237         /* adjust counter and outsize_b*/
238         subi OUTSIZE_B1, 2
239         movw r30, UCTX0
240         adiw r30, 63
241         adiw r30, 17
242         ldi r24, 1
243         ld r25, Z
244         add r25, r24
245         st Z+, r25
246         ldi r24, 7
247 6:      ld r25, Z
248         adc r25, r1
249         st Z+, r25
250         dec r24
251         brne 6b
252         rjmp 1b
253 3:      /* last iteraton */
254         movw r24, OUTSIZE_B0
255         adiw r24, 7
256         lsr r25
257         ror r24
258         lsr r25
259         ror r24
260         lsr r24
261         movw r30, DEST0
262         movw r26, UCTX0
263         adiw r26, 63
264         adiw r26, 17+8
265         tst r24
266         breq 8f
267 7:      ld r25, X+
268         st Z+, r25
269         dec r24
270         brne 7b
271 8:      
272         stack_free_large2 80+8+64
273         pop_range 10, 17
274         ret
275
276 /******************************************************************************/
277 /*
278 void skein512(void *dest, uint16_t outlength_b,const void *msg, uint32_t length_b){
279         skein512_ctx_t ctx;
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;
285         }
286         skein512_lastBlock(&ctx, msg, length_b);
287         skein512_ctx2hash(dest, &ctx);
288 }
289 */
290 /*
291  * param dest:         r24:r25
292  * param outlength_b:  r22:r23
293  * param msg:          r20:r21
294  * param length_b:     r16:r19
295  */
296 LENGTH_B0 =  2
297 LENGTH_B1 =  3
298 LENGTH_B2 =  4
299 LENGTH_B3 =  5
300 DEST0     =  6
301 DEST1     =  7
302 MSG0      =  8
303 MSG1      =  9
304 CTX0      = 10
305 CTX1      = 11
306 .global skein512
307 skein512:
308         push_range 2, 11
309         stack_alloc_large 82
310         adiw r30, 1
311         movw CTX0, r30
312         movw DEST0, r24
313         movw MSG0, r20
314         movw LENGTH_B0, r16
315         movw LENGTH_B2, r18
316         /* call skein512_init */
317         movw r24, r30
318         rcall skein512_init
319 1:      tst LENGTH_B2
320         brne 4f
321         tst LENGTH_B3
322         brne 4f
323    /* call skein512_lastBlock */
324         movw r24, CTX0
325         movw r22, MSG0
326         movw r20, LENGTH_B0
327         rcall skein512_lastBlock
328    /* call skein512_ctx2hash */
329         movw r24, DEST0
330         movw r22, CTX0
331         rcall skein512_ctx2hash
332    /* return */ 
333         stack_free_large 82
334         pop_range 2, 11
335         ret
336                 
337 4: /* process preceeding blocks */      
338         movw r24, CTX0
339         movw r22, MSG0
340         rcall skein512_nextBlock
341         ldi r24, 64
342         add MSG0, r24
343         adc MSG0, r1
344         mov r24, LENGTH_B1
345         mov r25, LENGTH_B2
346         sbiw r24, 2
347         sbc LENGTH_B3, r1
348         mov LENGTH_B1, r24
349         mov LENGTH_B2, r25
350         rjmp 1b
351