]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bmw/bmw_256-tinyasm.S
bmw tiny split up
[avr-crypto-lib.git] / bmw / bmw_256-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 acc2 =  8
32 acc3 =  9
33 acc0 = 14
34 acc1 = 15
35
36 #define DEBUG 0
37
38 /******************************************************************************/
39 /*
40   param a: r22:r23:r24:r25
41   param s: r20
42 */
43 shiftleft32:
44         clr r0
45         cpi r20, 8
46         brlo bitrotateleft_1
47         mov r25, r24
48         mov r24, r23
49         mov r23, r22
50         clr r22
51         subi r20, 8
52         rjmp shiftleft32
53
54 /******************************************************************************/
55 /*
56   param a: r22:r23:r24:r25
57   param s: r20
58 */
59 shiftright32:
60         cpi r20, 8
61         brlo bitshiftright
62         mov r22, r23
63         mov r23, r24
64         mov r24, r25
65         clr r25
66         subi r20, 8
67         rjmp shiftright32
68 bitshiftright:
69         tst r20
70         breq 20f
71 10:     lsr r25
72         ror r24
73         ror r23
74         ror r22
75         dec r20
76         brne 10b
77 20: ret
78
79 /******************************************************************************/
80 /*
81   param a: r22:r23:r24:r25
82   param s: r20
83 */
84 rotateleft32:
85         cpi r20, 8
86         brlo bitrotateleft
87         mov r0, r25
88         mov r25, r24
89         mov r24, r23
90         mov r23, r22
91         mov r22, r0
92         subi r20, 8
93         rjmp rotateleft32
94 bitrotateleft:
95     mov r0, r25
96 bitrotateleft_1:
97         tst r20
98         breq 20f
99 10:
100         lsl r0
101 rol32:
102         rol r22
103         rol r23
104         rol r24
105         rol r25
106         dec r20
107         brne 10b
108 20: ret
109
110
111 /******************************************************************************/
112
113 sn_stub:
114         movw r22, r2
115         movw r24, r4
116         lpm r20, Z+
117         rcall rotateleft32
118 eor32_to_acc:
119         eor acc0, r22
120         eor acc1, r23
121         eor acc2, r24
122         eor acc3, r25
123         ret
124
125 s_table:
126 s0:  .byte 1, 3, 4,19
127 s1:  .byte 1, 2, 8,23
128 s2:  .byte 2, 1,12,25
129 s3:  .byte 2, 2,15,29
130 s4:  .byte 1, 0, 0, 0
131 s5:  .byte 2, 0, 0, 0
132
133 h0   = 10
134 h1   = 11
135 m0   = 12
136 m1   = 13
137
138 /*
139   param x: r22:r23:r24:25
140   param s: r20
141 */
142 sn:
143         push_range 2, 5
144         push acc0
145         push acc1
146         push acc2
147         push acc3
148         ldi r30, lo8(s_table)
149         ldi r31, hi8(s_table)
150         lsl r20
151         lsl r20
152         add r30, r20
153         adc r31, r1
154         movw r2, r22
155         movw r4, r24
156         lpm r20, Z+
157         rcall shiftright32
158         rcall mov32_to_acc
159 ;---
160         movw r22, r2
161         movw r24, r4
162         lpm r20, Z+
163         rcall shiftleft32
164         rcall eor32_to_acc
165 ;---
166         rcall sn_stub
167         rcall sn_stub
168
169         movw r22, acc0
170         movw r24, acc2
171         pop acc3
172         pop acc2
173         pop acc1
174         pop acc0
175         rjmp pop5
176
177 /******************************************************************************/
178 /*
179   param dest: r26:r27 (X)
180   param src:  r30:r31 (Z)
181   param len:  r20
182 */
183 memxor_64:
184 ;       tst r20
185 ;       breq memxor_exit
186         ldi r20, 64
187 memxor:
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 store32_to_X:
240         st X+, r22
241         st X+, r23
242         st X+, r24
243         st X+, r25
244         ret
245
246 mov32_to_acc:
247         movw acc0, r22
248         movw acc2, r24
249         ret
250
251 /******************************************************************************/
252 /*
253   param q:  r28:r29 (Y)
254   param h:  r26:r27 (X)
255   param m:  r30:r31 (Z)
256 */
257
258 f2_1_shift_table:
259 ;       .byte 0x2B, 0x64, 0x66, 0x03, 0x51, 0x55, 0x87, 0x55
260         .byte 0x55, 0x87, 0x55, 0x51, 0x03, 0x66, 0x64, 0x2B
261 f2_2_shift_table:
262 ;       .byte (2<<1), (7<<1), (4<<1), (3<<1), (4<<1)+1, (6<<1)+1, (6<<1)
263         .byte (8<<1)+1, (6<<1), (6<<1)+1, (4<<1)+1, (3<<1), (4<<1), (7<<1), (2<<1)
264 expand2_rot_table:
265         .byte 3,7,13,16,19,23,27
266
267 f0_hacktable:
268         .byte 0x03, 0x11, 5*4
269         .byte 0xDD, 0xB3, 7*4
270         .byte 0x2A, 0x79, 10*4
271         .byte 0x07, 0xAA, 13*4
272         .byte 0x51, 0xC2, 14*4
273
274
275 /*******************************************************************************
276 * uint32_t addelment(uint8_t j, const uint32_t* m, const uint32_t* h){
277 *       uint32_t r;
278 *       r  = pgm_read_dword(k_lut+j);
279 *       r += rotl_addel(((uint32_t*)m)[j&0xf], j+0);
280 *       r += rotl_addel(((uint32_t*)m)[(j+3)&0xf], j+3);
281 *       r -= rotl_addel(((uint32_t*)m)[(j+10)&0xf], j+10);
282 *       r ^= ((uint32_t*)h)[(j+7)&0xf];
283 *       return r;
284 * }
285 * param j: r24
286 * param m: r22:r23
287 * param h: r20:r21
288 */
289 j    = 16
290 acc2 =  8
291 acc3 =  9
292 h0   = 10
293 h1   = 11
294 m0   = 12
295 m1   = 13
296 acc0 = 14
297 acc1 = 15
298
299 load_acc_from_X:
300         ld acc0, X+
301         ld acc1, X+
302         ld acc2, X+
303         ld acc3, X+
304         ret
305
306 add_acc_to_X:
307         ld r0, X
308         add r0, acc0
309         st X+, r0
310         ld r0, X
311         adc r0, acc1
312         st X+, r0
313         ld r0, X
314         adc r0, acc2
315         st X+, r0
316         ld r0, X
317         adc r0, acc3
318         st X+, r0
319         ret
320
321 load_rotate_add_M:
322         mov r20, j
323         andi r20, 0x0f
324         mov r0, r20
325         lsl r0
326         lsl r0
327         movw r26, m0
328         add r26, r0
329         adc r27, r1
330         rcall load32_from_X
331         inc r20
332         rcall rotateleft32
333         brts 10f
334         rjmp add32_to_acc
335 ;       ret
336 10:     sub acc0, r22
337         sbc acc1, r23
338         sbc acc2, r24
339         sbc acc3, r25
340         ret
341
342
343 ;---
344
345 /******************************************************************************/
346 load_sn_add:
347         rcall load32_from_X
348         rcall sn
349 add32_to_acc:
350         add acc0, r22
351         adc acc1, r23
352         adc acc2, r24
353         adc acc3, r25
354         ret
355
356 /*
357   param q: r26:r27
358   param m: r22:r23
359   param h: r20:r21
360   param j: r24
361 */
362
363 expand_intro:
364         push_range 26, 27
365         push r24
366 addelement:
367         mov j, r24
368         movw h0, r20
369         movw m0, r22
370         sbiw r26, 4
371         rcall load_acc_from_X
372         ldi r24, 0x55
373         add acc0, r24
374         adc acc1, r24
375         adc acc2, r24
376         ldi r24, 5
377         adc acc3, r24
378         rcall store_acc_to_dec_X
379         adiw r26, 4
380         clt
381         rcall load_rotate_add_M
382         subi j, -3
383         rcall load_rotate_add_M
384         set
385         subi j, -7
386         rcall load_rotate_add_M
387         lsl j
388         lsl j
389         subi j, -7*4+10*4
390         andi j, 0x3f
391         movw r26, h0
392         add r26, j
393         adc r27, r1
394         rcall load32_from_X
395         rcall eor32_to_acc
396 ;--
397         pop r24
398         pop_range 26, 27
399         lsl r24
400         lsl r24
401         add r26, r24
402         adc r27, r1
403         ret
404 expand1:
405         rcall expand_intro
406         ldi r19, 1
407 10:
408         mov r20, r19
409         andi r20, 3
410         rcall load_sn_add
411         inc r19
412         cpi r19, 17
413         brne 10b
414         rjmp expand2_exit
415
416
417 /******************************************************************************/
418 /*
419   param q: r26:r27
420   param m: r22:r23
421   param h: r20:r21
422   param j: r24
423 */
424
425
426 expand2:
427         rcall expand_intro
428         ldi r19, 14
429         ldi r30, lo8(expand2_rot_table)
430         ldi r31, hi8(expand2_rot_table)
431 10:
432         rcall load32_from_X
433         sbrs r19, 0
434         rjmp 12f
435         lpm r20, Z+
436         rcall rotateleft32
437 12:     rcall add32_to_acc
438         dec r19
439         brne 10b
440         ldi r20, 4
441         rcall load_sn_add
442         ldi r20, 5
443         rcall load_sn_add
444 expand2_exit:
445         adiw r26, 4
446 store_acc_to_dec_X:
447         st -X, acc3
448         st -X, acc2
449         st -X, acc1
450         st -X, acc0
451         ret
452
453 /******************************************************************************/
454 /*
455   param q: r24:r25
456   param m: r22:r23
457   param h: r20:r21
458 */
459 /* for calling expand1/2
460   param q: r26:r27
461   param m: r22:r23
462   param h: r20:r21
463   param j: r24
464 */
465
466 /******************************************************************************/
467 /*
468   param q: r24:r25
469   param m: r22:r23
470   param h: r20:r21
471 */
472
473 /******************************************************************************/
474 /*
475   param ctx:  r24:r25
476   param msg:  r22:r23
477 */
478 /* f0
479   param q:  r28:r29 (Y)
480   param h:  r26:r27 (X)
481   param m:  r30:r31 (Z)
482 */
483 /* f1
484   param q: r24:r25
485   param m: r22:r23
486   param h: r20:r21
487 */
488 /* f2
489   param q: r24:r25
490   param m: r22:r23
491   param h: r20:r21
492 */
493 q0 = 2
494 q1 = 3
495 h0 = 4
496 h1 = 5
497 m0 = 6
498 m1 = 7
499 ctx0 =   2
500 ctx1 =   3
501 msg0 =   4
502 msg1 =   5
503
504 restore_f1:
505         movw r26, r2
506         movw r22, r4
507     movw r20, r6
508         ret
509 bmw_small_nextBlock_early:
510         movw r24, ctx0
511         movw r22, msg0
512 .global bmw_small_nextBlock
513 .global bmw256_nextBlock
514 bmw_small_nextBlock:
515 bmw224_nextBlock:
516 bmw256_nextBlock:
517         push_range  2, 7
518         push_range 28, 29
519         push_range  8, 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_64
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_64
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         rcall restore_f1
658         ldi r24, 1
659         rcall expand1
660         ldi r17, 2
661 10: rcall restore_f1
662         mov r24, r17
663         rcall expand2
664         inc r17
665         sbrs r17, 4
666         rjmp 10b
667         rcall restore_f1
668         movw r24, r2
669
670
671         /* call f2 */
672 ;       pop_range 20, 25
673 ;       push_range 20, 25
674 ;       rcall printQ
675 ;       push r20
676 ;       push r21
677 acc2  =  8
678 acc3  =  9
679 acc0  = 14
680 acc1  = 15
681 xl0   =  2
682 xl1   =  3
683 xl2   =  4
684 xl3   =  5
685 xh0   =  6
686 xh1   =  7
687 xh2   = 10
688 xh3   = 11
689 q16_0 = 12
690 q16_1 = 13
691 h0   =  18
692 h1   =  19
693 f2:
694         movw r26, r24
695         /* calc XL & XH */
696         adiw r26, 63
697         adiw r26,  1
698         movw q16_0, r26
699         movw h0, r20
700 ;---
701 ;       push h0
702 ;       push h1
703 ;---
704         movw r28, r22
705         rcall load_acc_from_X
706         ldi r17, 15
707 10:     rcall load32_from_X
708         rcall eor32_to_acc
709         cpi r17, 9
710         brne 15f
711         movw xl0, acc0
712         movw xl2, acc2
713 15:
714         dec r17
715         brne 10b
716         movw xh0, acc0
717         movw xh2, acc2
718 ;--- DBG
719 ;       push_range 22, 25
720 ;       movw r22, xl0
721 ;       movw r24, xl2
722 ;       rcall print32
723 ;       movw r22, xh0
724 ;       movw r24, xh2
725 ;       rcall print32
726 ;       pop_range 22, 25
727 ;--- END DBG
728          /* copy m(Y) into h */
729         movw r26, h0
730         ldi r22, 64
731 10:
732         ld r23, Y+
733         st X+, r23
734         dec r22
735         brne 10b
736 ;--- /* calc first half of h0..h15 */
737         movw r28, q16_0
738         movw r26, h0
739         ldi r30, lo8(f2_1_shift_table)
740         ldi r31, hi8(f2_1_shift_table)
741         ldi r17, 16
742 10:
743 ;---
744         movw r22, xh0
745         movw r24, xh2
746         cpi r17, 9
747         brge 15f
748         clr r1
749         rjmp 26f
750 15:     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 mov32_to_acc
764 ;---
765         rcall load32_from_Y
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         rcall load32_from_X
777         rcall eor32_to_acc
778         rcall store_acc_to_dec_X
779         adiw r26, 4
780 ;---
781         dec r17
782         brne 10b
783 ;-----
784         sbiw r28, 4*8 /* Y points to q[24] */
785         movw r30, r28
786         sbiw r28, 63
787         sbiw r28, 33 /* Y points to q[0] */
788         movw r26, r28
789         ldi r20, 8*4
790         /* xor q[24..31] into q[0..7] */
791         rcall memxor
792         /* xor q[23] into q[8] */
793         sbiw r30, 9*4
794         ldi r20, 4
795         rcall memxor
796         /* xor q[16..22] into q[9..15] */
797         sbiw r30, 8*4
798         ldi r20, 7*4
799         rcall memxor
800
801         movw r26, h0
802         ldi r17, 15
803         ldi r30, lo8(f2_2_shift_table)
804         ldi r31, hi8(f2_2_shift_table)
805 10:     movw r22, xl0
806         movw r24, xl2
807         sbrc r17, 3
808         rjmp 20f
809         lpm r20, Z+
810         lsr r20
811         brcs 15f
812         rcall shiftright32
813         rjmp 20f
814 15:
815         rcall shiftleft32
816 20:
817         rcall mov32_to_acc
818         rcall load32_from_Y
819         rcall eor32_to_acc
820         rcall add_acc_to_X
821         dec r17
822         brpl 10b
823 ;-----
824         sbiw r26, 8*4 /* X points to h8 */
825         movw r28, r26
826         sbiw r28, 4*4 /* Y points to h4 */
827         ldi r17, 8
828         ldi r18, 9
829 10:
830         rcall load32_from_Y
831         mov r20, r18
832         rcall rotateleft32
833         rcall mov32_to_acc
834         rcall add_acc_to_X
835         inc r18
836         cpi r17, 5
837         brne 20f
838         sbiw r28, 8*4
839 20:     dec r17
840         brne 10b
841
842 exit:
843 ;--- DBG
844 ;       pop r25
845 ;       pop r24
846 ;       ldi r22, 'H'
847 ;       rcall printX
848 ;--- END DBG
849         stack_free_large3 32*4+4
850         pop_range 10, 17
851 pop9:
852         pop_range 8, 9
853 pop28:
854         pop_range 28, 29
855 pop7:
856         pop_range 6, 7
857 pop5:
858         pop_range 2, 5
859         ret
860
861 /******************************************************************************/
862 ctx0 =  2
863 ctx1 =  3
864 blc0 =  4
865 blc1 =  5
866 len0 = 28
867 len1 = 29
868 buf0 =  6
869 buf1 =  7
870
871 load32_from_Z_stub:
872         movw r30, ctx0
873         adiw r30, 60
874         ldd r21, Z+4
875         ldd r22, Z+5
876         ldd r23, Z+6
877         ldd r24, Z+7
878         ret
879
880 /******************************************************************************/
881 /*
882   param ctx:  r24:r25
883   param msg:  r22:r23
884   param len:  r20:r21
885 */
886
887 .global bmw_small_lastBlock
888 .global bmw256_lastBlock
889 bmw_small_lastBlock:
890 bmw224_lastBlock:
891 bmw256_lastBlock:
892 /*      while(length_b >= BMW_SMALL_BLOCKSIZE){
893                 bmw_small_nextBlock(ctx, block);
894                 length_b -= BMW_SMALL_BLOCKSIZE;
895                 block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
896         }
897 */
898         push_range 2, 7
899         push_range 28, 29
900         movw ctx0, r24
901         movw blc0, r22
902         movw len0, r20
903 1:
904         cpi len1, hi8(512)
905         brlo 2f
906         rcall bmw_small_nextBlock_early
907         ldi r24, 64
908         add blc0, r24
909         adc blc1, r1
910         subi len1, hi8(512)
911         rjmp 1b
912 2:
913 /*      struct {
914                 uint8_t  buffer[64];
915                 uint32_t ctr;
916         } pctx;
917 */
918         stack_alloc_large 68
919         adiw r30, 1
920         movw buf0, r30
921 /*      memset(pctx.buffer, 0, 64);
922         memcpy(pctx.buffer, block, (length_b+7)/8);
923         pctx.buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
924 */      movw r24, len0
925         ldi r23, 63
926         movw r26, blc0
927         lsr r25
928         ror r24
929         lsr r24
930         lsr r24
931         breq 301f
932         sub r23, r24
933         /* copy (#r24) bytes to stack buffer */
934 30: ld r20, X+
935         st Z+, r20
936         dec r24
937         brne 30b
938 301: /* calculate the appended byte */
939         clr r20
940         mov r21, len0
941         ldi r24, 0x80
942         andi r21, 0x07
943         breq 305f
944         ld r20, X+
945 303:
946         lsr r24
947         dec r21
948         brne 303b
949 305:
950         or r20, r24
951         st Z+, r20
952         tst r23
953         breq 32f
954 31: st Z+, r1
955         dec r23
956         brne 31b
957 32:
958 /*      if(length_b+1>64*8-64){ ; = 64*7-1 = 447 max(length_b)=511
959                 bmw_small_nextBlock(ctx, pctx.buffer);
960                 memset(pctx.buffer, 0, 64-8);
961                 ctx->counter -= 1;
962         }
963 */
964         tst len1
965         breq 400f
966         cpi len0, 192
967         brlo 400f
968         movw blc0, buf0
969         rcall bmw_small_nextBlock_early
970         movw r26, buf0
971         ldi r20, 64-8
972 350:
973         st X+, r1
974         dec r20
975         brne 350b
976         rcall load32_from_Z_stub
977         subi r21, 1
978         sbc r22, r1
979         sbc r23, r1
980         sbc r24, r1
981         rjmp 410f
982 /*      *((uint64_t*)&(pctx.buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
983         bmw_small_nextBlock(ctx, pctx.buffer);
984 */
985 400:
986         rcall load32_from_Z_stub
987 410:
988         clr r25
989         ldi r20, 1
990         lsl r21
991         rcall rol32
992         mov r20, len0
993         add r21, len1
994         adc r22, r1
995         adc r23, r1
996         adc r24, r1
997         adc r25, r1
998         movw r26, buf0
999         adiw r26, 64-8
1000         st X+, r20
1001         st X+, r21
1002         rcall store32_to_X
1003         st X+, r1
1004         st X+, r1
1005         movw blc0, buf0
1006         rcall bmw_small_nextBlock_early
1007 /*      memset(pctx.buffer, 0xaa, 64);
1008         for(i=0; i<16;++i){
1009                 pctx.buffer[i*4] = i+0xa0;
1010         }
1011 */
1012         ldi r22, 0xa0
1013         ldi r23, 0xaa
1014         ldi r24, 0xaa
1015         ldi r25, 0xaa
1016         movw r26, buf0
1017 500:
1018         rcall store32_to_X
1019         inc r22
1020         sbrs r22, 4
1021         rjmp 500b
1022 /*      bmw_small_nextBlock((bmw_small_ctx_t*)&pctx, ctx->h);
1023         memcpy(ctx->h, pctx.buffer, 64);
1024 */
1025     movw r24, buf0
1026     movw r22, ctx0
1027     rcall bmw_small_nextBlock
1028         ldi r18, 64
1029         movw r26, ctx0
1030         movw r30, buf0
1031 600:
1032         ld r20, Z+
1033         st X+, r20
1034         dec r18
1035         brne 600b
1036
1037         stack_free_large 68
1038         rjmp pop28
1039
1040
1041 /*******************************************************************************
1042 * void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
1043 *       memcpy(dest, &(ctx->h[8]), 256/8);
1044 * }
1045 *
1046 * param dest:  r24:r25
1047 * param ctx:   r22:r23
1048 */
1049 .global bmw256_ctx2hash
1050 bmw256_ctx2hash:
1051         movw r30, r22
1052         adiw r30, 8*4
1053         ldi r18, 32
1054 1:      movw r26, r24
1055 1:  ld r23, Z+
1056         st X+, r23
1057         dec r18
1058         brne 1b
1059         ret
1060
1061 /*******************************************************************************
1062 * void bmw256(void* dest, const void* msg, uint32_t length_b){
1063 *       bmw_small_ctx_t ctx;
1064 *       bmw256_init(&ctx);
1065 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1066 *               bmw_small_nextBlock(&ctx, msg);
1067 *               length_b -= BMW_SMALL_BLOCKSIZE;
1068 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1069 *       }
1070 *       bmw_small_lastBlock(&ctx, msg, length_b);
1071 *       bmw256_ctx2hash(dest, &ctx);
1072 * }
1073 *
1074 * param dest:     r24:r25
1075 * param msg:      r22:r23
1076 * param length_b: r18:r21
1077 */
1078 ctx0 =   2
1079 ctx1 =   3
1080 msg0 =   4
1081 msg1 =   5
1082 len0 =   6
1083 len1 =   7
1084 len2 =   8
1085 len3 =   9
1086 dst0 =  10
1087 dst1 =  11
1088
1089
1090 /*******************************************************************************
1091 * void bmw224(void* dest, const void* msg, uint32_t length_b){
1092 *       bmw_small_ctx_t ctx;
1093 *       bmw224_init(&ctx);
1094 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1095 *               bmw_small_nextBlock(&ctx, msg);
1096 *               length_b -= BMW_SMALL_BLOCKSIZE;
1097 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1098 *       }
1099 *       bmw_small_lastBlock(&ctx, msg, length_b);
1100 *       bmw224_ctx2hash(dest, &ctx);
1101 * }
1102 *
1103 * param dest:     r24:r25
1104 * param msg:      r22:r23
1105 * param length_b: r18:r21
1106 */
1107 ctx0 =   2
1108 ctx1 =   3
1109 msg0 =   4
1110 msg1 =   5
1111 len0 =  28
1112 len1 =  29
1113 len2 =   8
1114 len3 =   9
1115 dst0 =   6
1116 dst1 =   7
1117
1118
1119 .global bmw256
1120 bmw256:
1121         push_range 2, 7
1122         push_range 28, 29
1123         push_range 8, 9
1124         stack_alloc_large 64+4
1125 10:     movw ctx0, r30
1126         movw dst0, r24
1127         movw msg0, r22
1128         movw len0, r18
1129         movw len2, r20
1130         movw r24, ctx0
1131         rcall bmw256_init
1132 20:
1133         mov r18, len2
1134         or  r18, len3
1135         breq 50f
1136         rcall bmw_small_nextBlock_early
1137         subi len1, 2
1138         sbc len2, r1
1139         sbc len3, r1
1140         ldi r20, 64
1141         add msg0, r20
1142         adc msg1, r1
1143         rjmp 20b
1144 50:
1145         movw r24, ctx0
1146         movw r22, msg0
1147         movw r20, len0
1148         rcall bmw_small_lastBlock
1149         movw r24, dst0
1150         movw r22, ctx0
1151         rcall bmw256_ctx2hash
1152         stack_free_large 64+4
1153         rjmp pop9
1154
1155 /******************************************************************************/
1156 .global bmw256_init
1157 bmw256_init:
1158         ldi r22, 0x40
1159         ldi r23, 0x80
1160         movw r26, r24
1161         adiw r26, 4
1162 10:
1163         st -X, r22
1164         inc r22
1165         mov r20, r22
1166         andi r20, 0x3
1167         brne 10b
1168         adiw r26, 8
1169 20: cp r22, r23
1170         brne 10b
1171         st -X, r1
1172         st -X, r1
1173         st -X, r1
1174         st -X, r1
1175         ret
1176
1177
1178 /******************************************************************************/
1179
1180 #if DEBUG
1181
1182 printQ:
1183         push_range 20, 25
1184         ldi r16, 4
1185         mov r9, r16
1186         movw r16, r24
1187         ldi r24, lo8(qdbg_str)
1188         ldi r25, hi8(qdbg_str)
1189         call cli_putstr_P
1190         clr r8
1191 10:     ldi r24, lo8(qdbg_str1)
1192         ldi r25, hi8(qdbg_str1)
1193         call cli_putstr_P
1194         mov r24, r8
1195         call cli_hexdump_byte
1196         ldi r24, lo8(qdbg_str2)
1197         ldi r25, hi8(qdbg_str2)
1198         call cli_putstr_P
1199         movw r24, r16
1200         clr r23
1201         ldi r22, 4
1202         call cli_hexdump_rev
1203         add r16, r9
1204         adc r17, r1
1205         inc r8
1206         sbrs r8, 5
1207         rjmp 10b
1208         pop_range 20, 25
1209         ret
1210 qdbg_str:  .asciz "\r\nDBG Q: "
1211 qdbg_str1: .asciz "\r\n Q["
1212 qdbg_str2: .asciz "] =  "
1213
1214
1215 printX:
1216         push_range 6, 9
1217         push_range 16, 27
1218         push_range 30, 31
1219         ldi r16, 4
1220         mov r6, r22
1221         mov r9, r16
1222         movw r16, r24
1223         ldi r24, lo8(Xdbg_str)
1224         ldi r25, hi8(Xdbg_str)
1225         call cli_putstr_P
1226         mov r24, r6
1227         call cli_putc
1228         ldi r24, ':'
1229         call cli_putc
1230         clr r8
1231 10:     ldi r24, lo8(Xdbg_str1)
1232         ldi r25, hi8(Xdbg_str1)
1233         call cli_putstr_P
1234         mov r24, r6
1235         call cli_putc
1236         ldi r24, '['
1237         call cli_putc
1238         mov r24, r8
1239         call cli_hexdump_byte
1240         ldi r24, lo8(Xdbg_str2)
1241         ldi r25, hi8(Xdbg_str2)
1242         call cli_putstr_P
1243         movw r24, r16
1244         clr r23
1245         ldi r22, 4
1246         call cli_hexdump_rev
1247         add r16, r9
1248         adc r17, r1
1249         inc r8
1250         sbrs r8, 4
1251         rjmp 10b
1252         pop_range 30, 31
1253         pop_range 16, 27
1254         pop_range 6, 9
1255         ret
1256 Xdbg_str:  .asciz "\r\nDBG "
1257 Xdbg_str1: .asciz "\r\n "
1258 Xdbg_str2: .asciz "] = "
1259
1260 print32:
1261         push_range 6, 9
1262         push_range 16, 27
1263         push_range 30, 31
1264         movw r6, r22
1265         movw r8, r24
1266         ldi r24, lo8(Xdbg_str)
1267         ldi r25, hi8(Xdbg_str)
1268         call cli_putstr_P
1269         mov r24, r9
1270         call cli_hexdump_byte
1271         mov r24, r8
1272         call cli_hexdump_byte
1273         mov r24, r7
1274         call cli_hexdump_byte
1275         mov r24, r6
1276         call cli_hexdump_byte
1277         pop_range 30, 31
1278         pop_range 16, 27
1279         pop_range 6, 9
1280         ret
1281
1282
1283 print_acc:
1284         push_range 16, 27
1285         push_range 30, 31
1286         ldi r24, lo8(Xdbg_str)
1287         ldi r25, hi8(Xdbg_str)
1288         call cli_putstr_P
1289         mov r24, r9
1290         call cli_hexdump_byte
1291         mov r24, r8
1292         call cli_hexdump_byte
1293         mov r24, r15
1294         call cli_hexdump_byte
1295         mov r24, r14
1296         call cli_hexdump_byte
1297         pop_range 30, 31
1298         pop_range 16, 27
1299         ret
1300
1301 #endif
1302