]> git.cryptolib.org Git - avr-crypto-lib.git/blob - noekeon_asm.S
+RC5 +size-statistics tool +small modification to nessie_bc_test (optional free(...
[avr-crypto-lib.git] / noekeon_asm.S
1 /* 
2  * noekeon assembler implementation for avr
3  * author: Daniel Otte
4  * email:  daniel.otte@rub.de
5  * license: GPLv3
6  */
7
8 #include <avr/io.h>
9
10 .macro push_all
11         push r2
12         push r3
13         push r4
14         push r5
15         push r6
16         push r7
17         push r8
18         push r9
19         push r10
20         push r11
21         push r12
22         push r13
23         push r14
24         push r15
25         push r16
26         push r17
27         push r28
28         push r29
29         in r28, _SFR_IO_ADDR(SREG)
30         push r28
31 .endm
32
33 .macro pop_all
34         pop r28
35         out _SFR_IO_ADDR(SREG), r28
36         pop r29
37         pop r28
38         pop r17
39         pop r16
40         pop r15
41         pop r14
42         pop r13
43         pop r12
44         pop r11
45         pop r10
46         pop r9
47         pop r8
48         pop r7
49         pop r6
50         pop r5
51         pop r4
52         pop r3
53         pop r2
54         clr r1
55 .endm
56
57 .macro xchg a b
58         eor \a, \b
59         eor \b, \a
60         eor \a, \b
61 .endm
62
63 .macro op32 op a b
64         \op \a\()_0, \b\()_0
65         \op \a\()_1, \b\()_1
66         \op \a\()_2, \b\()_2
67         \op \a\()_3, \b\()_3
68 .endm
69
70
71 .macro op32_4t op a b c d w x y z
72         \op \a, \w
73         \op \b, \x
74         \op \c, \y
75         \op \d, \z
76 .endm
77
78
79 .macro op32_prefix op p q a b c d w x y z
80         \op \p\()\a, \q\()\w
81         \op \p\()\b, \q\()\x
82         \op \p\()\c, \q\()\y
83         \op \p\()\d, \q\()\z
84 .endm
85
86 ; === bigendian_rotl32 ===
87 ; this function rotates a 32bit bigendian word n bits to the left
88 ;  param1: the 32-bit value
89 ;       given in r25,r24,r23,r22 (r22 is most significant)
90 ;  param2: the 8-bit parameter giving the number of bits to rotate
91 ;       given in r20
92 ;  return: the rotatet 32-bit word
93 ;   given in r25,r24,r23,r22   
94
95 bigendian_rotl32:
96         /* copy high bit of r22 to carry */
97         mov r1, r22
98 2:
99         rol r1
100
101         rol r25
102         rol r24
103         rol r23
104         rol r22
105         
106         dec r20
107         brne 2b
108 bigendian_rotl32_exit:
109         clr r1
110         ret
111         
112         
113 /******************************************************************************/
114
115 ; === bigendian_rotl32 ===
116 ; this function rotates a 32bit bigendian word n bits to the right
117 ;  param1: the 32-bit value
118 ;       given in r25,r24,r23,r22 (r22 is most significant)
119 ;  param2: the 8-bit parameter giving the number of bits to rotate
120 ;       given in r20
121 ;  return: the rotatet 32-bit word
122 ;   given in r25,r24,r23,r22   
123
124 bigendian_rotr32:
125         /* copy high bit of r25 to carry */
126
127         mov r1, r25
128 2:
129         ror r1
130         
131         ror r22
132         ror r23
133         ror r24
134         ror r25
135         dec r20
136         brne 2b
137 bigendian_rotr32_exit:
138         clr r1
139         ret
140
141 /******************************************************************************/
142 /*
143 void theta(uint32_t* k, uint32_t* a){
144         uint32_t temp;
145         temp = a[0] ^ a[2]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
146         a[1] ^= temp;
147         a[3] ^= temp;
148         
149         a[0] ^= k[0];
150         a[1] ^= k[1];
151         a[2] ^= k[2];
152         a[3] ^= k[3];
153
154         temp = a[1] ^ a[3]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
155         a[0] ^= temp;
156         a[2] ^= temp;   
157 }
158 */
159
160 round_const: .byte    0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A, \
161                     0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A, \
162                 0xD4
163
164 ;-- a[0]
165 state0_0 =  2
166 state0_1 =  3
167 state0_2 =  4
168 state0_3 =  5
169 ;-- a[1]
170 state1_0 =  6
171 state1_1 =  7
172 state1_2 =  8
173 state1_3 =  9
174 ;-- a[2]
175 state2_0 = 10
176 state2_1 = 11
177 state2_2 = 12
178 state2_3 = 13
179 ;-- a[3]
180 state3_0 = 14
181 state3_1 = 15
182 state3_2 = 16
183 state3_3 = 17
184
185 ; === theta ===
186 ;
187 ;  param1: the state in r2-r17
188 ;  param2: pointer to k in X (r26,r27)
189 ;
190 temp_a = 18
191 temp_b = 19
192 temp_c = 20
193 temp_d = 21
194
195 theta:
196         /* temp = a[0] ^ a[2]; temp ^= temp>>>8 ^ temp<<<8 */
197         op32_prefix mov, temp_, state0_, a,b,c,d, 0,1,2,3
198         op32_prefix eor, temp_, state2_, a,b,c,d, 0,1,2,3
199
200         mov r1, temp_a
201         eor r1, temp_b
202         eor r1, temp_c
203         eor r1, temp_d
204         
205         op32_prefix eor, temp_, r, a,b,c,d, 1,1,1,1
206
207         /* temp is know a little bit mixed c,d,a,b (if abcd is normal order) */
208         /* a[1] ^= temp */
209         eor state1_0, temp_c 
210         eor state1_1, temp_d 
211         eor state1_2, temp_a 
212         eor state1_3, temp_b
213         /* a[3] ^= temp */
214         eor state3_0, temp_c 
215         eor state3_1, temp_d 
216         eor state3_2, temp_a 
217         eor state3_3, temp_b
218         
219         /* state ^ k (X points to K) */
220         ldi r28, 2
221         clr r29 /* Y points to r2 aka state0_0 */
222         ldi temp_a, 16
223 1:      
224         ld r1, X+
225         ld r0, Y
226         eor r1, r0
227         st Y+, r1
228         dec temp_a
229         brne 1b
230         sbiw r26, 16 /* set X back to key */ 
231         
232         mov temp_a, state1_0
233         mov temp_b, state1_1
234         mov temp_c, state1_2
235         mov temp_d, state1_3
236         eor temp_a, state3_0
237         eor temp_b, state3_1
238         eor temp_c, state3_2
239         eor temp_d, state3_3
240         mov r1, temp_a
241         eor r1, temp_b
242         eor r1, temp_c
243         eor r1, temp_d
244         eor temp_a, r1
245         eor temp_b, r1
246         eor temp_c, r1
247         eor temp_d, r1
248         /* temp is know a little bit mixed c,d,a,b (if abcd is normal order) */
249         /* a[0] ^= temp */
250         eor state0_0, temp_c 
251         eor state0_1, temp_d 
252         eor state0_2, temp_a 
253         eor state0_3, temp_b
254         /* a[2] ^= temp */
255         eor state2_0, temp_c 
256         eor state2_1, temp_d 
257         eor state2_2, temp_a 
258         eor state2_3, temp_b
259         
260         clr r1
261         ret
262
263 /******************************************************************************/
264 ; === noekeon_enc ===
265 ;
266 ;  param1: pointer to buffer/state (r24,r25)
267 ;  param2: pointer to k (r22,r23) 
268 ;
269 .global noekeon_enc
270 noekeon_enc:
271         push_all
272         /* load state */
273         movw r26, r22
274         ldi r28, 2
275         clr r29 /* Y points at r2 aka state0_0 */
276         movw r30, r24 /* Z points at state */
277         push r30
278         push r31
279         ldi r22, 16
280         push r22 /* 16 is also the number of rounds and gets pushed here */
281 1:      
282         ld r0, Z+
283         st Y+, r0
284         dec r22
285         brne 1b
286         /* state loaded */
287         push r1 /* push round constan2 (0x00) */
288         ldi r20, 0x80
289         push r20 /* push round constan2 (0x00) */
290         rjmp 3f
291 2:
292         ldi r30, lo8(round_const+15)
293         ldi r31, hi8(round_const+15)
294         sub r30, r22
295         sbci r31, 0
296         clr r1
297         push r1
298         lpm r0, Z
299         push r0
300 3:
301         call round /* pops rc2 & rc1 */
302         pop r22
303         dec r22
304         push r22
305         brne 2b
306
307         pop r22
308
309         ldi r22, 0xD4
310         eor state0_3, r22
311         call theta
312
313         pop r31
314         pop r30
315         clr r29
316         ldi r28, 2
317         ldi r22, 16
318 1:      
319         ld r0, Y+
320         st Z+, r0
321         dec r22
322         brne 1b
323         
324         pop_all
325         ret
326 /******************************************************************************/
327 /******************************************************************************/
328 ; === noekeon_dec ===
329 ;
330 ;  param1: pointer to buffer/state (r24,r25)
331 ;  param2: pointer to k  (r22,r23) 
332 ;
333 .global noekeon_dec
334 noekeon_dec:
335         push_all
336         /* allocate 16 bytes on the stack */
337         in r30, _SFR_IO_ADDR(SPL)
338         in r31, _SFR_IO_ADDR(SPH)
339         sbiw r30, 16 
340         out  _SFR_IO_ADDR(SPH), r31
341         out  _SFR_IO_ADDR(SPL), r30
342
343         adiw r30, 1
344         /* push state pointer */
345         push r24
346         push r25
347         movw r26, r22 /* move key ptr to X */
348
349         /* set stackkey to zero */
350         ldi r22, 16
351 1:      st Z+, r1
352         dec r22
353         brne 1b
354                 
355         /* copy key to state */
356         clr r29
357         ldi r28, 2
358         ldi r22, 16
359 1:  ld r0, X+
360         st Y+, r0
361         dec r22
362         brne 1b 
363
364         movw r26, r30
365         sbiw r26, 16 /* set X back to begining of stack key */
366         call theta
367         
368         /* mov state to stackkey */
369         clr r29
370         ldi r28,  2
371         ldi r22, 16
372 1:      ld r0, Y+
373         st X+, r0       
374         dec r22
375         brne 1b
376         sbiw r26, 16 /* set X back to begining of stack key */
377         
378         /* move data from stateptr to state */
379         pop r31
380         pop r30
381         push r30
382         push r31
383         clr r29
384         ldi r28,  2
385         ldi r22, 16
386         push r22
387 1:      ld r0, Z+
388         st Y+, r0
389         dec r22
390         brne 1b 
391         
392 ;--- snip 8< ----
393         
394         ldi r20, 0xD4
395         push r20 /* push round constant2 (0xD4) */
396         push r22 /* push round constan1 (0x00) */
397         rjmp 3f
398 2:
399         ldi r30, lo8(round_const-1)
400         ldi r31, hi8(round_const-1)
401         clr r1
402         add r30, r22
403         adc r31, r1
404         lpm r0, Z
405         push r0
406         push r1
407 3:
408         call round /* pops rc2 & rc1 */
409         pop r22
410         dec r22
411         push r22
412         brne 2b
413 ;----
414         pop r22
415
416         call theta
417         ldi r22, 0x80
418         eor state0_3, r22
419         
420 write_state_back:       
421         /* write state back */
422         pop r31 /* pop state pointer */
423         pop r30
424         clr r29
425         ldi r28, 2
426         ldi r22, 16
427 1:      
428         ld r0, Y+
429         st Z+, r0
430         dec r22
431         brne 1b
432         
433         /* remove key from stack */
434         in r30, _SFR_IO_ADDR(SPL)
435         in r31, _SFR_IO_ADDR(SPH)
436         adiw r30, 16 
437         out  _SFR_IO_ADDR(SPH), r31
438         out  _SFR_IO_ADDR(SPL), r30
439         pop_all
440         ret
441 /******************************************************************************/
442         
443 round:  
444         pop r24
445         pop r25
446         pop r1
447         eor state0_3, r1
448         call theta
449         pop r1
450         eor state0_3, r1
451         push r25
452         push r24
453 pi_gamma_pi:
454         ldi r30, lo8(bigendian_rotl32)
455         ldi r31, hi8(bigendian_rotl32)
456         call pi
457         /* pi1 done; now gamma */
458         call gamma_1
459         /* a[0] <-> a[3] */
460         xchg state0_0, state3_0
461         xchg state0_1, state3_1
462         xchg state0_2, state3_2
463         xchg state0_3, state3_3
464         /* a[2] ^= a[0] ^ a[1] ^ a[3] */
465         op32 eor, state2, state0
466         op32 eor, state2, state1
467         op32 eor, state2, state3
468 /*      
469         eor state2_0, state0_0
470         eor state2_1, state0_1
471         eor state2_2, state0_2
472         eor state2_3, state0_3
473         eor state2_0, state1_0
474         eor state2_1, state1_1
475         eor state2_2, state1_2
476         eor state2_3, state1_3
477         eor state2_0, state3_0
478         eor state2_1, state3_1
479         eor state2_2, state3_2
480         eor state2_3, state3_3
481 */
482         call gamma_1
483         ldi r30, lo8(bigendian_rotr32)
484         ldi r31, hi8(bigendian_rotr32)
485         call pi
486         ret
487         
488 gamma_1:
489         /* a[1] ^= ~(a[3]|a[2])*/
490         mov r1, state3_0
491         or  r1, state2_0
492         com r1
493         eor state1_0, r1
494
495         mov r1, state3_1
496         or  r1, state2_1
497         com r1
498         eor state1_1, r1
499
500         mov r1, state3_2
501         or  r1, state2_2
502         com r1
503         eor state1_2, r1
504         
505         mov r1, state3_3
506         or  r1, state2_3
507         com r1
508         eor state1_3, r1
509         
510         /* a[0] ^= a[2]&a[1] */
511         mov r1, state2_0
512         and r1, state1_0
513         eor state0_0, r1
514         
515         mov r1, state2_1
516         and r1, state1_1
517         eor state0_1, r1
518         
519         mov r1, state2_2
520         and r1, state1_2
521         eor state0_2, r1
522         
523         mov r1, state2_3
524         and r1, state1_3
525         eor state0_3, r1
526         ret
527         
528 pi:     
529         lsr r31
530         ror r30
531         /* a[1] <<<= 1*/
532         mov r22, state1_0
533         mov r23, state1_1
534         mov r24, state1_2
535         mov r25, state1_3
536         ldi r20, 1
537         icall
538         mov state1_0, r22
539         mov state1_1, r23
540         mov state1_2, r24
541         mov state1_3, r25
542         /* a[2] <<<= 5*/
543         mov r22, state2_0
544         mov r23, state2_1
545         mov r24, state2_2
546         mov r25, state2_3
547         ldi r20, 5
548         icall
549         mov state2_0, r22
550         mov state2_1, r23
551         mov state2_2, r24
552         mov state2_3, r25
553         /* a[3] <<<= 2*/
554         mov r22, state3_0
555         mov r23, state3_1
556         mov r24, state3_2
557         mov r25, state3_3
558         ldi r20, 2
559         icall
560         mov state3_0, r22
561         mov state3_1, r23
562         mov state3_2, r24
563         mov state3_3, r25
564         ret
565
566 /******************************************************************************/
567         
568 /*
569 void noekeon_init(void* key, noekeon_ctx_t* ctx){
570         uint8_t nullv[16];
571         
572         memset(nullv, 0, 16);
573         memcpy(ctx, key, 16);
574         noekeon_enc(ctx, nullv);
575 }
576 */
577 .global noekeon_init
578 noekeon_init:
579 ; === noekeon_init ===
580 ;
581 ;  param1: pointer to key (r24,r25)
582 ;  param2: pointer to context  (r22,r23) 
583 ;
584         in r30, _SFR_IO_ADDR(SPL)
585         in r31, _SFR_IO_ADDR(SPH)
586         sbiw r30, 16 
587         out  _SFR_IO_ADDR(SPH), r31
588         out  _SFR_IO_ADDR(SPL), r30
589
590         movw r26, r22
591         adiw r30, 1
592         movw r22, r30
593         /* set nullv(stack) to zero */
594         ldi r20, 16
595 1:      st Z+, r1
596         dec r20
597         brne 1b
598
599         /* copy key data to ctx */
600         movw r30, r24
601         ldi r20, 16
602 1:      ld r1, Z+
603         st X+, r1
604         dec r20
605         brne 1b
606         clr r1
607         
608         sbiw r26, 16
609         movw r24, r26
610         call noekeon_enc
611         
612         in r30, _SFR_IO_ADDR(SPL)
613         in r31, _SFR_IO_ADDR(SPH)
614         adiw r30, 16 
615         out  _SFR_IO_ADDR(SPH), r31
616         out  _SFR_IO_ADDR(SPL), r30     
617         ret
618         
619
620
621