]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bmw/bmw_small-tinyasm.S
38a2a21f45886219592d1f45b02158049af4eacf
[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 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 bmw224_nextBlock
514 .global bmw256_nextBlock
515 bmw_small_nextBlock:
516 bmw224_nextBlock:
517 bmw256_nextBlock:
518         push_range  2, 7
519         push_range 28, 29
520         push_range  8, 17
521         stack_alloc_large 32*4, r28, r29
522         ldi r16, 0x4f
523         push r16
524         ldi r16, 0xff
525         push r16
526         push r16
527         ldi r16, 0xfb
528         push r16
529         adiw r28, 1
530 ;       push_range 28, 29 /* push Q */
531 ;       push_range 22, 25 /* push M & H */
532         /* increment counter */
533         movw r26, r24
534         movw r2, r26
535         adiw r26, 63
536         adiw r26,  1
537         rcall load_acc_from_X
538         ldi r19, 1
539         add acc0, r19
540         adc acc1, r1
541         adc acc2, r1
542         adc acc3, r1
543         rcall store_acc_to_dec_X
544         /* call f0 */
545         movw r30, r22
546         movw r26, r24
547 f0:
548         movw h0, r26
549         movw q0, r28
550         movw m0, r30
551         /* xor m into h */
552 ;       ldi r20, 64
553         rcall memxor_64
554         movw r30, m0
555         movw r26, h0
556
557         /* set q to zero */
558         ldi r22, 64
559 10:     st Y+, r1
560         dec r22
561         brne 10b
562         movw r28, q0
563         /* calculate W and store it in Q */
564         ldi r19, 5
565 30:
566         ldi r18, 16
567         /* load initial index */
568
569         /* load values from hacktable */
570         ldi r30, lo8(f0_hacktable-3)
571         ldi r31, hi8(f0_hacktable-3)
572         mov r16, r19
573         lsl r16
574         add r16, r19
575         add r30, r16
576         adc r31, r1
577         lpm r21, Z+
578         lpm r20, Z+
579         lpm r16, Z+
580 40:
581         ;call add_hx_to_w
582 add_hx_to_w:
583         movw r26, h0
584         add r26, r16
585         adc r27, r1
586         rcall load32_from_Y
587         sbiw r28, 4
588         lsl r20
589         rol r21
590         brcs 300f
591         /* addition */
592         rcall add_X_to_32
593         rjmp 500f
594 300: /* substract */
595         rcall load_acc_from_X
596         sub r22, acc0
597         sbc r23, acc1
598         sbc r24, acc2
599         sbc r25, acc3
600
601 500:
602         rcall store32_to_Y
603         subi r16, -4
604         andi r16, 0x0f<<2
605         dec r18
606         brne 40b
607         movw r28, q0
608         dec r19
609         brne 30b
610         movw r26, h0
611         /* xor m into h */
612 ;       ldi r20, 64
613         movw r26, h0
614         movw r30, m0
615         rcall memxor_64
616         sbiw r26, 60
617 ;---
618         clr r17
619         ldi r21, 15
620         mov r8, r21
621 50:
622         rcall load32_from_Y
623         sbiw r28, 4
624         mov r20, r17
625         rcall sn
626         inc r17
627         cpi r17, 5
628         brne 52f
629         clr r17
630 52:
631         rcall add_X_to_32
632         rcall store32_to_Y
633
634         dec r8
635         brne 50b
636 ;---
637         rcall load32_from_Y
638         clr r20
639         rcall sn
640         movw r26, h0
641         rcall add_X_to_32
642         sbiw r26, 4
643         sbiw r28, 4
644         rcall store32_to_Y
645         sbiw r28, 4
646         sbiw r28, 15*4
647         movw r20, h0
648         movw r22, m0
649
650         /* call f1*/
651         movw r2, r28
652 f1:
653         movw r4, r22
654         movw r6, r20
655         movw r26, r2
656         clr r24
657         rcall expand1
658         rcall restore_f1
659         ldi r24, 1
660         rcall expand1
661         ldi r17, 2
662 10: rcall restore_f1
663         mov r24, r17
664         rcall expand2
665         inc r17
666         sbrs r17, 4
667         rjmp 10b
668         rcall restore_f1
669         movw r24, r2
670
671
672         /* call f2 */
673 ;       pop_range 20, 25
674 ;       push_range 20, 25
675 ;       rcall printQ
676 ;       push r20
677 ;       push r21
678 acc2  =  8
679 acc3  =  9
680 acc0  = 14
681 acc1  = 15
682 xl0   =  2
683 xl1   =  3
684 xl2   =  4
685 xl3   =  5
686 xh0   =  6
687 xh1   =  7
688 xh2   = 10
689 xh3   = 11
690 q16_0 = 12
691 q16_1 = 13
692 h0   =  18
693 h1   =  19
694 f2:
695         movw r26, r24
696         /* calc XL & XH */
697         adiw r26, 63
698         adiw r26,  1
699         movw q16_0, r26
700         movw h0, r20
701 ;---
702 ;       push h0
703 ;       push h1
704 ;---
705         movw r28, r22
706         rcall load_acc_from_X
707         ldi r17, 15
708 10:     rcall load32_from_X
709         rcall eor32_to_acc
710         cpi r17, 9
711         brne 15f
712         movw xl0, acc0
713         movw xl2, acc2
714 15:
715         dec r17
716         brne 10b
717         movw xh0, acc0
718         movw xh2, acc2
719 ;--- DBG
720 ;       push_range 22, 25
721 ;       movw r22, xl0
722 ;       movw r24, xl2
723 ;       rcall print32
724 ;       movw r22, xh0
725 ;       movw r24, xh2
726 ;       rcall print32
727 ;       pop_range 22, 25
728 ;--- END DBG
729          /* copy m(Y) into h */
730         movw r26, h0
731         ldi r22, 64
732 10:
733         ld r23, Y+
734         st X+, r23
735         dec r22
736         brne 10b
737 ;--- /* calc first half of h0..h15 */
738         movw r28, q16_0
739         movw r26, h0
740         ldi r30, lo8(f2_1_shift_table)
741         ldi r31, hi8(f2_1_shift_table)
742         ldi r17, 16
743 10:
744 ;---
745         movw r22, xh0
746         movw r24, xh2
747         cpi r17, 9
748         brge 15f
749         clr r1
750         rjmp 26f
751 15:     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 mov32_to_acc
765 ;---
766         rcall load32_from_Y
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         ld r0, X
778         eor r0, acc0
779         st X+, r0
780         ld r0, X
781         eor r0, acc1
782         st X+, r0
783         ld r0, X
784         eor r0, acc2
785         st X+, r0
786         ld r0, X
787         eor r0, acc3
788         st X+, r0
789 ;---
790         dec r17
791         brne 10b
792 ;-----
793         sbiw r28, 4*8 /* Y points to q[24] */
794         movw r30, r28
795         sbiw r28, 63
796         sbiw r28, 33 /* Y points to q[0] */
797         movw r26, r28
798         ldi r20, 8*4
799         /* xor q[24..31] into q[0..7] */
800         rcall memxor
801         /* xor q[23] into q[8] */
802         sbiw r30, 9*4
803         ldi r20, 4
804         rcall memxor
805         /* xor q[16..22] into q[9..15] */
806         sbiw r30, 8*4
807         ldi r20, 7*4
808         rcall memxor
809
810         movw r26, h0
811         ldi r17, 15
812         ldi r30, lo8(f2_2_shift_table)
813         ldi r31, hi8(f2_2_shift_table)
814 10:     movw r22, xl0
815         movw r24, xl2
816         sbrc r17, 3
817         rjmp 20f
818         lpm r20, Z+
819         lsr r20
820         brcs 15f
821         rcall shiftright32
822         rjmp 20f
823 15:
824         rcall shiftleft32
825 20:
826         rcall mov32_to_acc
827         rcall load32_from_Y
828         rcall eor32_to_acc
829         rcall add_acc_to_X
830         dec r17
831         brpl 10b
832 ;-----
833         sbiw r26, 8*4 /* X points to h8 */
834         movw r28, r26
835         sbiw r28, 4*4 /* Y points to h4 */
836         ldi r17, 8
837         ldi r18, 9
838 10:
839         rcall load32_from_Y
840         mov r20, r18
841         rcall rotateleft32
842         rcall mov32_to_acc
843         rcall add_acc_to_X
844         inc r18
845         cpi r17, 5
846         brne 20f
847         sbiw r28, 8*4
848 20:     dec r17
849         brne 10b
850
851 exit:
852 ;--- DBG
853 ;       pop r25
854 ;       pop r24
855 ;       ldi r22, 'H'
856 ;       rcall printX
857 ;--- END DBG
858         stack_free_large3 32*4+4
859         pop_range 10, 17
860 pop9:
861         pop_range 8, 9
862 pop28:
863         pop_range 28, 29
864 pop7:
865         pop_range 6, 7
866 pop5:
867         pop_range 2, 5
868         ret
869
870 /******************************************************************************/
871 ctx0 =  2
872 ctx1 =  3
873 blc0 =  4
874 blc1 =  5
875 len0 = 28
876 len1 = 29
877 buf0 =  6
878 buf1 =  7
879
880 load32_from_Z_stub:
881         movw r30, ctx0
882         adiw r30, 60
883         ldd r21, Z+4
884         ldd r22, Z+5
885         ldd r23, Z+6
886         ldd r24, Z+7
887         ret
888
889 /******************************************************************************/
890 /*
891   param ctx:  r24:r25
892   param msg:  r22:r23
893   param len:  r20:r21
894 */
895
896 .global bmw_small_lastBlock
897 .global bmw224_lastBlock
898 .global bmw256_lastBlock
899 bmw_small_lastBlock:
900 bmw224_lastBlock:
901 bmw256_lastBlock:
902 /*      while(length_b >= BMW_SMALL_BLOCKSIZE){
903                 bmw_small_nextBlock(ctx, block);
904                 length_b -= BMW_SMALL_BLOCKSIZE;
905                 block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
906         }
907 */
908         push_range 2, 7
909         push_range 28, 29
910         movw ctx0, r24
911         movw blc0, r22
912         movw len0, r20
913 1:
914         cpi len1, hi8(512)
915         brlo 2f
916         rcall bmw_small_nextBlock_early
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         ldi r23, 63
936         movw r26, blc0
937         lsr r25
938         ror r24
939         lsr r24
940         lsr r24
941         breq 301f
942         sub r23, r24
943         /* copy (#r24) bytes to stack buffer */
944 30: ld r20, X+
945         st Z+, r20
946         dec r24
947         brne 30b
948 301: /* calculate the appended byte */
949         clr r20
950         mov r21, len0
951         ldi r24, 0x80
952         andi r21, 0x07
953         breq 305f
954         ld r20, X+
955 303:
956         lsr r24
957         dec r21
958         brne 303b
959 305:
960         or r20, r24
961         st Z+, r20
962         tst r23
963         breq 32f
964 31: st Z+, r1
965         dec r23
966         brne 31b
967 32:
968 /*      if(length_b+1>64*8-64){ ; = 64*7-1 = 447 max(length_b)=511
969                 bmw_small_nextBlock(ctx, pctx.buffer);
970                 memset(pctx.buffer, 0, 64-8);
971                 ctx->counter -= 1;
972         }
973 */
974         tst len1
975         breq 400f
976         cpi len0, 192
977         brlo 400f
978         movw blc0, buf0
979         rcall bmw_small_nextBlock_early
980         movw r26, buf0
981         ldi r20, 64-8
982 350:
983         st X+, r1
984         dec r20
985         brne 350b
986         rcall load32_from_Z_stub
987         subi r21, 1
988         sbc r22, r1
989         sbc r23, r1
990         sbc r24, r1
991         rjmp 410f
992 /*      *((uint64_t*)&(pctx.buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
993         bmw_small_nextBlock(ctx, pctx.buffer);
994 */
995 400:
996         rcall load32_from_Z_stub
997 410:
998         clr r25
999         ldi r20, 1
1000         lsl r21
1001         rcall rol32
1002         mov r20, len0
1003         add r21, len1
1004         adc r22, r1
1005         adc r23, r1
1006         adc r24, r1
1007         adc r25, r1
1008         movw r26, buf0
1009         adiw r26, 64-8
1010         st X+, r20
1011         st X+, r21
1012         rcall store32_to_X
1013         st X+, r1
1014         st X+, r1
1015         movw blc0, buf0
1016         rcall bmw_small_nextBlock_early
1017 /*      memset(pctx.buffer, 0xaa, 64);
1018         for(i=0; i<16;++i){
1019                 pctx.buffer[i*4] = i+0xa0;
1020         }
1021 */
1022         ldi r22, 0xa0
1023         ldi r23, 0xaa
1024         ldi r24, 0xaa
1025         ldi r25, 0xaa
1026         movw r26, buf0
1027 500:
1028         rcall store32_to_X
1029         inc r22
1030         sbrs r22, 4
1031         rjmp 500b
1032 /*      bmw_small_nextBlock((bmw_small_ctx_t*)&pctx, ctx->h);
1033         memcpy(ctx->h, pctx.buffer, 64);
1034 */
1035     movw r24, buf0
1036     movw r22, ctx0
1037     rcall bmw_small_nextBlock
1038         ldi r18, 64
1039         movw r26, ctx0
1040         movw r30, buf0
1041 600:
1042         ld r20, Z+
1043         st X+, r20
1044         dec r18
1045         brne 600b
1046
1047         stack_free_large 68
1048         rjmp pop28
1049
1050
1051 /*******************************************************************************
1052 * void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
1053 *       memcpy(dest, &(ctx->h[9]), 224/8);
1054 * }
1055 *
1056 * param dest:  r24:r25
1057 * param ctx:   r22:r23
1058 */
1059 .global bmw224_ctx2hash
1060 bmw224_ctx2hash:
1061         movw r30, r22
1062         adiw r30, 9*4
1063         ldi r18, 28
1064         rjmp 1f
1065
1066 /*******************************************************************************
1067 * void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
1068 *       memcpy(dest, &(ctx->h[8]), 256/8);
1069 * }
1070 *
1071 * param dest:  r24:r25
1072 * param ctx:   r22:r23
1073 */
1074 .global bmw256_ctx2hash
1075 bmw256_ctx2hash:
1076         movw r30, r22
1077         adiw r30, 8*4
1078         ldi r18, 32
1079 1:      movw r26, r24
1080 1:  ld r23, Z+
1081         st X+, r23
1082         dec r18
1083         brne 1b
1084         ret
1085
1086 /*******************************************************************************
1087 * void bmw256(void* dest, const void* msg, uint32_t length_b){
1088 *       bmw_small_ctx_t ctx;
1089 *       bmw256_init(&ctx);
1090 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1091 *               bmw_small_nextBlock(&ctx, msg);
1092 *               length_b -= BMW_SMALL_BLOCKSIZE;
1093 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1094 *       }
1095 *       bmw_small_lastBlock(&ctx, msg, length_b);
1096 *       bmw256_ctx2hash(dest, &ctx);
1097 * }
1098 *
1099 * param dest:     r24:r25
1100 * param msg:      r22:r23
1101 * param length_b: r18:r21
1102 */
1103 ctx0 =   2
1104 ctx1 =   3
1105 msg0 =   4
1106 msg1 =   5
1107 len0 =   6
1108 len1 =   7
1109 len2 =   8
1110 len3 =   9
1111 dst0 =  10
1112 dst1 =  11
1113 .global bmw256
1114 bmw256:
1115         set
1116         rjmp bmw_small_all
1117
1118
1119 /*******************************************************************************
1120 * void bmw224(void* dest, const void* msg, uint32_t length_b){
1121 *       bmw_small_ctx_t ctx;
1122 *       bmw224_init(&ctx);
1123 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1124 *               bmw_small_nextBlock(&ctx, msg);
1125 *               length_b -= BMW_SMALL_BLOCKSIZE;
1126 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1127 *       }
1128 *       bmw_small_lastBlock(&ctx, msg, length_b);
1129 *       bmw224_ctx2hash(dest, &ctx);
1130 * }
1131 *
1132 * param dest:     r24:r25
1133 * param msg:      r22:r23
1134 * param length_b: r18:r21
1135 */
1136 ctx0 =   2
1137 ctx1 =   3
1138 msg0 =   4
1139 msg1 =   5
1140 len0 =  28
1141 len1 =  29
1142 len2 =   8
1143 len3 =   9
1144 dst0 =   6
1145 dst1 =   7
1146 .global bmw224
1147 bmw224:
1148         clt
1149         rjmp bmw_small_all
1150
1151
1152 bmw_small_all:
1153         push_range 2, 7
1154         push_range 28, 29
1155         push_range 8, 9
1156         push r16
1157         stack_alloc_large 64+4
1158         adiw r30, 1
1159         clr r16
1160         brtc 10f
1161         inc r16
1162 10:     movw ctx0, r30
1163         movw dst0, r24
1164         movw msg0, r22
1165         movw len0, r18
1166         movw len2, r20
1167         movw r24, ctx0
1168         ldi r30, pm_lo8(init_lut)
1169         ldi r31, pm_hi8(init_lut)
1170         add r30, r16
1171         adc r31, r1
1172         icall
1173 20:
1174         mov r18, len2
1175         or  r18, len3
1176         breq 50f
1177         rcall bmw_small_nextBlock_early
1178         subi len1, 2
1179         sbc len2, r1
1180         sbc len3, r1
1181         ldi r20, 64
1182         add msg0, r20
1183         adc msg1, r1
1184         rjmp 20b
1185 50:
1186         movw r24, ctx0
1187         movw r22, msg0
1188         movw r20, len0
1189         rcall bmw_small_lastBlock
1190         movw r24, dst0
1191         movw r22, ctx0
1192         ldi r30, pm_lo8(c2h_lut)
1193         ldi r31, pm_hi8(c2h_lut)
1194         add r30, r16
1195         adc r31, r1
1196         icall
1197         stack_free_large 64+4
1198         pop r16
1199         rjmp pop9
1200
1201 init_lut:
1202         rjmp bmw224_init
1203         rjmp bmw256_init
1204 c2h_lut:
1205         rjmp bmw224_ctx2hash
1206         rjmp bmw256_ctx2hash
1207
1208 /*******************************************************************************
1209 * void bmw224_init(bmw224_ctx_t* ctx){
1210 *       uint8_t i;
1211 *       ctx->h[0] = 0x00010203;
1212 *       for(i=1; i<16; ++i){
1213 *               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
1214 *       }
1215 *       ctx->counter=0;
1216 * }
1217 *
1218 * param ctx:  r24:r25
1219 */
1220 .global bmw224_init
1221 bmw224_init:
1222         ldi r22, 0x00
1223         ldi r23, 0x40
1224 bmw_small_init:
1225         movw r26, r24
1226         adiw r26, 4
1227 10:
1228         st -X, r22
1229         inc r22
1230         mov r20, r22
1231         andi r20, 0x3
1232         brne 10b
1233         adiw r26, 8
1234 20: cp r22, r23
1235         brne 10b
1236         st -X, r1
1237         st -X, r1
1238         st -X, r1
1239         st -X, r1
1240         ret
1241
1242 .global bmw256_init
1243 bmw256_init:
1244         ldi r22, 0x40
1245         ldi r23, 0x80
1246         rjmp bmw_small_init
1247
1248
1249 /******************************************************************************/
1250
1251 #if DEBUG
1252
1253 printQ:
1254         push_range 20, 25
1255         ldi r16, 4
1256         mov r9, r16
1257         movw r16, r24
1258         ldi r24, lo8(qdbg_str)
1259         ldi r25, hi8(qdbg_str)
1260         call cli_putstr_P
1261         clr r8
1262 10:     ldi r24, lo8(qdbg_str1)
1263         ldi r25, hi8(qdbg_str1)
1264         call cli_putstr_P
1265         mov r24, r8
1266         call cli_hexdump_byte
1267         ldi r24, lo8(qdbg_str2)
1268         ldi r25, hi8(qdbg_str2)
1269         call cli_putstr_P
1270         movw r24, r16
1271         clr r23
1272         ldi r22, 4
1273         call cli_hexdump_rev
1274         add r16, r9
1275         adc r17, r1
1276         inc r8
1277         sbrs r8, 5
1278         rjmp 10b
1279         pop_range 20, 25
1280         ret
1281 qdbg_str:  .asciz "\r\nDBG Q: "
1282 qdbg_str1: .asciz "\r\n Q["
1283 qdbg_str2: .asciz "] =  "
1284
1285
1286 printX:
1287         push_range 6, 9
1288         push_range 16, 27
1289         push_range 30, 31
1290         ldi r16, 4
1291         mov r6, r22
1292         mov r9, r16
1293         movw r16, r24
1294         ldi r24, lo8(Xdbg_str)
1295         ldi r25, hi8(Xdbg_str)
1296         call cli_putstr_P
1297         mov r24, r6
1298         call cli_putc
1299         ldi r24, ':'
1300         call cli_putc
1301         clr r8
1302 10:     ldi r24, lo8(Xdbg_str1)
1303         ldi r25, hi8(Xdbg_str1)
1304         call cli_putstr_P
1305         mov r24, r6
1306         call cli_putc
1307         ldi r24, '['
1308         call cli_putc
1309         mov r24, r8
1310         call cli_hexdump_byte
1311         ldi r24, lo8(Xdbg_str2)
1312         ldi r25, hi8(Xdbg_str2)
1313         call cli_putstr_P
1314         movw r24, r16
1315         clr r23
1316         ldi r22, 4
1317         call cli_hexdump_rev
1318         add r16, r9
1319         adc r17, r1
1320         inc r8
1321         sbrs r8, 4
1322         rjmp 10b
1323         pop_range 30, 31
1324         pop_range 16, 27
1325         pop_range 6, 9
1326         ret
1327 Xdbg_str:  .asciz "\r\nDBG "
1328 Xdbg_str1: .asciz "\r\n "
1329 Xdbg_str2: .asciz "] = "
1330
1331 print32:
1332         push_range 6, 9
1333         push_range 16, 27
1334         push_range 30, 31
1335         movw r6, r22
1336         movw r8, r24
1337         ldi r24, lo8(Xdbg_str)
1338         ldi r25, hi8(Xdbg_str)
1339         call cli_putstr_P
1340         mov r24, r9
1341         call cli_hexdump_byte
1342         mov r24, r8
1343         call cli_hexdump_byte
1344         mov r24, r7
1345         call cli_hexdump_byte
1346         mov r24, r6
1347         call cli_hexdump_byte
1348         pop_range 30, 31
1349         pop_range 16, 27
1350         pop_range 6, 9
1351         ret
1352
1353
1354 print_acc:
1355         push_range 16, 27
1356         push_range 30, 31
1357         ldi r24, lo8(Xdbg_str)
1358         ldi r25, hi8(Xdbg_str)
1359         call cli_putstr_P
1360         mov r24, r9
1361         call cli_hexdump_byte
1362         mov r24, r8
1363         call cli_hexdump_byte
1364         mov r24, r15
1365         call cli_hexdump_byte
1366         mov r24, r14
1367         call cli_hexdump_byte
1368         pop_range 30, 31
1369         pop_range 16, 27
1370         ret
1371
1372 #endif
1373