]> git.cryptolib.org Git - avr-crypto-lib.git/blob - md5-asm.S
new MD5 ins ASM with C (working on pure ASM implementation) plus enhancments in asm...
[avr-crypto-lib.git] / md5-asm.S
1 /* md5-asm.S */
2 /*
3     This file is part of the Crypto-avr-lib/microcrypt-lib.
4     Copyright (C) 2008  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  * Author:  Daniel Otte
21  * License: GPLv3 or later
22  * Date:    2008-11-15
23 */
24
25 .include "avr-asm-macros.S"
26
27 ;###########################################################    
28 ; S-BOX
29
30 T_table:
31 .hword  0xa478, 0xd76a, 0xb756, 0xe8c7, 0x70db, 0x2420, 0xceee, 0xc1bd, 0x0faf, 0xf57c 
32 .hword  0xc62a, 0x4787, 0x4613, 0xa830, 0x9501, 0xfd46, 0x98d8, 0x6980, 0xf7af, 0x8b44 
33 .hword  0x5bb1, 0xffff, 0xd7be, 0x895c, 0x1122, 0x6b90, 0x7193, 0xfd98, 0x438e, 0xa679 
34 .hword  0x0821, 0x49b4, 0x2562, 0xf61e, 0xb340, 0xc040, 0x5a51, 0x265e, 0xc7aa, 0xe9b6 
35 .hword  0x105d, 0xd62f, 0x1453, 0x0244, 0xe681, 0xd8a1, 0xfbc8, 0xe7d3, 0xcde6, 0x21e1 
36 .hword  0x07d6, 0xc337, 0x0d87, 0xf4d5, 0x14ed, 0x455a, 0xe905, 0xa9e3, 0xa3f8, 0xfcef 
37 .hword  0x02d9, 0x676f, 0x4c8a, 0x8d2a, 0x3942, 0xfffa, 0xf681, 0x8771, 0x6122, 0x6d9d 
38 .hword  0x380c, 0xfde5, 0xea44, 0xa4be, 0xcfa9, 0x4bde, 0x4b60, 0xf6bb, 0xbc70, 0xbebf 
39 .hword  0x7ec6, 0x289b, 0x27fa, 0xeaa1, 0x3085, 0xd4ef, 0x1d05, 0x0488, 0xd039, 0xd9d4 
40 .hword  0x99e5, 0xe6db, 0x7cf8, 0x1fa2, 0x5665, 0xc4ac, 0x2244, 0xf429, 0xff97, 0x432a 
41 .hword  0x23a7, 0xab94, 0xa039, 0xfc93, 0x59c3, 0x655b, 0xcc92, 0x8f0c, 0xf47d, 0xffef 
42 .hword  0x5dd1, 0x8584, 0x7e4f, 0x6fa8, 0xe6e0, 0xfe2c, 0x4314, 0xa301, 0x11a1, 0x4e08 
43 .hword  0x7e82, 0xf753, 0xf235, 0xbd3a, 0xd2bb, 0x2ad7, 0xd391, 0xeb86
44
45
46 #define MD5_init_fast
47
48 .global md5_init 
49 #ifndef MD5_init_fast
50 ;###########################################################    
51 ;void md5_init(md5_ctx_t *state)
52 ; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
53 ; modifys: Z(r30,r31), X(r25,r26)
54 ; size = 9+5*4 WORDS = 29 WORDS = 58 Bytes
55 md5_init:
56         movw r26, r24 ; (24,25) --> (26,27) load X with param1
57         ldi r30, lo8(md5_init_vector)
58         ldi r31, hi8(md5_init_vector)
59         ldi r24, 16+4
60 md5_init_vloop: 
61         lpm r0, Z+ 
62         st X+, r0
63         dec r24
64         brne md5_init_vloop
65         ret
66         
67 md5_init_vector:
68 .hword 0x2301, 0x6745
69 .hword 0xAB89, 0xEFCD 
70 .hword 0xDCFE, 0x98BA 
71 .hword 0x5476, 0x1032 
72 .hword 0x0000, 0x0000
73
74 #else
75 ;###########################################################    
76 .global md5_init_fast 
77 ;void md5_init(md5_ctx_t *state)
78 ; param1: (r24,r25) 16-bit pointer to sha256_ctx_t struct in ram
79 ; modifys: r23, r22
80 ; cycles = 1+16*3+4*2+4 = 1+48+12 = 61
81 ; size = 1+16*2+4+1 WORDS = 38 WORDS = 76 Bytes
82 md5_init:
83 md5_init_fast:
84         movw r26, r24
85         ldi r24, 0x01
86         st X+, r24
87         ldi r24, 0x23
88         st X+, r24
89         ldi r24, 0x45
90         st X+, r24
91         ldi r24, 0x67
92         st X+, r24
93         ldi r24, 0x89
94         st X+, r24
95         ldi r24, 0xAB
96         st X+, r24
97         ldi r24, 0xCD
98         st X+, r24
99         ldi r24, 0xEF
100         st X+, r24
101         ldi r24, 0xFE
102         st X+, r24
103         ldi r24, 0xDC
104         st X+, r24
105         ldi r24, 0xBA
106         st X+, r24
107         ldi r24, 0x98
108         st X+, r24
109         ldi r24, 0x76
110         st X+, r24
111         ldi r24, 0x54
112         st X+, r24
113         ldi r24, 0x32
114         st X+, r24
115         ldi r24, 0x10
116         st X+, r24
117         st X+, r1
118         st X+, r1
119         st X+, r1
120         st X+, r1
121         ret
122 #endif
123 ;###########################################################    
124
125 /*
126 static 
127 uint32_t md5_F(uint32_t x, uint32_t y, uint32_t z){
128         return ((x&y)|((~x)&z));
129 }
130 */
131 ; x: r22-r25
132 ; y: r18-r21
133 ; z: r14-r17
134 md5_F:
135         and r18, r22
136         and r19, r23
137         and r20, r24
138         and r21, r25
139         com r22
140         com r23
141         com r24
142         com r25
143         and r22, r14
144         and r23, r15
145         and r24, r16
146         and r25, r17
147         or  r22, r18
148         or  r23, r19
149         or  r24, r20
150         or  r25, r21
151         rjmp md5_core_F_exit
152         
153 /*
154 static
155 uint32_t md5_G(uint32_t x, uint32_t y, uint32_t z){
156         return ((x&z)|((~z)&y));
157 }
158 */
159
160 ; x: r22-r25
161 ; y: r18-r21
162 ; z: r14-r17
163 md5_G:
164         and r22, r14
165         and r23, r15
166         and r24, r16
167         and r25, r17
168         com r14
169         com r15
170         com r16
171         com r17
172         and r18, r14
173         and r19, r15
174         and r20, r16
175         and r21, r17
176         or  r22, r18
177         or  r23, r19
178         or  r24, r20
179         or  r25, r21
180         rjmp md5_core_F_exit
181 /*
182 static
183 uint32_t md5_H(uint32_t x, uint32_t y, uint32_t z){
184         return (x^y^z);
185 }
186 */
187 ; x: r22-r25
188 ; y: r18-r21
189 ; z: r14-r17
190 md5_H:
191         eor r22, r18
192         eor r22, r14
193         eor r23, r19
194         eor r23, r15
195         eor r24, r20
196         eor r24, r16
197         eor r25, r21
198         eor r25, r17
199         rjmp md5_core_F_exit
200 /*
201 static
202 uint32_t md5_I(uint32_t x, uint32_t y, uint32_t z){
203         return (y ^ (x | (~z)));
204 }
205 */
206
207 jump_table:
208         rjmp md5_F
209         rjmp md5_G
210         rjmp md5_H
211 ;       rjmp md5_I
212
213 ; x: r22-r25
214 ; y: r18-r21
215 ; z: r14-r17
216 md5_I:
217         com r14
218         com r15
219         com r16
220         com r17
221         or  r22, r14
222         or  r23, r15
223         or  r24, r16
224         or  r25, r17
225         eor r22, r18
226         eor r23, r19
227         eor r24, r20
228         eor r25, r21
229         rjmp md5_core_F_exit
230
231 as_table:
232 ;     (as+0)&3  (as+3)&3  (as+1)&3  (as+2)&3
233 ;                  Z         X         Y
234 ;     AS_SAVE0  AS_SAVE1  AS_SAVE2  AS_SAVE3 
235 .byte   1*4,      0*4,      2*4,      3*4    ;as=1
236 .byte   2*4,      1*4,      3*4,      0*4    ;as=2
237 .byte   3*4,      2*4,      0*4,      1*4    ;as=3
238 .byte   0*4,      3*4,      1*4,      2*4    ;as=4
239
240 ;###########################################################    
241 .global md5_core
242 md5_core:
243         mov r21, r20
244         mov r20, r18
245         mov r19, r16
246         mov r18, r14
247 ;       rjmp md5_core_asm
248 /*
249 void md5_core(uint32_t* a, void* block, uint8_t as, uint8_t s, uint8_t i, uint8_t fi){
250         uint32_t t;
251         md5_func_t* funcs[]={md5_F, md5_G, md5_H, md5_I};
252         as &= 0x3;
253         / * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). * /
254         t = a[as] + funcs[fi](a[(as+1)&3], a[(as+2)&3], a[(as+3)&3]) + *((uint32_t*)block) + md5_T[i] ;
255         a[as]=a[(as+1)&3] + ROTL32(t, s);
256 }
257 */
258 ; a:     r24-r25
259 ; block: r22-r23
260 ; as:    r21
261 ; s:     r20
262 ; i:     r19
263 ; fi:    r18
264 P_A0 = 24
265 P_A1 = 25
266 P_B0 = 22
267 P_B1 = 23
268 P_AS = 21
269 P_S  = 20
270 P_I  = 19
271 P_FI = 18
272
273 ; x: r22-r25
274 ; y: r18-r21
275 ; z: r14-r17
276
277
278 AS_SAVE0  =  4
279 AS_SAVE1  =  5
280 AS_SAVE2  =  6
281 AS_SAVE3  =  7
282 FI_SAVE   =  8
283 S_SAVE    =  9
284 ACCU0     = 10
285 ACCU1     = 11
286 ACCU2     = 12
287 ACCU3     = 13
288 ARG_X0    = 22
289 ARG_X1    = 23
290 ARG_X2    = 24
291 ARG_X3    = 25
292 ARG_Y0    = 18
293 ARG_Y1    = 19
294 ARG_Y2    = 20
295 ARG_Y3    = 21
296 ARG_Z0    = 14
297 ARG_Z1    = 15
298 ARG_Z2    = 16
299 ARG_Z3    = 17
300
301
302 md5_core_asm:
303         push r28
304         push r29
305         push_range 4, 17
306         ldi r30, lo8(T_table)
307         ldi r31, hi8(T_table)
308         lsl P_I
309         rol r1
310         lsl P_I
311         rol r1
312         add r30, P_I
313         adc r31, r1
314         clr r1
315         mov FI_SAVE, r18
316         /* loading T[i] into ACCU */    
317         lpm ACCU0, Z+   
318         lpm ACCU1, Z+   
319         lpm ACCU2, Z+   
320         lpm ACCU3, Z
321         /* add *block to ACCU */
322         movw r30, P_B0
323         ld r0, Z+
324         add ACCU0, r0
325         ld r0, Z+
326         adc ACCU1, r0
327         ld r0, Z+
328         adc ACCU2, r0
329         ld r0, Z+
330         adc ACCU3, r0
331         /* add a[as+0&3] to ACCU */
332         ldi r30, lo8(as_table)
333         ldi r31, hi8(as_table)
334         dec P_AS
335         andi P_AS, 0x03
336         lsl P_AS
337         lsl P_AS
338         add r30, r21
339         adc r31, r1       ; Z points to the correct row in as_table
340         lpm AS_SAVE0, Z+
341         lpm AS_SAVE1, Z+
342         lpm AS_SAVE2, Z+
343         lpm AS_SAVE3, Z
344         movw r26, r24     ; X points to a[0]
345         add r26, AS_SAVE0
346         adc r27, r1       ; X points at a[as&3]
347         ld r0, X+
348         add ACCU0, r0
349         ld r0, X+
350         adc ACCU1, r0
351         ld r0, X+
352         adc ACCU2, r0
353         ld r0, X+
354         adc ACCU3, r0
355         mov S_SAVE, r20
356
357         movw r28, r24
358         /* loading z value */
359         movw r26, r28
360         add r26, AS_SAVE1
361         adc r27, r1
362         ld ARG_Z0, X+
363         ld ARG_Z1, X+
364         ld ARG_Z2, X+
365         ld ARG_Z3, X
366
367         /* loading x value */
368         movw r26, r28   
369         add r26, AS_SAVE2
370         adc r27, r1
371         ld ARG_X0, X+
372         ld ARG_X1, X+
373         ld ARG_X2, X+
374         ld ARG_X3, X
375
376         /* loading y value */
377         movw r26, r28
378         add r26, AS_SAVE3
379         adc r27, r1
380         ldi r30, pm_lo8(jump_table)
381         ldi r31, pm_hi8(jump_table)
382         add r30, FI_SAVE
383         adc r31, r1    ; Z points to the correct entry in our jump table
384         ld ARG_Y0, X+
385         ld ARG_Y1, X+
386         ld ARG_Y2, X+
387         ld ARG_Y3, X
388
389         ijmp /* calls the function pointed by Z */
390 md5_core_F_exit:                
391
392         /* add ACCU to result of f() */
393         add r22, ACCU0
394         adc r23, ACCU1
395         adc r24, ACCU2
396         adc r25, ACCU3
397
398         /* rotate */
399         mov r20, S_SAVE
400 rotl32:
401         cpi r20, 8
402         brlo bitrotl
403         mov r21, r25
404         mov r25, r24
405         mov r24, r23
406         mov r23, r22
407         mov r22, r21
408         subi r20, 8
409         rjmp rotl32
410 bitrotl:
411         mov r21, r25
412 bitrotl_loop:   
413         tst r20
414         breq fixrotl
415 bitrotl_loop2:  
416         lsl r21
417         rol r22
418         rol r23
419         rol r24
420         rol r25
421         dec r20
422         brne bitrotl_loop2
423 fixrotl:
424
425         /* add a[(as+1)&3]  */
426         movw r26, r28
427         add r26, AS_SAVE2
428         adc r27, r1
429         ld r0, X+
430         add r22, r0
431         ld r0, X+
432         adc r23, r0
433         ld r0, X+
434         adc r24, r0
435         ld r0, X
436         adc r25, r0
437
438         /* store result */
439         movw r26, r28
440         add r26, AS_SAVE0
441         adc r27, r1
442         st X+, r22
443         st X+, r23
444         st X+, r24
445         st X , r25      
446 md5_core_exit:
447         pop_range 4, 17
448         pop r29
449         pop r28
450         ret
451
452 ;###################################################################
453 /*
454 void md5_nextBlock(md5_ctx_t *state, void* block){
455         uint32_t        a[4];
456         uint8_t         m,n,i=0;
457
458         a[0]=state->a[0];
459         a[1]=state->a[1];
460         a[2]=state->a[2];
461         a[3]=state->a[3];
462         
463         / * round 1 * /
464         uint8_t s1t[]={7,12,17,22}; // 1,-1   1,4   2,-1   3,-2
465         for(m=0;m<4;++m){
466                 for(n=0;n<4;++n){
467                         md5_core(a, &(((uint32_t*)block)[m*4+n]), 4-n, s1t[n],i++,0);
468                 }
469         }
470         / * round 2 * /
471         uint8_t s2t[]={5,9,14,20}; // 1,-3   1,1   2,-2   2,4
472         for(m=0;m<4;++m){
473                 for(n=0;n<4;++n){
474                         md5_core(a, &(((uint32_t*)block)[(1+m*4+n*5)&0xf]), 4-n, s2t[n],i++,1);
475                 }
476         }
477         / * round 3 * /
478         uint8_t s3t[]={4,11,16,23}; // 0,4   1,3   2,0   3,-1
479         for(m=0;m<4;++m){
480                 for(n=0;n<4;++n){
481                         md5_core(a, &(((uint32_t*)block)[(5-m*4+n*3)&0xf]), 4-n, s3t[n],i++,2);
482                 }
483         }
484         / * round 4 * /
485         uint8_t s4t[]={6,10,15,21}; // 1,-2   1,2   2,-1   3,-3
486         for(m=0;m<4;++m){
487                 for(n=0;n<4;++n){
488                         md5_core(a, &(((uint32_t*)block)[(0-m*4+n*7)&0xf]), 4-n, s4t[n],i++,3);
489                 }
490         }
491         state->a[0] += a[0];
492         state->a[1] += a[1];
493         state->a[2] += a[2];
494         state->a[3] += a[3];
495         state->counter++;
496 }
497 */
498 /*
499 shift_table:
500  .byte  7,12,17,22
501  .byte  5, 9,14,20
502  .byte  4,11,16,23
503  .byte  6,10,15,21
504
505 md5_nextBlock:
506         stack_alloc 4*4
507
508
509
510
511         stack_free 4*4
512
513
514 */
515
516
517
518
519
520
521