]> git.cryptolib.org Git - avr-crypto-lib.git/blob - skein/ubi256_asm.S
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / skein / ubi256_asm.S
1 /* ubi256_asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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   bg@nerilex.org
22  * \date    2009-03-16
23  * \license GPLv3 or later
24  */ 
25
26 #include "avr-asm-macros.S"
27
28 /******************************************************************************/
29 /*
30 void ubi256_init(ubi256_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, 32);
34 }
35 */
36 /*
37  * param ctx:  r24:r25
38  * param g:    r22:r23
39  * param type: r20
40  */
41 .global ubi256_init
42 ubi256_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, 32
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 ubi256_ctx2hash(void *dest, const ubi256_ctx_t *ctx){
61         memcpy(dest, ctx->g, UBI256_BLOCKSIZE_B);
62 }
63 */
64 /*
65  * param dest: r24:r24
66  * param ctx:  r22:r23
67  */
68 .global ubi256_ctx2hash
69 ubi256_ctx2hash:
70         movw r26, r24
71         movw r30, r22
72         adiw r30, 16
73         ldi r22, 32
74 1:      ld r23, Z+
75         st X+, r23
76         dec r22
77         brne 1b
78         ret
79
80 /******************************************************************************/
81 /*
82 void ubi256_nextBlock(ubi256_ctx_t *ctx, const void *block){
83         threefish256_ctx_t tfctx;
84         ((uint64_t*)(ctx->tweak))[0] += UBI256_BLOCKSIZE_B;
85         threefish256_init(ctx->g, ctx->tweak, &tfctx);
86         memcpy(ctx->g, block, UBI256_BLOCKSIZE_B);
87         threefish256_enc(ctx->g, &tfctx);
88         memxor(ctx->g, block, UBI256_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 ubi256_nextBlock
103 ubi256_nextBlock:
104         stack_alloc_large 64
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 (32) to tweak */
112         ldi r25, 32
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 threefish256_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 threefish256_init
129         /* copy block to ctx->g */      
130         movw r26, CTX0
131         movw r30, BLOCK0
132         ldi r25, 32
133 1:      ld r24, Z+
134         st X+, r24
135         dec r25
136         brne 1b
137 /* call threefish256_enc */     
138         movw r24, CTX0
139         movw r22, TFCTX0
140         rcall threefish256_enc
141 /* xor block into ctx->g */     
142         movw r26, BLOCK0
143         movw r30, CTX0
144         ldi r25, 32
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         ld r24, Z
154         andi r24, ~0x40
155         st Z, r24
156 exit:
157         pop_range 2, 7
158         stack_free_large 64
159         ret
160
161 /******************************************************************************/
162 /*
163 void ubi256_lastBlock(ubi256_ctx_t *ctx, const void *block, uint16_t length_b){
164         threefish256_ctx_t tfctx;
165         while(length_b>UBI256_BLOCKSIZE){
166                 ubi256_nextBlock(ctx, block);
167                 block = (uint8_t*)block + UBI256_BLOCKSIZE_B;
168                 length_b -= UBI256_BLOCKSIZE;
169         }
170         ctx->tweak[15] |= 0x80;
171         ((uint64_t*)(ctx->tweak))[0] += (length_b+7)/8;
172         if(length_b & 0x07){
173                 ctx->tweak[14] |= 0x80;
174         }
175         threefish256_init(ctx->g, ctx->tweak, &tfctx);
176         memset(ctx->g, 0, UBI256_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                 ctx->g[((length_b+7)/8)-1] &= ~((0x80>>(length_b&7))-1);
181         }
182         threefish256_enc(ctx->g, &tfctx);
183         memxor(ctx->g, block, (length_b+7)/8);
184         if(length_b & 0x07){
185                 ctx->g[((length_b+7)/8)-1] ^= 0x80>>(length_b&7);
186         }
187
188 */
189 /*
190  * param ctx:     r24:r25
191  * param block:   r22:r23
192  * param ength_b: r20:r21
193  */
194 MASK_B  =  8 
195 LEN_B   =  9
196 TFCTX0  = 10
197 TFCTX1  = 11
198 CTX0    = 12
199 CTX1    = 13
200 BLOCK0  = 14
201 BLOCK1  = 15
202 LENGTH0 = 16
203 LENGTH1 = 17
204 .global ubi256_lastBlock
205 ubi256_lastBlock:
206 /* run nextBlock for preceding blocks*/
207         push_range 8, 17
208         movw CTX0, r24
209         movw BLOCK0, r22
210         movw LENGTH0, r20
211 1:      cpi LENGTH1, 2
212         brlo 2f
213         movw r24, CTX0
214         movw r22, BLOCK0
215         rcall ubi256_nextBlock
216         ldi r25, 32
217         add BLOCK0, r25
218         adc BLOCK1, r1
219         dec LENGTH1
220         rjmp 1b
221 2:      tst LENGTH1
222         breq 3f
223         tst LENGTH0
224         breq 3f
225         movw r24, CTX0
226         movw r22, BLOCK0
227         rcall ubi256_nextBlock
228         ldi r25, 32
229         add BLOCK0, r25
230         adc BLOCK1, r1
231         dec LENGTH1
232 3:      /* now the real fun */
233     stack_alloc_large 64
234         adiw r30, 1
235         movw TFCTX0, r30
236         /* calculate LEN_B */
237         movw r24, LENGTH0
238         adiw r24, 7
239         lsr r25
240         ror r24
241         lsr r24
242         lsr r24
243         mov LEN_B, r24
244         /* add length to tweak */
245         movw r30, CTX0
246         ld r24, Z
247         add r24, LEN_B
248         st Z+, r24
249         ldi r25, 11
250 1:      ld r24, Z
251         adc r24, r1
252         st Z+, r24
253         dec r25
254         brne 1b
255         /* set 'final' bit*/
256         movw r30, CTX0
257         ldd r24, Z+15
258         ori r24, 0x80
259         std Z+15, r24
260         /* store in T if we do bit processing and set 'BitPad' bit*/
261         clr MASK_B
262         mov r24, LENGTH0
263         andi r24, 0x07
264         tst r24
265         breq 4f
266         ldd r25, Z+14
267         ori r25, 0x80
268         std Z+14, r25
269         ldi r25, 0x80
270         mov MASK_B, r25
271 1:      lsr MASK_B
272         dec r24
273         brne 1b
274 4:  /* call threefish256_init*/
275         movw r24, CTX0
276         adiw r24, 16
277         movw r22, CTX0
278         movw CTX0, r24 /* CTX points at ctx->g */
279         movw r20, TFCTX0
280         rcall threefish256_init
281         /* copy block to ctx->g */
282         movw r26, BLOCK0
283         movw r30, CTX0
284         mov r24, LEN_B
285         ldi r25, 32
286         sub r25, LEN_B
287         tst r24
288 1:      breq 2f
289         ld r22, X+
290         st Z+, r22
291         dec r24 
292         rjmp 1b
293 2:      tst MASK_B
294         breq 29f
295         or r22, MASK_B
296         st -Z, r22
297         adiw r30, 1
298 29:     tst r25
299 3:      breq 4f
300         st Z+, r1
301         dec r25
302         rjmp 3b
303 4: /* call threefish256_enc */
304         movw r24, CTX0
305         movw r22, TFCTX0
306         rcall threefish256_enc
307    /* xor block into ctx->g */
308         movw r30, CTX0
309         movw r26, BLOCK0
310         tst LEN_B
311 5:      breq 6f
312         ld r22, X+
313         ld r23, Z
314         eor r23, r22
315         st Z+, r23
316         dec LEN_B
317         rjmp 5b         
318 6:      tst MASK_B
319         breq 7f
320         eor r23, MASK_B
321         st -Z, r23
322         
323 7:      stack_free_large 64
324         pop_range 8, 17
325         ret
326
327