]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bmw/bmw_small-tinyasm.S
bmw tiny split up
[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         rcall load32_from_X
778         rcall eor32_to_acc
779         rcall store_acc_to_dec_X
780         adiw r26, 4
781 ;---
782         dec r17
783         brne 10b
784 ;-----
785         sbiw r28, 4*8 /* Y points to q[24] */
786         movw r30, r28
787         sbiw r28, 63
788         sbiw r28, 33 /* Y points to q[0] */
789         movw r26, r28
790         ldi r20, 8*4
791         /* xor q[24..31] into q[0..7] */
792         rcall memxor
793         /* xor q[23] into q[8] */
794         sbiw r30, 9*4
795         ldi r20, 4
796         rcall memxor
797         /* xor q[16..22] into q[9..15] */
798         sbiw r30, 8*4
799         ldi r20, 7*4
800         rcall memxor
801
802         movw r26, h0
803         ldi r17, 15
804         ldi r30, lo8(f2_2_shift_table)
805         ldi r31, hi8(f2_2_shift_table)
806 10:     movw r22, xl0
807         movw r24, xl2
808         sbrc r17, 3
809         rjmp 20f
810         lpm r20, Z+
811         lsr r20
812         brcs 15f
813         rcall shiftright32
814         rjmp 20f
815 15:
816         rcall shiftleft32
817 20:
818         rcall mov32_to_acc
819         rcall load32_from_Y
820         rcall eor32_to_acc
821         rcall add_acc_to_X
822         dec r17
823         brpl 10b
824 ;-----
825         sbiw r26, 8*4 /* X points to h8 */
826         movw r28, r26
827         sbiw r28, 4*4 /* Y points to h4 */
828         ldi r17, 8
829         ldi r18, 9
830 10:
831         rcall load32_from_Y
832         mov r20, r18
833         rcall rotateleft32
834         rcall mov32_to_acc
835         rcall add_acc_to_X
836         inc r18
837         cpi r17, 5
838         brne 20f
839         sbiw r28, 8*4
840 20:     dec r17
841         brne 10b
842
843 exit:
844 ;--- DBG
845 ;       pop r25
846 ;       pop r24
847 ;       ldi r22, 'H'
848 ;       rcall printX
849 ;--- END DBG
850         stack_free_large3 32*4+4
851         pop_range 10, 17
852 pop9:
853         pop_range 8, 9
854 pop28:
855         pop_range 28, 29
856 pop7:
857         pop_range 6, 7
858 pop5:
859         pop_range 2, 5
860         ret
861
862 /******************************************************************************/
863 ctx0 =  2
864 ctx1 =  3
865 blc0 =  4
866 blc1 =  5
867 len0 = 28
868 len1 = 29
869 buf0 =  6
870 buf1 =  7
871
872 load32_from_Z_stub:
873         movw r30, ctx0
874         adiw r30, 60
875         ldd r21, Z+4
876         ldd r22, Z+5
877         ldd r23, Z+6
878         ldd r24, Z+7
879         ret
880
881 /******************************************************************************/
882 /*
883   param ctx:  r24:r25
884   param msg:  r22:r23
885   param len:  r20:r21
886 */
887
888 .global bmw_small_lastBlock
889 .global bmw224_lastBlock
890 .global bmw256_lastBlock
891 bmw_small_lastBlock:
892 bmw224_lastBlock:
893 bmw256_lastBlock:
894 /*      while(length_b >= BMW_SMALL_BLOCKSIZE){
895                 bmw_small_nextBlock(ctx, block);
896                 length_b -= BMW_SMALL_BLOCKSIZE;
897                 block = (uint8_t*)block + BMW_SMALL_BLOCKSIZE_B;
898         }
899 */
900         push_range 2, 7
901         push_range 28, 29
902         movw ctx0, r24
903         movw blc0, r22
904         movw len0, r20
905 1:
906         cpi len1, hi8(512)
907         brlo 2f
908         rcall bmw_small_nextBlock_early
909         ldi r24, 64
910         add blc0, r24
911         adc blc1, r1
912         subi len1, hi8(512)
913         rjmp 1b
914 2:
915 /*      struct {
916                 uint8_t  buffer[64];
917                 uint32_t ctr;
918         } pctx;
919 */
920         stack_alloc_large 68
921         adiw r30, 1
922         movw buf0, r30
923 /*      memset(pctx.buffer, 0, 64);
924         memcpy(pctx.buffer, block, (length_b+7)/8);
925         pctx.buffer[length_b>>3] |= 0x80 >> (length_b&0x07);
926 */      movw r24, len0
927         ldi r23, 63
928         movw r26, blc0
929         lsr r25
930         ror r24
931         lsr r24
932         lsr r24
933         breq 301f
934         sub r23, r24
935         /* copy (#r24) bytes to stack buffer */
936 30: ld r20, X+
937         st Z+, r20
938         dec r24
939         brne 30b
940 301: /* calculate the appended byte */
941         clr r20
942         mov r21, len0
943         ldi r24, 0x80
944         andi r21, 0x07
945         breq 305f
946         ld r20, X+
947 303:
948         lsr r24
949         dec r21
950         brne 303b
951 305:
952         or r20, r24
953         st Z+, r20
954         tst r23
955         breq 32f
956 31: st Z+, r1
957         dec r23
958         brne 31b
959 32:
960 /*      if(length_b+1>64*8-64){ ; = 64*7-1 = 447 max(length_b)=511
961                 bmw_small_nextBlock(ctx, pctx.buffer);
962                 memset(pctx.buffer, 0, 64-8);
963                 ctx->counter -= 1;
964         }
965 */
966         tst len1
967         breq 400f
968         cpi len0, 192
969         brlo 400f
970         movw blc0, buf0
971         rcall bmw_small_nextBlock_early
972         movw r26, buf0
973         ldi r20, 64-8
974 350:
975         st X+, r1
976         dec r20
977         brne 350b
978         rcall load32_from_Z_stub
979         subi r21, 1
980         sbc r22, r1
981         sbc r23, r1
982         sbc r24, r1
983         rjmp 410f
984 /*      *((uint64_t*)&(pctx.buffer[64-8])) = (uint64_t)(ctx->counter*512LL)+(uint64_t)length_b;
985         bmw_small_nextBlock(ctx, pctx.buffer);
986 */
987 400:
988         rcall load32_from_Z_stub
989 410:
990         clr r25
991         ldi r20, 1
992         lsl r21
993         rcall rol32
994         mov r20, len0
995         add r21, len1
996         adc r22, r1
997         adc r23, r1
998         adc r24, r1
999         adc r25, r1
1000         movw r26, buf0
1001         adiw r26, 64-8
1002         st X+, r20
1003         st X+, r21
1004         rcall store32_to_X
1005         st X+, r1
1006         st X+, r1
1007         movw blc0, buf0
1008         rcall bmw_small_nextBlock_early
1009 /*      memset(pctx.buffer, 0xaa, 64);
1010         for(i=0; i<16;++i){
1011                 pctx.buffer[i*4] = i+0xa0;
1012         }
1013 */
1014         ldi r22, 0xa0
1015         ldi r23, 0xaa
1016         ldi r24, 0xaa
1017         ldi r25, 0xaa
1018         movw r26, buf0
1019 500:
1020         rcall store32_to_X
1021         inc r22
1022         sbrs r22, 4
1023         rjmp 500b
1024 /*      bmw_small_nextBlock((bmw_small_ctx_t*)&pctx, ctx->h);
1025         memcpy(ctx->h, pctx.buffer, 64);
1026 */
1027     movw r24, buf0
1028     movw r22, ctx0
1029     rcall bmw_small_nextBlock
1030         ldi r18, 64
1031         movw r26, ctx0
1032         movw r30, buf0
1033 600:
1034         ld r20, Z+
1035         st X+, r20
1036         dec r18
1037         brne 600b
1038
1039         stack_free_large 68
1040         rjmp pop28
1041
1042
1043 /*******************************************************************************
1044 * void bmw224_ctx2hash(void* dest, const bmw224_ctx_t* ctx){
1045 *       memcpy(dest, &(ctx->h[9]), 224/8);
1046 * }
1047 *
1048 * param dest:  r24:r25
1049 * param ctx:   r22:r23
1050 */
1051 .global bmw224_ctx2hash
1052 bmw224_ctx2hash:
1053         movw r30, r22
1054         adiw r30, 9*4
1055         ldi r18, 28
1056         rjmp 1f
1057
1058 /*******************************************************************************
1059 * void bmw256_ctx2hash(void* dest, const bmw256_ctx_t* ctx){
1060 *       memcpy(dest, &(ctx->h[8]), 256/8);
1061 * }
1062 *
1063 * param dest:  r24:r25
1064 * param ctx:   r22:r23
1065 */
1066 .global bmw256_ctx2hash
1067 bmw256_ctx2hash:
1068         movw r30, r22
1069         adiw r30, 8*4
1070         ldi r18, 32
1071 1:      movw r26, r24
1072 1:  ld r23, Z+
1073         st X+, r23
1074         dec r18
1075         brne 1b
1076         ret
1077
1078 /*******************************************************************************
1079 * void bmw256(void* dest, const void* msg, uint32_t length_b){
1080 *       bmw_small_ctx_t ctx;
1081 *       bmw256_init(&ctx);
1082 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1083 *               bmw_small_nextBlock(&ctx, msg);
1084 *               length_b -= BMW_SMALL_BLOCKSIZE;
1085 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1086 *       }
1087 *       bmw_small_lastBlock(&ctx, msg, length_b);
1088 *       bmw256_ctx2hash(dest, &ctx);
1089 * }
1090 *
1091 * param dest:     r24:r25
1092 * param msg:      r22:r23
1093 * param length_b: r18:r21
1094 */
1095 ctx0 =   2
1096 ctx1 =   3
1097 msg0 =   4
1098 msg1 =   5
1099 len0 =   6
1100 len1 =   7
1101 len2 =   8
1102 len3 =   9
1103 dst0 =  10
1104 dst1 =  11
1105 .global bmw256
1106 bmw256:
1107         set
1108         rjmp bmw_small_all
1109
1110
1111 /*******************************************************************************
1112 * void bmw224(void* dest, const void* msg, uint32_t length_b){
1113 *       bmw_small_ctx_t ctx;
1114 *       bmw224_init(&ctx);
1115 *       while(length_b>=BMW_SMALL_BLOCKSIZE){
1116 *               bmw_small_nextBlock(&ctx, msg);
1117 *               length_b -= BMW_SMALL_BLOCKSIZE;
1118 *               msg = (uint8_t*)msg + BMW_SMALL_BLOCKSIZE_B;
1119 *       }
1120 *       bmw_small_lastBlock(&ctx, msg, length_b);
1121 *       bmw224_ctx2hash(dest, &ctx);
1122 * }
1123 *
1124 * param dest:     r24:r25
1125 * param msg:      r22:r23
1126 * param length_b: r18:r21
1127 */
1128 ctx0 =   2
1129 ctx1 =   3
1130 msg0 =   4
1131 msg1 =   5
1132 len0 =  28
1133 len1 =  29
1134 len2 =   8
1135 len3 =   9
1136 dst0 =   6
1137 dst1 =   7
1138 .global bmw224
1139 bmw224:
1140         clt
1141
1142
1143 bmw_small_all:
1144         push_range 2, 7
1145         push_range 28, 29
1146         push_range 8, 9
1147         push r16
1148         stack_alloc_large 64+4
1149         adiw r30, 1
1150         clr r16
1151         brtc 10f
1152         inc r16
1153 10:     movw ctx0, r30
1154         movw dst0, r24
1155         movw msg0, r22
1156         movw len0, r18
1157         movw len2, r20
1158         movw r24, ctx0
1159         ldi r30, pm_lo8(init_lut)
1160         ldi r31, pm_hi8(init_lut)
1161         add r30, r16
1162         adc r31, r1
1163         icall
1164 20:
1165         mov r18, len2
1166         or  r18, len3
1167         breq 50f
1168         rcall bmw_small_nextBlock_early
1169         subi len1, 2
1170         sbc len2, r1
1171         sbc len3, r1
1172         ldi r20, 64
1173         add msg0, r20
1174         adc msg1, r1
1175         rjmp 20b
1176 50:
1177         movw r24, ctx0
1178         movw r22, msg0
1179         movw r20, len0
1180         rcall bmw_small_lastBlock
1181         movw r24, dst0
1182         movw r22, ctx0
1183         ldi r30, pm_lo8(c2h_lut)
1184         ldi r31, pm_hi8(c2h_lut)
1185         add r30, r16
1186         adc r31, r1
1187         icall
1188         stack_free_large 64+4
1189         pop r16
1190         rjmp pop9
1191
1192 init_lut:
1193         rjmp bmw224_init
1194         rjmp bmw256_init
1195 c2h_lut:
1196         rjmp bmw224_ctx2hash
1197         rjmp bmw256_ctx2hash
1198
1199 /*******************************************************************************
1200 * void bmw224_init(bmw224_ctx_t* ctx){
1201 *       uint8_t i;
1202 *       ctx->h[0] = 0x00010203;
1203 *       for(i=1; i<16; ++i){
1204 *               ctx->h[i] = ctx->h[i-1]+ 0x04040404;
1205 *       }
1206 *       ctx->counter=0;
1207 * }
1208 *
1209 * param ctx:  r24:r25
1210 */
1211 .global bmw224_init
1212 bmw224_init:
1213         ldi r22, 0x00
1214         ldi r23, 0x40
1215 bmw_small_init:
1216         movw r26, r24
1217         adiw r26, 4
1218 10:
1219         st -X, r22
1220         inc r22
1221         mov r20, r22
1222         andi r20, 0x3
1223         brne 10b
1224         adiw r26, 8
1225 20: cp r22, r23
1226         brne 10b
1227         st -X, r1
1228         st -X, r1
1229         st -X, r1
1230         st -X, r1
1231         ret
1232
1233 .global bmw256_init
1234 bmw256_init:
1235         ldi r22, 0x40
1236         ldi r23, 0x80
1237         rjmp bmw_small_init
1238
1239
1240 /******************************************************************************/
1241
1242 #if DEBUG
1243
1244 printQ:
1245         push_range 20, 25
1246         ldi r16, 4
1247         mov r9, r16
1248         movw r16, r24
1249         ldi r24, lo8(qdbg_str)
1250         ldi r25, hi8(qdbg_str)
1251         call cli_putstr_P
1252         clr r8
1253 10:     ldi r24, lo8(qdbg_str1)
1254         ldi r25, hi8(qdbg_str1)
1255         call cli_putstr_P
1256         mov r24, r8
1257         call cli_hexdump_byte
1258         ldi r24, lo8(qdbg_str2)
1259         ldi r25, hi8(qdbg_str2)
1260         call cli_putstr_P
1261         movw r24, r16
1262         clr r23
1263         ldi r22, 4
1264         call cli_hexdump_rev
1265         add r16, r9
1266         adc r17, r1
1267         inc r8
1268         sbrs r8, 5
1269         rjmp 10b
1270         pop_range 20, 25
1271         ret
1272 qdbg_str:  .asciz "\r\nDBG Q: "
1273 qdbg_str1: .asciz "\r\n Q["
1274 qdbg_str2: .asciz "] =  "
1275
1276
1277 printX:
1278         push_range 6, 9
1279         push_range 16, 27
1280         push_range 30, 31
1281         ldi r16, 4
1282         mov r6, r22
1283         mov r9, r16
1284         movw r16, r24
1285         ldi r24, lo8(Xdbg_str)
1286         ldi r25, hi8(Xdbg_str)
1287         call cli_putstr_P
1288         mov r24, r6
1289         call cli_putc
1290         ldi r24, ':'
1291         call cli_putc
1292         clr r8
1293 10:     ldi r24, lo8(Xdbg_str1)
1294         ldi r25, hi8(Xdbg_str1)
1295         call cli_putstr_P
1296         mov r24, r6
1297         call cli_putc
1298         ldi r24, '['
1299         call cli_putc
1300         mov r24, r8
1301         call cli_hexdump_byte
1302         ldi r24, lo8(Xdbg_str2)
1303         ldi r25, hi8(Xdbg_str2)
1304         call cli_putstr_P
1305         movw r24, r16
1306         clr r23
1307         ldi r22, 4
1308         call cli_hexdump_rev
1309         add r16, r9
1310         adc r17, r1
1311         inc r8
1312         sbrs r8, 4
1313         rjmp 10b
1314         pop_range 30, 31
1315         pop_range 16, 27
1316         pop_range 6, 9
1317         ret
1318 Xdbg_str:  .asciz "\r\nDBG "
1319 Xdbg_str1: .asciz "\r\n "
1320 Xdbg_str2: .asciz "] = "
1321
1322 print32:
1323         push_range 6, 9
1324         push_range 16, 27
1325         push_range 30, 31
1326         movw r6, r22
1327         movw r8, r24
1328         ldi r24, lo8(Xdbg_str)
1329         ldi r25, hi8(Xdbg_str)
1330         call cli_putstr_P
1331         mov r24, r9
1332         call cli_hexdump_byte
1333         mov r24, r8
1334         call cli_hexdump_byte
1335         mov r24, r7
1336         call cli_hexdump_byte
1337         mov r24, r6
1338         call cli_hexdump_byte
1339         pop_range 30, 31
1340         pop_range 16, 27
1341         pop_range 6, 9
1342         ret
1343
1344
1345 print_acc:
1346         push_range 16, 27
1347         push_range 30, 31
1348         ldi r24, lo8(Xdbg_str)
1349         ldi r25, hi8(Xdbg_str)
1350         call cli_putstr_P
1351         mov r24, r9
1352         call cli_hexdump_byte
1353         mov r24, r8
1354         call cli_hexdump_byte
1355         mov r24, r15
1356         call cli_hexdump_byte
1357         mov r24, r14
1358         call cli_hexdump_byte
1359         pop_range 30, 31
1360         pop_range 16, 27
1361         ret
1362
1363 #endif
1364