]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bmw/bmw_small-tinyasm.S
further shrinked bmw tiny to 1778 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         rcall 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         rcall 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         push_range 20, 27
401 ;       push r24
402         rcall addelement
403 ;       pop r24
404         pop_range 20, 27
405         lsl r24
406         lsl r24
407         add r26, r24
408         adc r27, r1
409         ret
410 expand1:
411         rcall expand_intro
412         ldi r19, 1
413 10:
414         mov r20, r19
415         andi r20, 3
416         rcall load_sn_add
417         inc r19
418         cpi r19, 17
419         brne 10b
420         rjmp expand2_exit
421
422
423 /******************************************************************************/
424 /*
425   param q: r26:r27
426   param m: r22:r23
427   param h: r20:r21
428   param j: r24
429 */
430
431 f2_1_shift_table:
432         .byte 0x2B, 0x64, 0x66, 0x03, 0x51, 0x55, 0x87, 0x55
433 f2_2_shift_table:
434         .byte (2<<1), (7<<1), (4<<1), (3<<1), (4<<1)+1, (6<<1)+1, (6<<1)
435
436 expand2_rot_table:
437         .byte 3,7,13,16,19,23,27
438 ;       .byte 0 ; just for alignment
439
440 expand2:
441         rcall expand_intro
442         ldi r19, 14
443         ldi r30, lo8(expand2_rot_table)
444         ldi r31, hi8(expand2_rot_table)
445 10:
446         rcall load32_from_X
447         sbrs r19, 0
448         rjmp 12f
449         lpm r20, Z+
450         rcall rotateleft32
451 12:     rcall add32_to_acc
452         dec r19
453         brne 10b
454         ldi r20, 4
455         rcall load_sn_add
456         ldi r20, 5
457         rcall load_sn_add
458 expand2_exit:
459         adiw r26, 4
460         rcall store_acc_to_dec_X
461         ret
462
463 /******************************************************************************/
464 /*
465   param q: r24:r25
466   param m: r22:r23
467   param h: r20:r21
468 */
469 /* for calling expand1/2
470   param q: r26:r27
471   param m: r22:r23
472   param h: r20:r21
473   param j: r24
474 */
475
476 /******************************************************************************/
477 /*
478   param q: r24:r25
479   param m: r22:r23
480   param h: r20:r21
481 */
482
483 /******************************************************************************/
484 /*
485   param ctx:  r24:r25
486   param msg:  r22:r23
487 */
488 /* f0
489   param q:  r28:r29 (Y)
490   param h:  r26:r27 (X)
491   param m:  r30:r31 (Z)
492 */
493 /* f1
494   param q: r24:r25
495   param m: r22:r23
496   param h: r20:r21
497 */
498 /* f2
499   param q: r24:r25
500   param m: r22:r23
501   param h: r20:r21
502 */
503 q0 = 2
504 q1 = 3
505 h0 = 4
506 h1 = 5
507 m0 = 6
508 m1 = 7
509
510
511 .global bmw_small_nextBlock
512 .global bmw224_nextBlock
513 .global bmw256_nextBlock
514 bmw_small_nextBlock:
515 bmw224_nextBlock:
516 bmw256_nextBlock:
517         push_range 28, 29
518         push_range  2, 17
519         stack_alloc_large 32*4, r28, r29
520         ldi r16, 0x4f
521         push r16
522         ldi r16, 0xff
523         push r16
524         push r16
525         ldi r16, 0xfb
526         push r16
527         adiw r28, 1
528 ;       push_range 28, 29 /* push Q */
529 ;       push_range 22, 25 /* push M & H */
530         /* increment counter */
531         movw r26, r24
532         movw r2, r26
533         adiw r26, 63
534         adiw r26,  1
535         rcall load_acc_from_X
536         ldi r19, 1
537         add acc0, r19
538         adc acc1, r1
539         adc acc2, r1
540         adc acc3, r1
541         rcall store_acc_to_dec_X
542         /* call f0 */
543         movw r30, r22
544         movw r26, r24
545 f0:
546         movw h0, r26
547         movw q0, r28
548         movw m0, r30
549         /* xor m into h */
550 ;       ldi r20, 64
551         rcall memxor_short
552         movw r30, m0
553         movw r26, h0
554
555         /* set q to zero */
556         ldi r22, 64
557 10:     st Y+, r1
558         dec r22
559         brne 10b
560         movw r28, q0
561         /* calculate W and store it in Q */
562         ldi r19, 5
563 30:
564         ldi r18, 16
565         /* load initial index */
566
567         /* load values from hacktable */
568         ldi r30, lo8(f0_hacktable-3)
569         ldi r31, hi8(f0_hacktable-3)
570         mov r16, r19
571         lsl r16
572         add r16, r19
573         add r30, r16
574         adc r31, r1
575         lpm r21, Z+
576         lpm r20, Z+
577         lpm r16, Z+
578 40:
579         ;call add_hx_to_w
580 add_hx_to_w:
581         movw r26, h0
582         add r26, r16
583         adc r27, r1
584         rcall load32_from_Y
585         sbiw r28, 4
586         lsl r20
587         rol r21
588         brcs 300f
589         /* addition */
590         rcall add_X_to_32
591         rjmp 500f
592 300: /* substract */
593         rcall load_acc_from_X
594         sub r22, acc0
595         sbc r23, acc1
596         sbc r24, acc2
597         sbc r25, acc3
598
599 500:
600         rcall store32_to_Y
601         subi r16, -4
602         andi r16, 0x0f<<2
603         dec r18
604         brne 40b
605         movw r28, q0
606         dec r19
607         brne 30b
608         movw r26, h0
609         /* xor m into h */
610 ;       ldi r20, 64
611         movw r26, h0
612         movw r30, m0
613         rcall memxor_short
614         sbiw r26, 60
615 ;---
616         clr r17
617         ldi r21, 15
618         mov r8, r21
619 50:
620         rcall load32_from_Y
621         sbiw r28, 4
622         mov r20, r17
623         rcall sn
624         inc r17
625         cpi r17, 5
626         brne 52f
627         clr r17
628 52:
629         rcall add_X_to_32
630         rcall store32_to_Y
631
632         dec r8
633         brne 50b
634 ;---
635         rcall load32_from_Y
636         clr r20
637         rcall sn
638         movw r26, h0
639         rcall add_X_to_32
640         sbiw r26, 4
641         sbiw r28, 4
642         rcall store32_to_Y
643         sbiw r28, 4
644         sbiw r28, 15*4
645         movw r20, h0
646         movw r22, m0
647
648         /* call f1*/
649         movw r2, r28
650 f1:
651         movw r4, r22
652         movw r6, r20
653         movw r26, r2
654         clr r24
655         rcall expand1
656         movw r26, r2
657         movw r22, r4
658     movw r20, r6
659         ldi r24, 1
660         rcall expand1
661         ldi r17, 2
662 10:     movw r26, r2
663         movw r22, r4
664         movw r20, r6
665         mov r24, r17
666         rcall expand2
667         inc r17
668         sbrs r17, 4
669         rjmp 10b
670         movw r24, r2
671         movw r22, r4
672         movw r20, r6
673
674
675         /* call f2 */
676 ;       pop_range 20, 25
677 ;       push_range 20, 25
678 ;       rcall printQ
679 ;       push r20
680 ;       push r21
681 acc2  =  8
682 acc3  =  9
683 acc0  = 14
684 acc1  = 15
685 xl0   =  2
686 xl1   =  3
687 xl2   =  4
688 xl3   =  5
689 xh0   =  6
690 xh1   =  7
691 xh2   = 10
692 xh3   = 11
693 q16_0 = 12
694 q16_1 = 13
695 h0   =  18
696 h1   =  19
697 f2:
698         movw r26, r24
699         /* calc XL */
700         adiw r26, 63
701         adiw r26,  1
702         movw q16_0, r26
703         movw h0, r20
704         movw r28, r22
705         rcall load32_from_X
706         movw acc0, r22
707         movw acc2, r24
708         ldi r17, 15
709 10:     rcall load32_from_X
710         rcall eor32_to_acc
711         cpi r17, 9
712         brne 15f
713         movw xl0, acc0
714         movw xl2, acc2
715 15:
716         dec r17
717         brne 10b
718         movw xh0, acc0
719         movw xh2, acc2
720 ;--- DBG
721 ;       push_range 22, 25
722 ;       movw r22, xl0
723 ;       movw r24, xl2
724 ;       rcall print32
725 ;       movw r22, xh0
726 ;       movw r24, xh2
727 ;       rcall print32
728 ;       pop_range 22, 25
729 ;--- END DBG
730
731 ;--- /* calc first half of h0..h15 */
732         movw r26, q16_0
733         ldi r17, 16
734 10:
735         ld acc0, Y+
736         ld acc1, Y+
737         ld acc2, Y+
738         ld acc3, Y+
739 ;---
740         movw r22, xh0
741         movw r24, xh2
742         cpi r17, 9
743         brge 15f
744         clr r1
745         rjmp 26f
746 15:     ldi r30, lo8(f2_1_shift_table-9)
747         ldi r31, hi8(f2_1_shift_table-9)
748         add r30, r17
749         adc r31, r1
750         lpm r20, Z
751         mov r1, r20
752         andi r20, 0x0f
753         clt
754         cpi r17, 16
755         breq 20f
756         cpi r17, 11
757         brne 21f
758 20:     set
759 21:     brts 25f
760         rcall shiftright32
761         rjmp 26f
762 25:     rcall shiftleft32
763 26: rcall eor32_to_acc
764 ;---
765         rcall load32_from_X
766         mov r20, r1
767         clr r1
768         swap r20
769         andi r20, 0x0f
770         brts 27f
771         rcall shiftleft32
772         rjmp 28f
773 27:     rcall shiftright32
774 28:     rcall eor32_to_acc
775 ;---
776         movw r30, h0
777         st Z+, acc0
778         st Z+, acc1
779         st Z+, acc2
780         st Z+, acc3
781         movw h0, r30
782 ;---
783         dec r17
784         brne 10b
785 ;-----
786         sbiw r26, 4*8 /* X points to q[24] */
787         movw r28, r26
788         sbiw r28, 63
789         sbiw r28, 33 /* Y points to q[0] */
790         sbiw r30, 63
791         sbiw r30,  1 /* Z points to h0 */
792         ldi r17, 8
793 10:     movw acc0, xl0
794         movw acc2, xl2
795         rcall load32_from_X
796         rcall eor32_to_acc
797         rcall load32_from_Y
798         rcall eor32_to_acc
799         rcall add_acc_to_Z
800         dec r17
801         brne 10b
802         sbiw r26, 9*4 /* X points to q[23] */
803         rcall load_acc_from_X
804         eor acc1, xl0
805         eor acc2, xl1
806         eor acc3, xl2
807         rcall load32_from_Y
808         rcall eor32_to_acc
809         rcall add_acc_to_Z
810 ;---
811         sbiw r26, 8*4 /* X points to q[16] */
812         mov h0, r30
813         ldi r17, 7
814 10:
815         ldi r30, lo8(f2_2_shift_table-1)
816         ldi r31, hi8(f2_2_shift_table-1)
817         add r30, r17
818         adc r31, r1
819         lpm r20, Z
820         rcall load_acc_from_X
821         movw r22, xl0
822         movw r24, xl2
823         lsr r20
824         brcc 20f
825         rcall shiftleft32
826         rjmp 21f
827 20:     rcall shiftright32
828 21:
829         rcall eor32_to_acc
830         rcall load32_from_Y
831         rcall eor32_to_acc
832         movw r30, h0
833         rcall add_acc_to_Z
834         movw h0, r30
835         dec r17
836         brne 10b
837 ;-----
838         sbiw r30, 8*4 /* Z points to h8 */
839         movw r26, r30
840         sbiw r26, 4*4 /* X points to h4 */
841         ldi r17, 8
842         ldi r18, 9
843 10:
844         rcall load32_from_X
845         mov r20, r18
846         rcall rotateleft32
847         movw acc0, r22
848         movw acc2, r24
849         rcall add_acc_to_Z
850         inc r18
851         cpi r17, 5
852         brne 20f
853         sbiw r26, 8*4
854 20:     dec r17
855         brne 10b
856
857 ;--- DBG
858 ;       pop r25
859 ;       pop r24
860 ;       ldi r22, 'H'
861 ;       rcall printX
862 ;--- END DBG
863         stack_free_large3 32*4+4
864         pop_range  2, 17
865         pop_range 28, 29
866         ret
867
868 /******************************************************************************/
869 ctx0 =  2
870 ctx1 =  3
871 blc0 =  4
872 blc1 =  5
873 len0 = 28
874 len1 = 29
875 buf0 =  6
876 buf1 =  7
877
878 load32_from_Z_stub:
879         movw r30, ctx0
880         adiw r30, 60
881         ldd r21, Z+4
882         ldd r22, Z+5
883         ldd r23, Z+6
884         ldd r24, Z+7
885         ret
886
887 /******************************************************************************/
888 /*
889   param ctx:  r24:r25
890   param msg:  r22:r23
891   param len:  r20:r21
892 */
893
894 .global bmw_small_lastBlock
895 .global bmw224_lastBlock
896 .global bmw256_lastBlock
897 bmw_small_lastBlock:
898 bmw224_lastBlock:
899 bmw256_lastBlock:
900 /*      while(length_b >= BMW_SMALL_BLOCKSIZE){
901                 bmw_small_nextBlock(ctx, block);
902                 length_b -= BMW_SMALL_BLOCKSIZE;
903                 block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
904         }
905 */
906         push_range 2, 7
907         push_range 28, 29
908         movw ctx0, r24
909         movw blc0, r22
910         movw len0, r20
911 1:
912         cpi len1, hi8(512)
913         brlo 2f
914         movw r24, ctx0
915         movw r22, blc0
916         rcall bmw_small_nextBlock
917         ldi r24, 64
918         add blc0, r24
919         adc blc1, r1
920         subi len1, hi8(512)
921         rjmp 1b
922 2:
923 /*      struct {
924                 uint8_t  buffer[64];
925                 uint32_t ctr;
926         } pctx;
927 */
928         stack_alloc_large 68
929         adiw r30, 1
930         movw buf0, r30
931 /*      memset(pctx.buffer, 0, 64);
932         memcpy(pctx.buffer, block, (length_b+7)/8);
933         pctx.buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
934 */      movw r24, len0
935         lsr r25
936         ror r24
937         lsr r24
938         lsr r24
939         ldi r23, 63
940         sub r23, r24
941         movw r26, blc0
942         tst r24
943         breq 301f
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