]> git.cryptolib.org Git - avr-crypto-lib.git/blob - noekeon/omac_noekeon.S
small optimizations to sha2 / sha256
[avr-crypto-lib.git] / noekeon / omac_noekeon.S
1 /* noekeon_omac.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2008  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    2008-08-24
23  * \license GPLv3 or later
24  * 
25  * 
26  * 
27  */
28
29 #include <avr/io.h>
30 #include "avr-asm-macros.S"
31
32 .extern noekeon_enc
33
34
35 /******************************************************************************/
36
37 /*
38  * void noekeon_omac_init(noekeon_omac_ctx_t *ctx){
39  *      memset(ctx, 0, 16);
40  * }
41  */
42 /*
43  * param ctx in r24:r25
44  */
45
46 .global omac_noekeon_init 
47 omac_noekeon_init:
48         movw r30, r24
49         ldi r24, 16
50 1:
51         st Z+, r1
52         dec r24
53         brne 1b
54         ret     
55
56 /******************************************************************************/        
57
58 /*
59  * void omac_noekeon_tweak(uint8_t t, const void *key, noekeon_omac_ctx_t *ctx){
60  *      *ctx[15] = t;
61  *      noekeon_enc(ctx, key);
62  * }
63  */
64 /*
65  * param t   in r24
66  * param key in r22:r23
67  * param ctx in r20:r21
68  */ 
69 .global omac_noekeon_tweak 
70 omac_noekeon_tweak:
71         movw r30, r20
72         std Z+15, r24
73         movw r24, r20
74         rjmp noekeon_enc
75
76 /******************************************************************************/
77         
78 /*
79  * void noekeon_omac_next(const void *buffer, const void *key, noekeon_omac_ctx_t *ctx){
80  *      memxor(ctx, buffer, 16);
81  *      noekeon_enc(ctx, key);
82  * }
83  */
84 /*
85  * param buffer in r24:r25
86  * param key    in r22:r23
87  * param ctx    in r20:r21
88  */ 
89 .global omac_noekeon_next 
90 omac_noekeon_next:
91         movw r26, r20
92         movw r30, r24
93         ldi r24, 16
94 1:
95         ld r0, X
96         ld r25, Z+
97         eor r0, r25
98         st X+, r0
99         dec r24
100         brne 1b
101         movw r24, r20
102         rjmp noekeon_enc        
103
104 /******************************************************************************/
105
106 /*
107  * void omac_noekeon_comppad(uint8_t *pad, const void *key, uint8_t length_b){
108  *      uint8_t c1,c2,r,j;
109  *      memset(pad, 0, 16);
110  *      noekeon_enc(pad, key);
111  *      r=(length_b==128)?1:2;
112  *      for(;r!=0;--r){
113  *              c1=0;
114  *              for(j=0;j<16;++j){
115  *                      c2 = c1;
116  *                      c1 = (pad[15-j])>>7;
117  *                      pad[15-j] = ((pad[15-j])<<1) | c2;
118  *              }
119  *              if(c1){
120  *                      pad[15] ^= 0x87;
121  *              }
122  *      }
123  *      if(length_b<128){
124  *              pad[(length_b)/8] ^= 0x80 >> (length_b%8);
125  *      }
126  *}
127  */
128 /*
129  * param pad      in r24:r25
130  * param key      in r22:r23
131  * param length_b in r20
132  */ 
133 .global omac_noekeon_comppad
134 omac_noekeon_comppad:
135         push_ r20, r24, r25
136         ldi r20, 16
137         movw r30, r24
138 1:
139         st Z+, r1
140         dec r20
141         brne 1b
142         rcall noekeon_enc
143         pop_ r31, r30, r20 /* now Z points at pad, and r20 contains length_b */
144         ldi r21, 1
145         clt
146         cpi r20, 128
147         breq 2f
148         set     
149         inc r21
150 2:
151         adiw r30, 16
152         ldi r24, 16
153         clc
154 3:      
155         ld r0, -Z
156         rol r0
157         st Z, r0
158         dec r24
159         brne 3b
160         
161         brcc 4f
162         ldi r24, 0x87
163         ldd r0, Z+15
164         eor r0, r24
165         std Z+15, r0
166 4:
167         dec r21
168         brne 2b
169         /* the B/P calculation is done, now we have only to insert the one for
170            messages of a length != n*128 */
171         brts 5f
172         ret
173 5:
174         /* r20 contains the length in bits where a one must be appended via xor */
175         mov r21, r20
176         lsr r21
177         lsr r21
178         lsr r21
179         add r30, r21
180         adc r31, r1
181         andi r20, 0x07
182         ldi r21, 0x80
183 6:      tst r20
184         breq 8f
185 7:      lsr r21
186         dec r20
187         brne 7b
188 8:      
189         ld r24, Z
190         eor r24, r21
191         st Z, r24
192         ret
193
194 /******************************************************************************/
195
196 /*
197  * void omac_noekeon_last(const void *buffer, uint8_t length_b, const void *key, noekeon_omac_ctx_t *ctx){
198  *      while(length_b>128){
199  *              omac_noekeon_next(buffer, key, ctx);
200  *              buffer = (uint8_t*)buffer +16;
201  *              length_b -= 128;
202  *      }
203  *      uint8_t pad[16];
204  *      omac_noekeon_comppad(pad, key, length_b);
205  *  memxor(pad, buffer, (length_b+7)/8);
206  *      omac_noekeon_next(pad, key, ctx);
207  *}
208  */
209 /*
210  * param buffer   in r24:r25
211  * param length_b in r22
212  * param key      in r20:r21
213  * param ctx      in r18:r19
214  */ 
215 .global omac_noekeon_last
216 omac_noekeon_last:
217         push_range 10, 16
218         push_ r28, r29
219         movw r28, r24 /* buffer */
220         movw r12, r20 /* key */
221         movw r14, r18 /* ctx */
222         mov r16, r22  /* length_b */
223 1:
224         cpi r16, 129
225         brlo 2f
226         movw r22, r20
227         movw r20, r18
228         rcall omac_noekeon_next
229         adiw r28, 16
230         subi r16, 128
231 2:
232         stack_alloc 16
233         adiw r30, 1
234         movw r10, r30
235         movw r24, r30
236         movw r22, r12
237         mov  r20, r16
238         rcall omac_noekeon_comppad
239     movw r30, r10
240     subi r16, -7
241     lsr r16
242         lsr r16
243         lsr r16
244         breq 4f 
245 3:
246         ld r0,  Z
247         ld r24, Y+
248         eor r0, r24
249         st Z+, r0
250         dec r16
251         brne 3b         
252 4: 
253         movw r24, r10
254         movw r22, r12
255         movw r20, r14
256         rcall omac_noekeon_next
257         stack_free 16
258  
259         pop_ r29, r28
260         pop_range 10, 16
261         ret
262
263 /******************************************************************************/
264
265 /* 
266  *void omac_noekeon(void *dest, const void *msg, uint16_t msglength_b,
267  *                  const void *key, uint8_t t){
268  *      omac_noekeon_init(dest);
269  *      if(t!=0xff)
270  *              omac_noekeon_tweak(t,key,dest);
271  *      while(msglength_b>128){
272  *              omac_noekeon_next(msg, key, dest);
273  *              msg = (uint8_t*)msg +16;
274  *              msglength_b -= 128;
275  *      }
276  *      omac_noekeon_last(msg, msglength_b, key, dest);                         
277  *}
278  */
279 /*
280  * param dest        in r24:r25
281  * param msg         in r22:r23
282  * param msglength_b in r20:r21
283  * param key         in r18:r19
284  * param t           in r16
285  */ 
286 MSG0 = 28
287 MSG1 = 29
288 KEY0 = 10
289 KEY1 = 11
290 LEN0 = 12
291 LEN1 = 13
292 DST0 = 14
293 DST1 = 15 
294
295 .global omac_noekeon
296 omac_noekeon:
297         push_ r28, r29 
298         push_range 10, 17 
299         movw MSG0, r22 /* msg */
300         movw KEY0, r18 /* key */
301         movw LEN0, r20 /* msglength_b */
302         movw DST0, r24 /* dest */
303         /* omac_noekeon_init(dest); */
304         rcall omac_noekeon_init
305         cpi r16, 0xff
306         breq 1f
307         mov  r24, r16
308         movw r22, KEY0
309         movw r20, DST0
310         /* omac_noekeon_tweak(t,key,dest); */
311         rcall omac_noekeon_tweak        
312 1:      
313         movw r16, LEN0
314         tst r17
315         breq 4f
316 3:      
317         movw r24, MSG0
318         movw r22, KEY0
319         movw r20, DST0
320         /* omac_noekeon_next(msg, key, dest); */
321         rcall omac_noekeon_next
322         adiw MSG0, 16
323         subi r16, 128
324         sez
325         sbci r17, 0 /* wont change Z if result is zero */
326         brne 3b
327 4:
328         movw r24, MSG0
329         mov r22, r16
330         movw r20, KEY0
331         movw r18, DST0
332         /* omac_noekeon_last(msg, msglength_b, key, dest); */
333         call omac_noekeon_last
334         
335         pop_range 10, 17
336         pop_ r29, r28
337         ret
338  
339  
340  
341  
342  
343  
344  
345  
346  
347  
348  
349  
350
351
352
353