]> git.cryptolib.org Git - avr-crypto-lib.git/blob - serpent/serpent-asm.S
new and more compact aes
[avr-crypto-lib.git] / serpent / serpent-asm.S
1 /* serpent_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 /* 
21  * File:        serpent_sboxes.S
22  * Author:      Daniel Otte
23  * Date:        2008-08-07
24  * License:     GPLv3 or later
25  * Description: Implementation of the serpent sbox function.
26  * 
27  */
28  
29 #include <avr/io.h>
30 #include "avr-asm-macros.S"
31
32 /*
33 static void serpent_lt(uint8_t *b){
34         X0 = rotl32(X0, 13);
35         X2 = rotl32(X2,  3);
36         X1 ^= X0 ^ X2;
37         X3 ^= X2 ^ (X0 << 3);
38         X1 = rotl32(X1, 1);
39         X3 = rotl32(X3, 7);
40         X0 ^= X1 ^ X3;
41         X2 ^= X3 ^ (X1 << 7);
42         X0 = rotl32(X0, 5);
43         X2 = rotr32(X2, 10);
44 }
45 */
46
47 #if 0
48 A0 =  4
49 A1 =  5
50 A2 =  6
51 A3 =  7
52 B0 =  8
53 B1 =  9
54 B2 = 10
55 B3 = 11
56 C0 = 12
57 C1 = 13
58 C2 = 14
59 C3 = 15
60 D0 = 16
61 D1 = 17
62 D2 = 18
63 D3 = 19
64 T0 = 20
65 T1 = 21
66 T2 = 22
67 T3 = 23
68
69 serpent_lt:
70         push_range 4, 17
71         movw r26, r24
72         ld A2, X+
73         ld A3, X+
74         ld A0, X+
75         ld A1, X+
76         ldi r20, 3
77         mov r0, A0
78 1:      
79         lsr r0
80         ror A3
81         ror A2
82         ror A1
83         ror A0
84         dec r20
85         brne 1b
86         ld B0, X+
87         ld B1, X+
88         ld B2, X+
89         ld B3, X+
90         
91         ld C2, X+
92         ld C3, X+
93         ld C0, X+
94         ld C1, X+
95         ldi r20, 3
96         mov r0, C0
97 1:      
98         lsr r0
99         ror C3
100         ror C2
101         ror C1
102         ror C0
103         dec r20
104         brne 1b
105
106         ld D0, X+
107         ld D1, X+
108         ld D2, X+
109         ld D3, X+
110         /* X1 ^= X0 ^ X2; */
111         eor B0, A0
112         eor B0, C0
113         eor B1, A1
114         eor B1, C1
115         eor B2, A2
116         eor B2, C2
117         eor B3, A3
118         eor B3, C3
119         /* X3 ^= X2 ^ (X0 << 3); */
120         mov T0, A0
121         mov T1, A1
122         mov T2, A2
123         mov T3, A3
124         ldi r24, 3
125 1:
126         lsl T0
127         rol T1
128         rol T2
129         rol T3
130         dec r24
131         brne 1b
132         eor C0, B0
133         eor C0, T0
134         eor C1, B1
135         eor C1, T1
136         eor C2, B2
137         eor C2, T2
138         eor C3, B3
139         eor C3, T3
140         /*      X1 = rotl32(X1, 1); */
141         mov r0, B3
142         lsl r0
143         rol B0
144         rol B1
145         rol B2
146         rol B3
147         /* X3 = rotl32(X3, 7); */
148         mov r0, D3
149         mov D3, D2
150         mov D2, D1
151         mov D1, D0
152         mov D0, r0
153         lsr r0
154         ror D3
155         ror D2
156         ror D1
157         ror D0
158         /*      X0 ^= X1 ^ X3; */
159         eor A0, B0
160         eor A0, D0
161         eor A1, B1
162         eor A1, D1
163         eor A2, B2
164         eor A2, D2
165         eor A3, B3
166         eor A3, D3
167         /*  X2 ^= X3 ^ (X1 << 7); */
168         mov T1, B0
169         mov T2, B1
170         mov T3, B2
171         clr T0
172         mov r0, B3
173         lsr r0
174         ror T2
175         ror T1
176         ror T0 
177         eor C0, D0
178         eor C0, T0
179         eor C1, D1
180         eor C1, T1
181         eor C2, D2
182         eor C2, T2
183         eor C3, D3
184         eor C3, T3
185         /*      X0 = rotl32(X0, 5); */
186         ldi r24, 5
187         mov r0, A3
188 1:      
189         lsl r0
190         rol A0
191         rol A1
192         rol A2
193         rol A3
194         dec r24
195         brne 1b
196         /* X2 = rotr32(X2, 10); */
197         mov r0, C0
198         mov C0, C1
199         mov C1, C2
200         mov C2, C3      
201         mov C3, r0
202         ldi r24, 2
203 1:
204         lsr r0
205         ror C2
206         ror C1
207         ror C0
208         ror C3  
209         dec r24
210         brne 1b
211         
212         clr r31
213         ldi r30, D3+1
214         ldi r24, 16
215 1:
216         ld r0, -Z
217         st -X, r0       
218         dec r24
219         brne 1b
220         
221         pop_range 4, 17
222         ret
223 #endif
224
225 T0 = 22
226 T1 = 23
227 T2 = 24
228 T3 = 25
229 TT = 21
230 /* rotate the data word (4 byte) pointed to by X by r20 bits to the right */
231 memrotr32:
232         ld T0, X+
233         ld T1, X+
234         ld T2, X+
235         ld T3, X+
236         mov TT, T0
237 1:
238         lsr TT
239         ror T3
240         ror T2
241         ror T1
242         ror T0
243         dec r20
244         brne 1b
245         st -X, T3
246         st -X, T2
247         st -X, T1
248         st -X, T0
249         ret
250         
251 /* rotate the data word (4 byte) pointed to by X by r20 bits to the left */
252 memrotl32:
253         ld T0, X+
254         ld T1, X+
255         ld T2, X+
256         ld T3, X+
257         mov TT, T3
258 1:
259         lsl TT
260         rol T0
261         rol T1
262         rol T2
263         rol T3
264         dec r20
265         brne 1b
266         st -X, T3
267         st -X, T2
268         st -X, T1
269         st -X, T0
270         ret
271
272 /* xor the dataword (4 byte) pointed by Z into X */     
273 memeor32:
274   ldi T2, 4
275 1:  
276   ld T0, X              
277   ld T1, Z+
278   eor T0, T1
279   st X+, T0
280   dec T2
281   brne 1b
282   ret
283
284 serpent_lt:
285          /* X0 := X0 <<< 13 */
286         movw r26, r24
287         ldi r20, 7
288         rcall memrotl32
289         ldi r20, 6
290         rcall memrotl32
291         /* X2 := X2 <<< 3 */
292         adiw r26, 8
293         ldi r20, 3
294         rcall memrotl32
295         /* X1 ^= X2 */
296         movw r30, r26
297         sbiw r26, 4
298         rcall memeor32
299         /* X1 ^= X0 */
300         sbiw r26, 4
301         sbiw r30, 12
302         rcall memeor32
303         /* X3 ^= X2 */
304         movw r30, r26
305         adiw r26, 4
306         rcall memeor32
307         /* T := X0 */
308         sbiw r26, 16
309         ld r18, X+
310         ld r19, X+
311         ld r20, X+
312         ld r21, X+
313         /* T := T<<3 */
314         ldi r22, 3
315 1:
316         lsl r18
317         rol r19
318         rol r20
319         rol r21
320         dec r22
321         brne 1b
322         clr r31 
323         /* X3 ^= T */
324         adiw r26, 8
325         ldi r30, 18
326         rcall memeor32
327         /* X1 := X1<<<1 */
328         sbiw r26, 12
329         ldi r20, 1
330         rcall memrotl32
331         /* X3 := X3<<<7 */
332         adiw r26, 8
333         ldi r20, 7
334         rcall memrotl32
335         /* X0 ^= X3 */
336         movw r30, r26
337         sbiw r26, 12
338         rcall memeor32
339         /* X0 ^= X1 */
340         movw r30, r26
341         sbiw r26, 4
342         rcall memeor32
343         /* X2 ^= X3 */
344         adiw r26, 4
345         adiw r30, 4
346         rcall memeor32
347         /* T := X1<<<8 */
348         sbiw r26, 8
349         ld r19, X+
350         ld r20, X+
351         ld r21, X+
352         ld r18, X+
353         /* T := T>>>1; T&=0xfffffff8 */
354         lsr r18
355         ror r21
356         ror r20
357         ror r19
358         clr r18
359         ror r18
360         clr r31
361         ldi r30, 18
362         /* X2 ^= T */
363         rcall memeor32
364         /* X0 := X0 <<< 5 */
365         sbiw r26, 12
366         ldi r20, 5
367         rcall memrotl32
368         /* X3 := X3 >>> 10 */
369         adiw r26, 8
370         ldi r20, 7
371         rcall memrotr32
372         ldi r20, 3
373         rcall memrotr32
374         ret
375
376 serpent_inv_lt:
377          /* X0 := X0 >>> 5 */
378         movw r26, r24
379         ldi r20, 5
380         rcall memrotr32
381         /* X2 := X2 <<< 10 */
382         adiw r26, 8
383         ldi r20, 7
384         rcall memrotl32
385         ldi r20, 3
386         rcall memrotl32
387         /* X2 ^= X3 */
388         movw r30, r26
389         adiw r30, 4
390         rcall memeor32
391         sbiw r26, 4
392         sbiw r30, 12
393         /* T := X1<<7 */
394         ld r19, Z+
395         ld r20, Z+
396         ld r21, Z+
397         ld r18, Z+
398         lsr r18
399         ror r21
400         ror r20
401         ror r19
402         clr r18
403         ror r18
404     clr r31
405     /* X2 ^= T */
406     ldi r30, 18
407     rcall memeor32
408     /* X0 ^= X1 */
409     sbiw r26, 12
410     movw r30, r26
411     adiw r30, 4
412     rcall memeor32
413     /* X0 ^= X3 */
414     sbiw r26, 4
415     adiw r30, 4
416     rcall memeor32
417     /* X1 := X1>>>1 */
418     ldi r20, 1
419         rcall memrotr32
420         /* X3 := X3>>>7 */
421         adiw r26, 8
422         ldi r20, 7
423         rcall memrotr32
424         /* X3 ^= X2 */
425         sbiw r30, 8
426         rcall memeor32
427         sbiw r26, 4
428         /* T:= X0<<3 */
429         sbiw r30, 12
430         ld r18, Z+
431         ld r19, Z+
432         ld r20, Z+
433         ld r21, Z+
434         ldi r24, 3
435 1:
436         lsl r18
437         rol r19
438         rol r20
439         rol r21
440         dec r24
441         brne 1b
442         /* X3 ^= T */
443         clr r31
444         ldi r30, 18
445         rcall memeor32
446         /* X1 ^= X0 */
447         sbiw r26, 12
448         movw r30, r26
449         sbiw r30, 4
450         rcall memeor32
451         /* X1 ^= X2 */
452         movw r26, r30
453         adiw r30, 4
454         rcall memeor32
455         /* X2 := X2 >>> 3 */
456         ldi r20, 3
457         rcall memrotr32
458         /* X0 := X0 >>> 13 */
459         sbiw r26, 8
460         ldi r20, 7
461         rcall memrotr32
462         ldi r20, 6
463         rcall memrotr32
464         ret
465
466 /*
467 #define GOLDEN_RATIO 0x9e3779b9l
468
469 static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
470         uint32_t ret;
471         ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
472         ret = rotl32(ret, 11);
473         return ret;
474 }
475 */
476 /*
477  * param b is passed in r24:r25
478  * param i is passed in r22
479  * return value is returned in r22.r23.r24.r25
480  */
481  /* trashes:
482   *  r20-r25, r30-r31
483   */
484 serpent_gen_w:
485         movw r30, r24
486         /* ^i^b[0]*/
487     ld r21, Z+
488     eor r22, r21
489     ld r23, Z+
490     ld r24, Z+
491     ld r25, Z+
492     /* ^b[3]^b[5]^[b7] */
493     adiw r30, 4
494     ldi r20, 3
495 1:    
496     adiw r30, 4
497     ld r21, Z+
498     eor r22, r21
499     ld r21, Z+
500     eor r23, r21
501     ld r21, Z+
502     eor r24, r21
503     ld r21, Z+
504     eor r25, r21
505         dec r20
506         brne 1b
507         /* ^0x9e3779b9l */
508         ldi r21, 0xb9
509         eor r22, r21
510         ldi r21, 0x79
511         eor r23, r21
512         ldi r21, 0x37
513         eor r24, r21
514         ldi r21, 0x9e
515         eor r25, r21
516         /* <<<11 */
517         mov r21, r25
518         mov r25, r24
519         mov r24, r23
520         mov r23, r22
521         mov r22, r21
522         mov r21, r25
523         ldi r20, 3
524 1:
525         lsl r21
526         rol r22
527         rol r23
528         rol r24
529         rol r25
530         dec r20
531         brne 1b
532         ret
533
534 /*
535  * void serpent_init(const void *key, uint16_t keysize_b, serpent_ctx_t *ctx)
536  */
537 /*
538  * param key     is passed in r24:r25
539  * param keysize is passed in r22:r23
540  * param ctx     is passed in r20:r21
541  */
542 .global serpent_init
543 serpent_init:
544     stack_alloc 32
545     adiw r30, 1
546         push_ r30, r31
547     movw r26, r22
548     adiw r26, 7
549     tst r27
550     breq 1f
551         ldi r26, 32
552         rjmp 2f
553 1:
554         lsr r26
555         lsr r26
556         lsr r26
557 2:      
558         mov r22, r26
559         bst r22, 5 /* store in T if we have to do the "append 1 thing"*/
560         ldi r27, 32
561 3:      /* set buffer to zero */
562         st Z+, r1
563         dec r27
564         brne 3b
565         
566         movw r26, r24 /* X points to the key */
567         sbiw r30, 32
568         tst r22
569         breq 5f /* if keylength_b==0 */
570 4:      /* copy keybytes to buffer */
571         ld r19, X+
572         st Z+, r19
573         dec r22
574         brne 4b
575 5:
576         brts 7f /* if keylength_b == 256 */
577         ldi r18, 0x01
578         andi r22, 0x07
579         brne 6f
580         st Z, r18
581         rjmp 7f
582 6:      /* shift the one to the right position */
583         lsl r18
584         dec r22
585         brne 6b
586         or r18, r19
587         st -Z, r18
588 7: /* post "appending 1 thing" buffer is ready for subkey generation */
589         movw r26, r20  /* X points to the context */
590         
591         pop_ r19, r18 /* r18:r19 points to the buffer */
592         push r16
593         clr r16
594 8:
595         movw r24, r18
596         mov  r22, r16
597         rcall serpent_gen_w
598         movw r30, r18
599         ldi r20, 7*4
600 1: /* the memmove */
601         ldd r0, Z+4
602         st Z+, r0
603         dec r20
604         brne 1b
605   /* store new word in buffer and context */    
606         st Z+, r22
607         st Z+, r23
608         st Z+, r24
609         st Z+, r25
610         st X+, r22
611         st X+, r23
612         st X+, r24
613         st X+, r25
614         
615         inc r16
616         cpi r16, 132
617         brne 8b 
618         
619         push_ r28, r29
620         movw r28, r26
621         subi r28, lo8(132*4)
622         sbci r29, hi8(132*4)
623         ldi r16, 33
624 2:
625         movw r24, r28
626         adiw r28, 16
627         ldi r22, 2
628         add r22, r16
629         rcall sbox128
630         dec r16
631         brne 2b
632         pop_ r29, r28, r16
633         stack_free 32
634         ret
635
636 /*
637  * void serpent_enc(void *buffer, const serpent_ctx_t *ctx){
638  */
639 /*
640  * param buffer is passed in r24:r25
641  * param ctx    is passed in r22:r23
642  */
643 .global serpent_enc
644 serpent_enc:
645
646         push_ r12, r13, r14, r15, r16 
647         clr r16
648         movw r14, r24
649         movw r12, r22
650 1:
651         movw r24, r14
652         movw r22, r12
653         ldi r20, 16
654         add r12, r20
655         adc r13, r1
656         clr r21
657         rcall memxor
658         movw r24, r14
659         mov r22, r16
660         rcall sbox128
661         movw r24, r14
662         rcall serpent_lt
663         
664         inc r16
665         cpi r16, 31
666         brne 1b
667         
668         movw r24, r14
669         movw r22, r12
670         ldi r20, 16
671         add r12, r20
672         adc r13, r1
673         clr r21
674         rcall memxor
675         movw r24, r14
676         mov r22, r16
677         rcall sbox128
678         
679         inc r16
680         movw r24, r14
681         movw r22, r12
682         ldi r20, 16
683         clr r21
684         pop_ r16, r15, r14, r13, r12
685         rjmp memxor
686
687 /*
688  * void serpent_dec(void *buffer, const serpent_ctx_t *ctx){
689  */
690 /*
691  * param buffer is passed in r24:r25
692  * param ctx    is passed in r22:r23
693  */
694 .global serpent_dec
695 serpent_dec:
696         push_ r12, r13, r14, r15, r16 
697         movw r14, r24
698 //      ldi r16, lo8(32*16)
699 //      add r22, r16
700         ldi r16, hi8(32*16)
701         add r23, r16
702         movw r12, r22
703         ldi r20, 16
704         clr r21
705         rcall memxor
706         
707         movw r24, r14
708         ldi r22, 31
709         call inv_sbox128
710         
711         movw r24, r14
712         ldi r20, 16
713         sub r12, r20
714         sbc r13, r1
715         movw r22, r12
716         clr r21
717         rcall memxor
718         ldi r16, 31
719 1:
720         dec r16
721         movw r24, r14
722         rcall serpent_inv_lt
723         movw r24, r14
724         mov r22, r16
725         rcall inv_sbox128
726         movw r24, r14
727         ldi r20, 16
728         sub r12, r20
729         sbc r13, r1
730         movw r22, r12
731         clr r21
732         rcall memxor
733         
734         tst r16
735         brne 1b
736         pop_ r16, r15, r14, r13, r12
737         ret     
738         
739         
740         
741
742
743
744
745
746
747
748
749
750
751
752
753
754