]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bmw/bmw_small-tinyasm.S
further shrinked bmw tiny to 1750 bytes
[avr-crypto-lib.git] / bmw / bmw_small-tinyasm.S
1 /* bmw_small-tinyasm.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 /*
21  * File:        bmw_small-tinyasm.S
22  * Author:      Daniel Otte
23  * Date:        2010-03-28
24  * License:     GPLv3 or later
25  * Description: implementation of BlueMidnightWish
26  *
27  */
28
29 #include "avr-asm-macros.S"
30
31 /******************************************************************************/
32 /*
33   param a: r22:r23:r24:r25
34   param s: r20
35 */
36 shiftleft32:
37         clr r0
38         cpi r20, 8
39         brlo bitrotateleft_1
40         mov r25, r24
41         mov r24, r23
42         mov r23, r22
43         clr r22
44         subi r20, 8
45         rjmp shiftleft32
46
47 /******************************************************************************/
48 /*
49   param a: r22:r23:r24:r25
50   param s: r20
51 */
52 shiftright32:
53         cpi r20, 8
54         brlo bitshiftright
55         mov r22, r23
56         mov r23, r24
57         mov r24, r25
58         clr r25
59         subi r20, 8
60         rjmp shiftright32
61 bitshiftright:
62         tst r20
63         breq 20f
64 10:     lsr r25
65         ror r24
66         ror r23
67         ror r22
68         dec r20
69         brne 10b
70 20: ret
71
72 /******************************************************************************/
73 /*
74   param a: r22:r23:r24:r25
75   param s: r20
76 */
77 rotateleft32:
78         cpi r20, 8
79         brlo bitrotateleft
80         mov r0, r25
81         mov r25, r24
82         mov r24, r23
83         mov r23, r22
84         mov r22, r0
85         subi r20, 8
86         rjmp rotateleft32
87 bitrotateleft:
88     mov r0, r25
89 bitrotateleft_1:
90         tst r20
91         breq 20f
92 10:
93         lsl r0
94         rol r22
95         rol r23
96         rol r24
97         rol r25
98         dec r20
99         brne 10b
100 20: ret
101
102
103 /******************************************************************************/
104
105 s_table:
106 s0:  .byte 1, 3, 4,19
107 s1:  .byte 1, 2, 8,23
108 s2:  .byte 2, 1,12,25
109 s3:  .byte 2, 2,15,29
110 s4:  .byte 1, 0, 0, 0
111 s5:  .byte 2, 0, 0, 0
112 /*
113 s0:  .byte 0x34, 19
114 s1:  .byte 0x28, 23
115 s2:  .byte 0x9C, 25
116 s3:  .byte 0xAF, 29
117 s4:  .byte 0x00,  0
118 s5:  .byte 0x80,  0
119 */
120 acc2 =  8
121 acc3 =  9
122 h0   = 10
123 h1   = 11
124 m0   = 12
125 m1   = 13
126 acc0 = 14
127 acc1 = 15
128
129 /*
130   param x: r22:r23:r24:25
131   param s: r20
132 */
133 sn:
134         push_range 2, 5
135         push acc0
136         push acc1
137         push acc2
138         push acc3
139         ldi r30, lo8(s_table)
140         ldi r31, hi8(s_table)
141         lsl r20
142         lsl r20
143         add r30, r20
144         adc r31, r1
145         movw r2, r22
146         movw r4, r24
147         lpm r20, Z+
148         rcall shiftright32
149         movw acc0, r22
150         movw acc2, r24
151 ;---
152         movw r22, r2
153         movw r24, r4
154         lpm r20, Z+
155         rcall shiftleft32
156         rcall eor32_to_acc
157 ;---
158         movw r22, r2
159         movw r24, r4
160         lpm r20, Z+
161         rcall rotateleft32
162         rcall eor32_to_acc
163 ;---
164         movw r22, r2
165         movw r24, r4
166         lpm r20, Z+
167         rcall rotateleft32
168         rcall eor32_to_acc
169         movw r22, acc0
170         movw r24, acc2
171         pop acc3
172         pop acc2
173         pop acc1
174         pop acc0
175         pop_range 2, 5
176         ret
177
178 /******************************************************************************/
179 /*
180   param dest: r26:r27 (X)
181   param src:  r30:r31 (Z)
182   param len:  r20
183 */
184 memxor_short:
185 ;       tst r20
186 ;       breq memxor_exit
187         ldi r20, 64
188 10: ld r21, X
189         ld r22, Z+
190         eor r21, r22
191         st X+, r21
192         dec r20
193         brne 10b
194 memxor_exit:
195         ret
196
197 /******************************************************************************/
198 q0 = 2
199 q1 = 3
200 h0 = 4
201 h1 = 5
202 m0 = 6
203 m1 = 7
204
205
206 /******************************************************************************/
207 load32_from_X:
208         ld r22, X+
209         ld r23, X+
210         ld r24, X+
211         ld r25, X+
212         ret
213
214 load32_from_Y:
215         ld r22, Y+
216         ld r23, Y+
217         ld r24, Y+
218         ld r25, Y+
219         ret
220
221 store32_to_Y:
222         st Y+, r22
223         st Y+, r23
224         st Y+, r24
225         st Y+, r25
226         ret
227
228 add_X_to_32:
229         ld r0, X+
230         add r22, r0
231         ld r0, X+
232         adc r23, r0
233         ld r0, X+
234         adc r24, r0
235         ld r0, X+
236         adc r25, r0
237         ret
238
239 store_acc_to_dec_X:
240         st -X, acc3
241         st -X, acc2
242         st -X, acc1
243         st -X, acc0
244         ret
245
246 store32_to_X:
247         st X+, r22
248         st X+, r23
249         st X+, r24
250         st X+, r25
251         ret
252
253 /******************************************************************************/
254 /*
255   param q:  r28:r29 (Y)
256   param h:  r26:r27 (X)
257   param m:  r30:r31 (Z)
258 */
259
260 f0_hacktable:
261         .byte 0x03, 0x11, 5*4
262         .byte 0xDD, 0xB3, 7*4
263         .byte 0x2A, 0x79, 10*4
264         .byte 0x07, 0xAA, 13*4
265         .byte 0x51, 0xC2, 14*4
266         .byte 0 ; just for alignment
267
268
269 /*******************************************************************************
270 * uint32_t addelment(uint8_t j, const uint32_t* m, const uint32_t* h){
271 *       uint32_t r;
272 *       r  = pgm_read_dword(k_lut+j);
273 *       r += rotl_addel(((uint32_t*)m)[j&0xf], j+0);
274 *       r += rotl_addel(((uint32_t*)m)[(j+3)&0xf], j+3);
275 *       r -= rotl_addel(((uint32_t*)m)[(j+10)&0xf], j+10);
276 *       r ^= ((uint32_t*)h)[(j+7)&0xf];
277 *       return r;
278 * }
279 * param j: r24
280 * param m: r22:r23
281 * param h: r20:r21
282 */
283 j    = 16
284 acc2 =  8
285 acc3 =  9
286 h0   = 10
287 h1   = 11
288 m0   = 12
289 m1   = 13
290 acc0 = 14
291 acc1 = 15
292
293 add32_to_acc:
294         add acc0, r22
295         adc acc1, r23
296         adc acc2, r24
297         adc acc3, r25
298         ret
299
300 eor32_to_acc:
301         eor acc0, r22
302         eor acc1, r23
303         eor acc2, r24
304         eor acc3, r25
305         ret
306
307 load_acc_from_X:
308         ld acc0, X+
309         ld acc1, X+
310         ld acc2, X+
311         ld acc3, X+
312         ret
313
314 add_acc_to_Z:
315         ld r0, Z
316         add r0, acc0
317         st Z+, r0
318         ld r0, Z
319         adc r0, acc1
320         st Z+, r0
321         ld r0, Z
322         adc r0, acc2
323         st Z+, r0
324         ld r0, Z
325         adc r0, acc3
326         st Z+, r0
327         ret
328
329 load_rotate_add_M:
330         andi r20, 0x0f
331         mov r0, r20
332         lsl r0
333         lsl r0
334         movw r26, m0
335         add r26, r0
336         adc r27, r1
337         rcall load32_from_X
338         inc r20
339         rcall rotateleft32
340         brts 10f
341         rjmp add32_to_acc
342 ;       ret
343 10:     sub acc0, r22
344         sbc acc1, r23
345         sbc acc2, r24
346         sbc acc3, r25
347         ret
348
349 addelement:
350         mov j, r24
351         movw h0, r20
352         movw m0, r22
353         sbiw r26, 4
354         rcall load_acc_from_X
355         ldi r24, 0x55
356         add acc0, r24
357         adc acc1, r24
358         adc acc2, r24
359         ldi r24, 5
360         adc acc3, r24
361         rcall store_acc_to_dec_X
362         adiw r26, 4
363         clt
364         mov r20, j
365         rcall load_rotate_add_M
366         mov r20, j
367         subi r20, -3
368         rcall load_rotate_add_M
369         mov r20, j
370         set
371         subi r20, -10
372         rcall load_rotate_add_M
373         lsl j
374         lsl j
375         subi j, -7*4
376         andi j, 0x3f
377         movw r26, h0
378         add r26, j
379         adc r27, r1
380         rcall load32_from_X
381         rcall eor32_to_acc
382 ;---
383         ret
384
385 /******************************************************************************/
386 load_sn_add:
387         rcall load32_from_X
388         rcall sn
389         rjmp add32_to_acc
390 ;       ret
391
392 /*
393   param q: r26:r27
394   param m: r22:r23
395   param h: r20:r21
396   param j: r24
397 */
398
399 expand_intro:
400
401         push_range 26, 27
402         push r24
403         rcall addelement
404         pop r24
405         pop_range 26, 27
406         lsl r24
407         lsl r24
408         add r26, r24
409         adc r27, r1
410         ret
411 expand1:
412         rcall expand_intro
413         ldi r19, 1
414 10:
415         mov r20, r19
416         andi r20, 3
417         rcall load_sn_add
418         inc r19
419         cpi r19, 17
420         brne 10b
421         rjmp expand2_exit
422
423
424 /******************************************************************************/
425 /*
426   param q: r26:r27
427   param m: r22:r23
428   param h: r20:r21
429   param j: r24
430 */
431
432 f2_1_shift_table:
433         .byte 0x2B, 0x64, 0x66, 0x03, 0x51, 0x55, 0x87, 0x55
434 f2_2_shift_table:
435         .byte (2<<1), (7<<1), (4<<1), (3<<1), (4<<1)+1, (6<<1)+1, (6<<1)
436
437 expand2_rot_table:
438         .byte 3,7,13,16,19,23,27
439 ;       .byte 0 ; just for alignment
440
441 expand2:
442         rcall expand_intro
443         ldi r19, 14
444         ldi r30, lo8(expand2_rot_table)
445         ldi r31, hi8(expand2_rot_table)
446 10:
447         rcall load32_from_X
448         sbrs r19, 0
449         rjmp 12f
450         lpm r20, Z+
451         rcall rotateleft32
452 12:     rcall add32_to_acc
453         dec r19
454         brne 10b
455         ldi r20, 4
456         rcall load_sn_add
457         ldi r20, 5
458         rcall load_sn_add
459 expand2_exit:
460         adiw r26, 4
461         rjmp store_acc_to_dec_X
462 ;       ret
463
464 /******************************************************************************/
465 /*
466   param q: r24:r25
467   param m: r22:r23
468   param h: r20:r21
469 */
470 /* for calling expand1/2
471   param q: r26:r27
472   param m: r22:r23
473   param h: r20:r21
474   param j: r24
475 */
476
477 /******************************************************************************/
478 /*
479   param q: r24:r25
480   param m: r22:r23
481   param h: r20:r21
482 */
483
484 /******************************************************************************/
485 /*
486   param ctx:  r24:r25
487   param msg:  r22:r23
488 */
489 /* f0
490   param q:  r28:r29 (Y)
491   param h:  r26:r27 (X)
492   param m:  r30:r31 (Z)
493 */
494 /* f1
495   param q: r24:r25
496   param m: r22:r23
497   param h: r20:r21
498 */
499 /* f2
500   param q: r24:r25
501   param m: r22:r23
502   param h: r20:r21
503 */
504 q0 = 2
505 q1 = 3
506 h0 = 4
507 h1 = 5
508 m0 = 6
509 m1 = 7
510
511
512 .global bmw_small_nextBlock
513 .global bmw224_nextBlock
514 .global bmw256_nextBlock
515 bmw_small_nextBlock:
516 bmw224_nextBlock:
517 bmw256_nextBlock:
518         push_range 28, 29
519         push_range  2, 17
520         stack_alloc_large 32*4, r28, r29
521         ldi r16, 0x4f
522         push r16
523         ldi r16, 0xff
524         push r16
525         push r16
526         ldi r16, 0xfb
527         push r16
528         adiw r28, 1
529 ;       push_range 28, 29 /* push Q */
530 ;       push_range 22, 25 /* push M & H */
531         /* increment counter */
532         movw r26, r24
533         movw r2, r26
534         adiw r26, 63
535         adiw r26,  1
536         rcall load_acc_from_X
537         ldi r19, 1
538         add acc0, r19
539         adc acc1, r1
540         adc acc2, r1
541         adc acc3, r1
542         rcall store_acc_to_dec_X
543         /* call f0 */
544         movw r30, r22
545         movw r26, r24
546 f0:
547         movw h0, r26
548         movw q0, r28
549         movw m0, r30
550         /* xor m into h */
551 ;       ldi r20, 64
552         rcall memxor_short
553         movw r30, m0
554         movw r26, h0
555
556         /* set q to zero */
557         ldi r22, 64
558 10:     st Y+, r1
559         dec r22
560         brne 10b
561         movw r28, q0
562         /* calculate W and store it in Q */
563         ldi r19, 5
564 30:
565         ldi r18, 16
566         /* load initial index */
567
568         /* load values from hacktable */
569         ldi r30, lo8(f0_hacktable-3)
570         ldi r31, hi8(f0_hacktable-3)
571         mov r16, r19
572         lsl r16
573         add r16, r19
574         add r30, r16
575         adc r31, r1
576         lpm r21, Z+
577         lpm r20, Z+
578         lpm r16, Z+
579 40:
580         ;call add_hx_to_w
581 add_hx_to_w:
582         movw r26, h0
583         add r26, r16
584         adc r27, r1
585         rcall load32_from_Y
586         sbiw r28, 4
587         lsl r20
588         rol r21
589         brcs 300f
590         /* addition */
591         rcall add_X_to_32
592         rjmp 500f
593 300: /* substract */
594         rcall load_acc_from_X
595         sub r22, acc0
596         sbc r23, acc1
597         sbc r24, acc2
598         sbc r25, acc3
599
600 500:
601         rcall store32_to_Y
602         subi r16, -4
603         andi r16, 0x0f<<2
604         dec r18
605         brne 40b
606         movw r28, q0
607         dec r19
608         brne 30b
609         movw r26, h0
610         /* xor m into h */
611 ;       ldi r20, 64
612         movw r26, h0
613         movw r30, m0
614         rcall memxor_short
615         sbiw r26, 60
616 ;---
617         clr r17
618         ldi r21, 15
619         mov r8, r21
620 50:
621         rcall load32_from_Y
622         sbiw r28, 4
623         mov r20, r17
624         rcall sn
625         inc r17
626         cpi r17, 5
627         brne 52f
628         clr r17
629 52:
630         rcall add_X_to_32
631         rcall store32_to_Y
632
633         dec r8
634         brne 50b
635 ;---
636         rcall load32_from_Y
637         clr r20
638         rcall sn
639         movw r26, h0
640         rcall add_X_to_32
641         sbiw r26, 4
642         sbiw r28, 4
643         rcall store32_to_Y
644         sbiw r28, 4
645         sbiw r28, 15*4
646         movw r20, h0
647         movw r22, m0
648
649         /* call f1*/
650         movw r2, r28
651 f1:
652         movw r4, r22
653         movw r6, r20
654         movw r26, r2
655         clr r24
656         rcall expand1
657         movw r26, r2
658         movw r22, r4
659     movw r20, r6
660         ldi r24, 1
661         rcall expand1
662         ldi r17, 2
663 10:     movw r26, r2
664         movw r22, r4
665         movw r20, r6
666         mov r24, r17
667         rcall expand2
668         inc r17
669         sbrs r17, 4
670         rjmp 10b
671         movw r24, r2
672         movw r22, r4
673         movw r20, r6
674
675
676         /* call f2 */
677 ;       pop_range 20, 25
678 ;       push_range 20, 25
679 ;       rcall printQ
680 ;       push r20
681 ;       push r21
682 acc2  =  8
683 acc3  =  9
684 acc0  = 14
685 acc1  = 15
686 xl0   =  2
687 xl1   =  3
688 xl2   =  4
689 xl3   =  5
690 xh0   =  6
691 xh1   =  7
692 xh2   = 10
693 xh3   = 11
694 q16_0 = 12
695 q16_1 = 13
696 h0   =  18
697 h1   =  19
698 f2:
699         movw r26, r24
700         /* calc XL */
701         adiw r26, 63
702         adiw r26,  1
703         movw q16_0, r26
704         movw h0, r20
705         movw r28, r22
706         rcall load32_from_X
707         movw acc0, r22
708         movw acc2, r24
709         ldi r17, 15
710 10:     rcall load32_from_X
711         rcall eor32_to_acc
712         cpi r17, 9
713         brne 15f
714         movw xl0, acc0
715         movw xl2, acc2
716 15:
717         dec r17
718         brne 10b
719         movw xh0, acc0
720         movw xh2, acc2
721 ;--- DBG
722 ;       push_range 22, 25
723 ;       movw r22, xl0
724 ;       movw r24, xl2
725 ;       rcall print32
726 ;       movw r22, xh0
727 ;       movw r24, xh2
728 ;       rcall print32
729 ;       pop_range 22, 25
730 ;--- END DBG
731
732 ;--- /* calc first half of h0..h15 */
733         movw r26, q16_0
734         ldi r17, 16
735 10:
736         ld acc0, Y+
737         ld acc1, Y+
738         ld acc2, Y+
739         ld acc3, Y+
740 ;---
741         movw r22, xh0
742         movw r24, xh2
743         cpi r17, 9
744         brge 15f
745         clr r1
746         rjmp 26f
747 15:     ldi r30, lo8(f2_1_shift_table-9)
748         ldi r31, hi8(f2_1_shift_table-9)
749         add r30, r17
750         adc r31, r1
751         lpm r20, Z
752         mov r1, r20
753         andi r20, 0x0f
754         clt
755         cpi r17, 16
756         breq 20f
757         cpi r17, 11
758         brne 21f
759 20:     set
760 21:     brts 25f
761         rcall shiftright32
762         rjmp 26f
763 25:     rcall shiftleft32
764 26: rcall eor32_to_acc
765 ;---
766         rcall load32_from_X
767         mov r20, r1
768         clr r1
769         swap r20
770         andi r20, 0x0f
771         brts 27f
772         rcall shiftleft32
773         rjmp 28f
774 27:     rcall shiftright32
775 28:     rcall eor32_to_acc
776 ;---
777         movw r30, h0
778         st Z+, acc0
779         st Z+, acc1
780         st Z+, acc2
781         st Z+, acc3
782         movw h0, r30
783 ;---
784         dec r17
785         brne 10b
786 ;-----
787         sbiw r26, 4*8 /* X points to q[24] */
788         movw r28, r26
789         sbiw r28, 63
790         sbiw r28, 33 /* Y points to q[0] */
791         sbiw r30, 63
792         sbiw r30,  1 /* Z points to h0 */
793         ldi r17, 8
794 10:     movw acc0, xl0
795         movw acc2, xl2
796         rcall load32_from_X
797         rcall eor32_to_acc
798         rcall load32_from_Y
799         rcall eor32_to_acc
800         rcall add_acc_to_Z
801         dec r17
802         brne 10b
803         sbiw r26, 9*4 /* X points to q[23] */
804         rcall load_acc_from_X
805         eor acc1, xl0
806         eor acc2, xl1
807         eor acc3, xl2
808         rcall load32_from_Y
809         rcall eor32_to_acc
810         rcall add_acc_to_Z
811 ;---
812         sbiw r26, 8*4 /* X points to q[16] */
813         mov h0, r30
814         ldi r17, 7
815 10:
816         ldi r30, lo8(f2_2_shift_table-1)
817         ldi r31, hi8(f2_2_shift_table-1)
818         add r30, r17
819         adc r31, r1
820         lpm r20, Z
821         rcall load_acc_from_X
822         movw r22, xl0
823         movw r24, xl2
824         lsr r20
825         brcc 20f
826         rcall shiftleft32
827         rjmp 21f
828 20:     rcall shiftright32
829 21:
830         rcall eor32_to_acc
831         rcall load32_from_Y
832         rcall eor32_to_acc
833         movw r30, h0
834         rcall add_acc_to_Z
835         movw h0, r30
836         dec r17
837         brne 10b
838 ;-----
839         sbiw r30, 8*4 /* Z points to h8 */
840         movw r26, r30
841         sbiw r26, 4*4 /* X points to h4 */
842         ldi r17, 8
843         ldi r18, 9
844 10:
845         rcall load32_from_X
846         mov r20, r18
847         rcall rotateleft32
848         movw acc0, r22
849         movw acc2, r24
850         rcall add_acc_to_Z
851         inc r18
852         cpi r17, 5
853         brne 20f
854         sbiw r26, 8*4
855 20:     dec r17
856         brne 10b
857
858 ;--- DBG
859 ;       pop r25
860 ;       pop r24
861 ;       ldi r22, 'H'
862 ;       rcall printX
863 ;--- END DBG
864         stack_free_large3 32*4+4
865         pop_range  2, 17
866         pop_range 28, 29
867         ret
868
869 /******************************************************************************/
870 ctx0 =  2
871 ctx1 =  3
872 blc0 =  4
873 blc1 =  5
874 len0 = 28
875 len1 = 29
876 buf0 =  6
877 buf1 =  7
878
879 load32_from_Z_stub:
880         movw r30, ctx0
881         adiw r30, 60
882         ldd r21, Z+4
883         ldd r22, Z+5
884         ldd r23, Z+6
885         ldd r24, Z+7
886         ret
887
888 /******************************************************************************/
889 /*
890   param ctx:  r24:r25
891   param msg:  r22:r23
892   param len:  r20:r21
893 */
894
895 .global bmw_small_lastBlock
896 .global bmw224_lastBlock
897 .global bmw256_lastBlock
898 bmw_small_lastBlock:
899 bmw224_lastBlock:
900 bmw256_lastBlock:
901 /*      while(length_b >= BMW_SMALL_BLOCKSIZE){
902                 bmw_small_nextBlock(ctx, block);
903                 length_b -= BMW_SMALL_BLOCKSIZE;
904                 block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
905         }
906 */
907         push_range 2, 7
908         push_range 28, 29
909         movw ctx0, r24
910         movw blc0, r22
911         movw len0, r20
912 1:
913         cpi len1, hi8(512)
914         brlo 2f
915         movw r24, ctx0
916         movw r22, blc0
917         rcall bmw_small_nextBlock
918         ldi r24, 64
919         add blc0, r24
920         adc blc1, r1
921         subi len1, hi8(512)
922         rjmp 1b
923 2:
924 /*      struct {
925                 uint8_t  buffer[64];
926                 uint32_t ctr;
927         } pctx;
928 */
929         stack_alloc_large 68
930         adiw r30, 1
931         movw buf0, r30
932 /*      memset(pctx.buffer, 0, 64);
933         memcpy(pctx.buffer, block, (length_b+7)/8);
934         pctx.buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
935 */      movw r24, len0
936         ldi r23, 63
937         movw r26, blc0
938         lsr r25
939         ror r24
940         lsr r24
941         lsr r24
942         breq 301f
943         sub r23, r24
944         /* copy (#r24) bytes to stack buffer */
945 30: ld r20, X+
946         st Z+, r20
947         dec r24
948         brne 30b
949 301: /* calculate the appended byte */
950         clr r20
951         mov r21, len0
952         ldi r24, 0x80
953         andi r21, 0x07
954         breq 305f
955         ld r20, X+
956 303:
957         lsr r24
958         dec r21
959         brne 303b
960 305:
961         or r20, r24
962         st Z+, r20
963         tst r23
964         breq 32f
965 31: st Z+, r1
966         dec r23
967         brne 31b
968 32:
969 /*      if(length_b+1>64*8-64){ ; = 64*7-1 = 447 max(length_b)=511
970                 bmw_small_nextBlock(ctx, pctx.buffer);
971                 memset(pctx.buffer, 0, 64-8);
972                 ctx->counter -= 1;
973         }
974 */
975         tst len1
976         breq 400f
977         cpi len0, 192
978         brlo 400f
979         movw r24, ctx0
980         movw r22, buf0
981         rcall bmw_small_nextBlock
982         movw r26, buf0
983         ldi r20, 64-8
984 350:
985         st X+, r1
986         dec r20
987         brne 350b
988         rcall load32_from_Z_stub
989         subi r21, 1
990         sbc r22, r1
991         sbc r23, r1
992         sbc r24, r1
993         rjmp 410f
994 /*      *((uint64_t*)&(pctx.buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
995         bmw_small_nextBlock(ctx, pctx.buffer);
996 */
997 400:
998         rcall load32_from_Z_stub
999 410:
1000         clr r25
1001         lsl r21
1002         rol r22
1003         rol r23
1004         rol r24
1005         rol r25
1006         mov r20, len0
1007         add r21, len1
1008         adc r22, r1
1009         adc r23, r1
1010         adc r24, r1
1011         adc r25, r1
1012         movw r30, buf0
1013         adiw r30, 64-8
1014         st Z+, r20
1015         st Z+, r21
1016         st Z+, r22
1017         st Z+, r23
1018         st Z+, r24
1019         st Z+, r25
1020         st Z+, r1
1021         st Z+, r1
1022         movw r24, ctx0
1023         movw r22, buf0
1024         rcall bmw_small_nextBlock
1025 /*      memset(pctx.buffer, 0xaa, 64);
1026         for(i=0; i<16;++i){
1027                 pctx.buffer[i*4] = i+0xa0;
1028         }
1029 */
1030         ldi r22, 0xa0
1031         ldi r23, 0xaa
1032         ldi r24, 0xaa
1033         ldi r25, 0xaa
1034         movw r26, buf0
1035 500:
1036         rcall store32_to_X
1037         inc r22
1038         sbrs r22, 4
1039         rjmp 500b
1040 /*      bmw_small_nextBlock((bmw_small_ctx_t*)&pctx, ctx->h);
1041         memcpy(ctx->h, pctx.buffer, 64);
1042 */
1043         movw r24, buf0
1044         movw r22, ctx0
1045         rcall bmw_small_nextBlock
1046         ldi r18, 64
1047         movw r26, ctx0
1048         movw r30, buf0
1049 600:
1050         ld r20, Z+
1051         st X+, r20
1052         dec r18
1053         brne 600b
1054
1055         stack_free_large 68
1056         pop_range 28, 29
1057         pop_range 2, 7
1058         ret
1059
1060
1061 /*******************************************************************************
1062 * void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
1063 *       memcpy(dest, &(ctx->h[9]), 224/8);
1064 * }
1065 *
1066 * param dest:  r24:r25
1067 * param ctx:   r22:r23
1068 */
1069 .global bmw224_ctx2hash
1070 bmw224_ctx2hash:
1071         movw r26, r24
1072         movw r30, r22
1073         adiw r30, 9*4
1074         ldi r22, 28
1075         rjmp 1f
1076
1077 /*******************************************************************************
1078 * void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
1079 *       memcpy(dest, &(ctx->h[8]), 256/8);
1080 * }
1081 *
1082 * param dest:  r24:r25
1083 * param ctx:   r22:r23
1084 */
1085 .global bmw256_ctx2hash
1086 bmw256_ctx2hash:
1087         movw r26, r24
1088         movw r30, r22
1089         adiw r30, 8*4
1090         ldi r22, 32
1091 1:
1092         ld r23, Z+
1093         st X+, r23
1094         dec r22
1095         brne 1b
1096         ret
1097
1098 /*******************************************************************************
1099 * void bmw256(void* dest, const void* msg, uint32_t length_b){
1100 *       bmw_small_ctx_t ctx;
1101 *       bmw256_init(&ctx);
1102 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1103 *               bmw_small_nextBlock(&ctx, msg);
1104 *               length_b -= BMW_SMALL_BLOCKSIZE;
1105 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1106 *       }
1107 *       bmw_small_lastBlock(&ctx, msg, length_b);
1108 *       bmw256_ctx2hash(dest, &ctx);
1109 * }
1110 *
1111 * param dest:     r24:r25
1112 * param msg:      r22:r23
1113 * param length_b: r18:r21
1114 */
1115 ctx0 =   2
1116 ctx1 =   3
1117 msg0 =   4
1118 msg1 =   5
1119 len0 =   6
1120 len1 =   7
1121 len2 =   8
1122 len3 =   9
1123 dst0 =  10
1124 dst1 =  11
1125 .global bmw256
1126 bmw256:
1127         push r16
1128         ldi r16, 1
1129         rjmp bmw_small_all
1130
1131 /*******************************************************************************
1132 * void bmw224(void* dest, const void* msg, uint32_t length_b){
1133 *       bmw_small_ctx_t ctx;
1134 *       bmw224_init(&ctx);
1135 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1136 *               bmw_small_nextBlock(&ctx, msg);
1137 *               length_b -= BMW_SMALL_BLOCKSIZE;
1138 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1139 *       }
1140 *       bmw_small_lastBlock(&ctx, msg, length_b);
1141 *       bmw224_ctx2hash(dest, &ctx);
1142 * }
1143 *
1144 * param dest:     r24:r25
1145 * param msg:      r22:r23
1146 * param length_b: r18:r21
1147 */
1148 ctx0 =   2
1149 ctx1 =   3
1150 msg0 =   4
1151 msg1 =   5
1152 len0 =  28
1153 len1 =  29
1154 len2 =   8
1155 len3 =   9
1156 dst0 =   6
1157 dst1 =   7
1158 .global bmw224
1159 bmw224:
1160         push r16
1161         clr r16
1162
1163 bmw_small_all:
1164         push_range 2, 9
1165         push_range 28, 29
1166         stack_alloc_large 64+4
1167         adiw r30, 1
1168         movw ctx0, r30
1169         movw dst0, r24
1170         movw msg0, r22
1171         movw len0, r18
1172         movw len2, r20
1173         movw r24, ctx0
1174         ldi r30, pm_lo8(init_lut)
1175         ldi r31, pm_hi8(init_lut)
1176         add r30, r16
1177         adc r31, r1
1178         icall
1179 20:
1180         mov r18, len2
1181         or  r18, len3
1182         breq 50f
1183         movw r24, ctx0
1184         movw r22, msg0
1185         rcall bmw_small_nextBlock
1186         subi len1, 2
1187         sbc len2, r1
1188         sbc len3, r1
1189         ldi r20, 64
1190         add msg0, r20
1191         adc msg1, r1
1192         rjmp 20b
1193 50:
1194         movw r24, ctx0
1195         movw r22, msg0
1196         movw r20, len0
1197         rcall bmw_small_lastBlock
1198         movw r24, dst0
1199         movw r22, ctx0
1200         ldi r30, pm_lo8(c2h_lut)
1201         ldi r31, pm_hi8(c2h_lut)
1202         add r30, r16
1203         adc r31, r1
1204         icall
1205         stack_free_large 64+4
1206         pop_range 28, 29
1207         pop_range 2, 9
1208         pop r16
1209         ret
1210
1211 init_lut:
1212         rjmp bmw224_init
1213         rjmp bmw256_init
1214 c2h_lut:
1215         rjmp bmw224_ctx2hash
1216         rjmp bmw256_ctx2hash
1217
1218 /*******************************************************************************
1219 * void bmw224_init(bmw224_ctx_t* ctx){
1220 *       uint8_t i;
1221 *       ctx->h[0] = 0x00010203;
1222 *       for(i=1; i<16; ++i){
1223 *               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
1224 *       }
1225 *       ctx->counter=0;
1226 * }
1227 *
1228 * param ctx:  r24:r25
1229 */
1230 .global bmw224_init
1231 bmw224_init:
1232         movw r26, r24
1233         ldi r22, 0x03
1234         ldi r23, 0x02
1235         ldi r24, 0x01
1236         ldi r25, 0x00
1237 bmw_small_init:
1238         rcall store32_to_X
1239         ldi r18, 16-1
1240         ldi r20, 0x04
1241 1:
1242         add r22, r20
1243         adc r23, r20
1244         adc r24, r20
1245         adc r25, r20
1246         rcall store32_to_X
1247         dec r18
1248         brne 1b
1249         st X+, r1
1250         st X+, r1
1251         st X+, r1
1252         st X+, r1
1253         ret
1254
1255 .global bmw256_init
1256 bmw256_init:
1257         movw r26, r24
1258         ldi r22, 0x43
1259         ldi r23, 0x42
1260         ldi r24, 0x41
1261         ldi r25, 0x40
1262         rjmp bmw_small_init
1263
1264
1265 /******************************************************************************/
1266
1267 #if DEBUG
1268
1269 printQ:
1270         push_range 20, 25
1271         ldi r16, 4
1272         mov r9, r16
1273         movw r16, r24
1274         ldi r24, lo8(qdbg_str)
1275         ldi r25, hi8(qdbg_str)
1276         call cli_putstr_P
1277         clr r8
1278 10:     ldi r24, lo8(qdbg_str1)
1279         ldi r25, hi8(qdbg_str1)
1280         call cli_putstr_P
1281         mov r24, r8
1282         call cli_hexdump_byte
1283         ldi r24, lo8(qdbg_str2)
1284         ldi r25, hi8(qdbg_str2)
1285         call cli_putstr_P
1286         movw r24, r16
1287         clr r23
1288         ldi r22, 4
1289         call cli_hexdump_rev
1290         add r16, r9
1291         adc r17, r1
1292         inc r8
1293         sbrs r8, 5
1294         rjmp 10b
1295         pop_range 20, 25
1296         ret
1297 qdbg_str:  .asciz "\r\nDBG Q: "
1298 qdbg_str1: .asciz "\r\n Q["
1299 qdbg_str2: .asciz "] =  "
1300
1301
1302 printX:
1303         push_range 6, 9
1304         push_range 16, 27
1305         push_range 30, 31
1306         ldi r16, 4
1307         mov r6, r22
1308         mov r9, r16
1309         movw r16, r24
1310         ldi r24, lo8(Xdbg_str)
1311         ldi r25, hi8(Xdbg_str)
1312         call cli_putstr_P
1313         mov r24, r6
1314         call cli_putc
1315         ldi r24, ':'
1316         call cli_putc
1317         clr r8
1318 10:     ldi r24, lo8(Xdbg_str1)
1319         ldi r25, hi8(Xdbg_str1)
1320         call cli_putstr_P
1321         mov r24, r6
1322         call cli_putc
1323         ldi r24, '['
1324         call cli_putc
1325         mov r24, r8
1326         call cli_hexdump_byte
1327         ldi r24, lo8(Xdbg_str2)
1328         ldi r25, hi8(Xdbg_str2)
1329         call cli_putstr_P
1330         movw r24, r16
1331         clr r23
1332         ldi r22, 4
1333         call cli_hexdump_rev
1334         add r16, r9
1335         adc r17, r1
1336         inc r8
1337         sbrs r8, 4
1338         rjmp 10b
1339         pop_range 30, 31
1340         pop_range 16, 27
1341         pop_range 6, 9
1342         ret
1343 Xdbg_str:  .asciz "\r\nDBG "
1344 Xdbg_str1: .asciz "\r\n "
1345 Xdbg_str2: .asciz "] = "
1346
1347 print32:
1348         push_range 6, 9
1349         push_range 16, 27
1350         push_range 30, 31
1351         movw r6, r22
1352         movw r8, r24
1353         ldi r24, lo8(Xdbg_str)
1354         ldi r25, hi8(Xdbg_str)
1355         call cli_putstr_P
1356         mov r24, r9
1357         call cli_hexdump_byte
1358         mov r24, r8
1359         call cli_hexdump_byte
1360         mov r24, r7
1361         call cli_hexdump_byte
1362         mov r24, r6
1363         call cli_hexdump_byte
1364         pop_range 30, 31
1365         pop_range 16, 27
1366         pop_range 6, 9
1367         ret
1368
1369
1370 print_acc:
1371         push_range 16, 27
1372         push_range 30, 31
1373         ldi r24, lo8(Xdbg_str)
1374         ldi r25, hi8(Xdbg_str)
1375         call cli_putstr_P
1376         mov r24, r9
1377         call cli_hexdump_byte
1378         mov r24, r8
1379         call cli_hexdump_byte
1380         mov r24, r15
1381         call cli_hexdump_byte
1382         mov r24, r14
1383         call cli_hexdump_byte
1384         pop_range 30, 31
1385         pop_range 16, 27
1386         ret
1387
1388 #endif
1389