]> git.cryptolib.org Git - avr-crypto-lib.git/blob - skein/ubi512_asm.S
syncing with bzr
[avr-crypto-lib.git] / skein / ubi512_asm.S
1 /* ubi512_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-25
23  * \license GPLv3 or later
24  */ 
25
26 #include "avr-asm-macros.S"
27
28 /******************************************************************************/
29 /*
30 void ubi512_init(ubi512_ctx_t* ctx, const void* g, uint8_t type){
31         memset(ctx->tweak, 0, 15);
32         ctx->tweak[15] = 0x40+type;
33         memcpy(ctx->g, g, UBI512_BLOCKSIZE_B);
34 }
35 */
36 /*
37  * param ctx:  r24:r25
38  * param g:    r22:r23
39  * param type: r20
40  */
41 .global ubi512_init
42 ubi512_init:
43         movw r26, r24
44         ldi r21, 15
45 1:      st X+, r1
46         dec r21
47         brne 1b
48         ori r20, 0x40
49         st X+, r20
50         ldi r21, 64
51         movw r30, r22
52 2:  ld r20, Z+
53         st X+, r20
54         dec r21
55         brne 2b
56         ret     
57
58 /******************************************************************************/
59 /*
60 void ubi512_ctx2hash(void* dest, const ubi512_ctx_t* ctx){
61         memcpy(dest, ctx->g, UBI512_BLOCKSIZE_B);
62 }
63 */
64 /*
65  * param dest: r24:r24
66  * param ctx:  r22:r23
67  */
68 .global ubi512_ctx2hash
69 ubi512_ctx2hash:
70         movw r26, r24
71         movw r30, r22
72         adiw r30, 16
73         ldi r22, 64
74 1:      ld r23, Z+
75         st X+, r23
76         dec r22
77         brne 1b
78         ret
79
80 /******************************************************************************/
81 /*
82 void ubi512_nextBlock(ubi512_ctx_t* ctx, const void* block){
83         threefish512_ctx_t tfctx;
84         ((uint64_t*)(ctx->tweak))[0] += UBI512_BLOCKSIZE_B;
85         threefish512_init(ctx->g, ctx->tweak, &tfctx);
86         memcpy(ctx->g, block, UBI512_BLOCKSIZE_B);
87         threefish512_enc(ctx->g, &tfctx);
88         memxor(ctx->g, block, UBI512_BLOCKSIZE_B);
89         ctx->tweak[15] &= (uint8_t)~0x40;
90 }  
91 */
92 /*
93  * param ctx:   r24:r25
94  * param block: r22:r23
95  */
96 CTX0   = 2
97 CTX1   = 3
98 BLOCK0 = 4
99 BLOCK1 = 5
100 TFCTX0 = 6
101 TFCTX1 = 7 
102 .global ubi512_nextBlock
103 ubi512_nextBlock:
104         stack_alloc_large 12*8
105         push_range 2, 7
106         adiw r30, 1 /* Z points to tfctx */
107         movw TFCTX0, r30
108         movw CTX0, r24
109         movw BLOCK0, r22
110         movw r26, r24
111 /* add BLOCKSIZE_B (64) to tweak */
112         ldi r25, 64
113         ld r24, X
114         add r24, r25
115         st X+, r24
116         ldi r25, 11
117 1:      ld r24, X 
118         adc r24, r1
119         st X+, r24
120         dec r25
121         brne 1b
122 /* call threefish512_init */    
123         movw r24, CTX0
124         adiw r24, 16
125         movw r22, CTX0
126         movw CTX0, r24  /* CTX points to ctx->g */
127         movw r20, TFCTX0
128         rcall threefish512_init
129         /* copy block to ctx->g */      
130         movw r26, CTX0
131         movw r30, BLOCK0
132         ldi r25, 64
133 1:      ld r24, Z+
134         st X+, r24
135         dec r25
136         brne 1b
137 /* call threefish512_enc */     
138         movw r24, CTX0
139         movw r22, TFCTX0
140         rcall threefish512_enc
141 /* xor block into ctx->g */     
142         movw r26, BLOCK0
143         movw r30, CTX0
144         ldi r25, 64
145 1:      ld r24, X+
146         ld r23, Z
147         eor r23, r24
148         st Z+, r23      
149         dec r25
150         brne 1b
151 /* clear 'first' bit in tweak */
152         sbiw r30, 33
153         sbiw r30, 32    
154         ld r24, Z
155         andi r24, ~0x40
156         st Z, r24
157 exit:
158         pop_range 2, 7
159         stack_free_large 12*8
160         ret
161
162 /******************************************************************************/
163 /*
164 void ubi512_lastBlock(ubi512_ctx_t* ctx, const void* block, uint16_t length_b){
165         threefish512_ctx_t tfctx;
166         while(length_b>UBI512_BLOCKSIZE){
167                 ubi512_nextBlock(ctx, block);
168                 block = (uint8_t*)block + UBI512_BLOCKSIZE_B;
169                 length_b -= UBI512_BLOCKSIZE;
170         }
171         ctx->tweak[15] |= 0x80;
172         ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
173         if(length_b & 0x07)
174                 ctx->tweak[14] |= 0x80;
175         threefish512_init(ctx->g, ctx->tweak, &tfctx);
176         memset(ctx->g, 0, UBI512_BLOCKSIZE_B);
177         memcpy(ctx->g, block, (length_b+7)/8);
178         if(length_b & 0x07)
179                 ctx->g[(length_b+7)/8-1] |= 0x80>>(length_b&7);
180         threefish512_enc(ctx->g, &tfctx);
181         memxor(ctx->g, block, (length_b+7)/8);
182         if(length_b & 0x07){
183                 ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
184         }
185
186 */
187 /*
188  * param ctx:     r24:r25
189  * param block:   r22:r23
190  * param ength_b: r20:r21
191  */
192 MASK_B  =  8 
193 LEN_B   =  9
194 TFCTX0  = 10
195 TFCTX1  = 11
196 CTX0    = 12
197 CTX1    = 13
198 BLOCK0  = 14
199 BLOCK1  = 15
200 LENGTH0 = 16
201 LENGTH1 = 17
202 .global ubi512_lastBlock
203 ubi512_lastBlock:
204 /* run nextBlock for preceding blocks*/
205         push_range 8, 17
206         movw CTX0, r24
207         movw BLOCK0, r22
208         movw LENGTH0, r20
209 1:      cpi LENGTH1, 3
210         brlo 2f
211         movw r24, CTX0
212         movw r22, BLOCK0
213         rcall ubi512_nextBlock
214         ldi r25, 64
215         add BLOCK0, r25
216         adc BLOCK1, r1
217         subi LENGTH1, 2
218         rjmp 1b
219 2:      cpi LENGTH1, 2
220         brlo 3f
221         tst LENGTH0
222         breq 3f
223         movw r24, CTX0
224         movw r22, BLOCK0
225         rcall ubi512_nextBlock
226         ldi r25, 64
227         add BLOCK0, r25
228         adc BLOCK1, r1
229         subi LENGTH1, 2
230 3:      /* now the real fun */
231     stack_alloc_large 8*12
232         adiw r30, 1
233         movw TFCTX0, r30
234         /* calculate LEN_B */
235         movw r24, LENGTH0
236         adiw r24, 7
237         lsr r25
238         ror r24
239         lsr r25
240         ror r24
241         lsr r24
242         mov LEN_B, r24
243         /* add length to tweak */
244         movw r30, CTX0
245         ld r24, Z
246         add r24, LEN_B
247         st Z+, r24
248         ldi r25, 11
249 1:      ld r24, Z
250         adc r24, r1
251         st Z+, r24
252         dec r25
253         brne 1b
254         /* set 'final' bit*/
255         movw r30, CTX0
256         ldd r24, Z+15
257         ori r24, 0x80
258         std Z+15, r24
259         /* store in MASk_B if we do bit processing and set 'BitPad' bit*/
260         clr MASK_B
261         mov r24, LENGTH0
262         andi r24, 0x07
263         tst r24
264         breq 4f
265         ldd r25, Z+14
266         ori r25, 0x80
267         std Z+14, r25
268         ldi r25, 0x80
269         mov MASK_B, r25
270 1:      lsr MASK_B
271         dec r24
272         brne 1b
273 4:  /* call threefish512_init*/
274         movw r24, CTX0
275         adiw r24, 16
276         movw r22, CTX0
277         movw CTX0, r24 /* CTX points at ctx->g */
278         movw r20, TFCTX0
279         rcall threefish512_init
280         /* copy block to ctx->g */
281         movw r26, BLOCK0
282         movw r30, CTX0
283         mov r24, LEN_B
284         ldi r25, 64
285         sub r25, LEN_B
286         tst r24
287 1:      breq 2f
288         ld r22, X+
289         st Z+, r22
290         dec r24 
291         rjmp 1b
292 2:      tst MASK_B
293         breq 29f
294         or r22, MASK_B
295         st -Z, r22
296         adiw r30, 1
297 29:     tst r25
298 3:      breq 4f
299         st Z+, r1
300         dec r25
301         rjmp 3b
302 4: /* call threefish512_enc */
303         movw r24, CTX0
304         movw r22, TFCTX0
305         rcall threefish512_enc
306    /* xor block into ctx->g */
307         movw r30, CTX0
308         movw r26, BLOCK0
309         tst LEN_B
310 5:      breq 6f
311         ld r22, X+
312         ld r23, Z
313         eor r23, r22
314         st Z+, r23
315         dec LEN_B
316         rjmp 5b         
317 6:      tst MASK_B
318         breq 7f
319         eor r23, MASK_B
320         st -Z, r23
321         
322 7:      stack_free_large 8*12
323         pop_range 8, 17
324         ret
325
326