]> git.cryptolib.org Git - avr-crypto-lib.git/blob - xtea-asm.S
35063f21257174bc35975f8c2fa43dc90032d3e3
[avr-crypto-lib.git] / xtea-asm.S
1 /* xtea-asm.S 
2  * Author:      Daniel Otte
3  * Date:                06.06.2006
4  * License: GPL
5  *  Implementation of XTEA for AVR
6  *  include xtea.h in your C-Project to use this functions.
7 */
8
9 V01 = 2
10 V02 = 3
11 V03 = 4
12 V04 = 5
13 V11 = 6
14 V12 = 7
15 V13 = 8
16 V14 = 9
17 Accu1 = 14
18 Accu2 = 15
19 Accu3 = 16
20 Accu4 = 17
21 Sum1 = 18
22 Sum2 = 19
23 Sum3 = 20
24 Sum4 = 21
25 Func1 = 22
26 Func2 = 23
27 Func3 = 24
28 Func4 = 25
29 C = 28 /* der kleine Zaehler fuer zwischendurch */
30
31 .global xtea_enc
32 ; == xtea_enc ==
33 ; xtea encrytion function
34 ; param1: 16-bit pointer to destination for encrypted block 
35 ;  given in r25,r24
36 ; param2: 16-bit pointer to the block (64-bit) which is to encrypt 
37 ;  given in r23,r22
38 ; param3: 16-bit pointer to the key (128-bit) 
39 ;  given in r21,r20
40 ;
41 xtea_enc:
42  /* prolog */
43         push r2
44         push r3
45         push r4
46         push r5
47         push r6
48         push r7
49         push r8
50         push r9
51         push r14
52         push r15
53         push r16
54         push r17
55         push r28
56         
57  /* load the block */
58         movw r26, r22 /* X points to block */
59         movw r30, r20 /* Z points to key   */
60         ld V01, X+
61         ld V02, X+
62         ld V03, X+
63         ld V04, X+
64         ld V11, X+
65         ld V12, X+
66         ld V13, X+
67         ld V14, X+
68 ;       push r25
69 ;       push r24
70         movw r26, r24 /* X points to destination */
71  
72         ldi Func1, 32
73         mov r0, Func1 /* r1 is cycle-counter */
74         clr Sum1
75         clr Sum2
76         movw Sum3, Sum1
77         clt
78
79 1:
80         movw Accu1, V11
81         movw Accu3, V13
82         ldi C, 4
83 2:      lsl Accu1
84         rol Accu2
85         rol Accu3
86         rol Accu4
87         dec C
88         brne 2b                 /* Accu == V1 << 4 */
89
90         movw Func1, V11
91         movw Func3, V13
92         ldi C, 5
93 3:      lsr Func4
94         ror Func3
95         ror Func2
96         ror Func1
97         dec C
98         brne 3b                 /* Func == V1 >> 5 */
99         
100         eor Accu1, Func1
101         eor Accu2, Func2
102         eor Accu3, Func3
103         eor Accu4, Func4
104         add Accu1, V11
105         adc Accu2, V12
106         adc Accu3, V13
107         adc Accu4, V14  /* Accu == ( (V1<<4)^(V1>>5) ) + V1 */
108         
109         brtc 4f
110         mov C, Sum2
111         lsr C
112         andi C,(0x03 <<2)
113         clt
114         rjmp 5f
115 4:      
116         mov C, Sum1     /* calc key offset */
117         andi C, 0x03
118         lsl C
119         lsl C
120         set
121         
122 5:      
123         add r30, C
124         adc r31, r1
125         ld  Func1, Z
126         ldd Func2, Z+1
127         ldd Func3, Z+2
128         ldd Func4, Z+3 /* Func = key[sum & 3] */
129         sub r30, C
130         sbci r31, 0
131         add Func1, Sum1
132         adc Func2, Sum2
133         adc Func3, Sum3
134         adc Func4, Sum4 
135         eor Accu1, Func1
136         eor Accu2, Func2
137         eor Accu3, Func3
138         eor Accu4, Func4 /* Accu = ((V1<<4 ^ V1>>5) + V1) ^ (sum + key[sum&3])  */
139         add Accu1, V01
140         adc Accu2, V02
141         adc Accu3, V03
142         adc Accu4, V04
143         
144         movw V01, V11
145         movw V03, V13
146         movw V11, Accu1
147         movw V13, Accu3
148         
149         /* sum += delta */ /* delta == 0x9E3779B9 */
150         brtc 6f
151         ldi C, 0xB9
152         add Sum1, C
153         ldi C, 0x79
154         adc Sum2, C
155         ldi C, 0x37
156         adc Sum3, C
157         ldi C, 0x9E
158         adc Sum4, C
159         rjmp 1b
160         
161 6:      
162         dec r0
163         breq 7f
164         rjmp 1b 
165  
166  7:
167  /* write block back */
168  ;      pop r26
169  ;      pop r27
170         st X+, V01
171         st X+, V02
172         st X+, V03
173         st X+, V04
174         st X+, V11
175         st X+, V12
176         st X+, V13
177         st X+, V14
178  
179  /* epilog */
180         pop r28
181         pop r17
182         pop r16
183         pop r15
184         pop r14
185         pop r9
186         pop r8
187         pop r7
188         pop r6
189         pop r5
190         pop r4
191         pop r3
192         pop r2
193         ret
194
195 ;####################################################################
196  
197  /* #endif TWO_IN_ONE */        
198  
199  /* #ifdef TWO_IN_ONE */
200  /* now we use the same base-structure for enc- and decryption
201         to indicate operation mode we use the highest bit of param3 (16 bit pointer to key),
202         this is ok, since even the larges atmel today has "only" 8k of ram,
203         but you shouldn't use this feature while using external ram. 
204  */
205 .global xtea_enc
206         ori r21, 0x80
207         
208 .global xtea_dec
209 ; == xtea_dec ==
210 ; xtea decrytion function
211 ; param1: 16-bit pointer to destination for decrypted block 
212 ;  given in r25,r24
213 ; param2: 16-bit pointer to the block (64-bit) which is to derypt 
214 ;  given in r23,r22
215 ; param3: 16-bit pointer to the key (128-bit) 
216 ;  given in r21,r20
217 ;
218 /*
219 void xtea_dec(uint32_t* dest, uint32_t* v, uint32_t* k) {
220     uint32_t v0=v[0], v1=v[1], i;
221     uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
222     for(i=0; i<32; i++) {
223         v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
224         sum -= delta;
225         v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
226     }
227     dest[0]=v0; dest[1]=v1;
228 }
229 */
230
231 xtea_dec:
232  /* prolog */
233         push r2
234         push r3
235         push r4
236         push r5
237         push r6
238         push r7
239         push r8
240         push r9
241         push r14
242         push r15
243         push r16
244         push r17
245         push r28 
246  /* load the block */
247         movw r26, r22 /* Z points to block */
248         movw r30, r20 /* X points to key   */
249         ld V01, X+
250         ld V02, X+
251         ld V03, X+
252         ld V04, X+
253         ld V11, X+
254         ld V12, X+
255         ld V13, X+
256         ld V14, X+
257         movw r26, r24 /* Z points to destination */
258  
259         ldi Sum1, 32
260         mov r0, Sum1 /* r1 is cycle-counter */
261         ldi Sum1, 0x20 /* sum = 0xC6EF3720 */
262         ldi Sum2, 0x37
263         ldi Sum3, 0xEF
264         ldi Sum4, 0xC6
265         clt
266
267 1:
268         movw Accu1, V01
269         movw Accu3, V03
270         ldi C, 4
271 2:      lsl Accu1
272         rol Accu2
273         rol Accu3
274         rol Accu4
275         dec C
276         brne 2b                 /* Accu == V0 << 4 */
277
278         movw Func1, V01
279         movw Func3, V03
280         ldi C, 5
281 3:      lsr Func4
282         ror Func3
283         ror Func2
284         ror Func1
285         dec C
286         brne 3b                 /* Func == V0 >> 5 */
287         
288         eor Accu1, Func1
289         eor Accu2, Func2
290         eor Accu3, Func3
291         eor Accu4, Func4
292         add Accu1, V01
293         adc Accu2, V02
294         adc Accu3, V03
295         adc Accu4, V04  /* Accu == ( (V0<<4)^(V0>>5) ) + V0 */
296         
297         brts 4f
298         mov C, Sum2
299         lsr C
300         andi C,(0x03 <<2)
301         set
302         rjmp 5f
303 4:      
304         mov C, Sum1     /* calc key offset */
305         andi C, 0x03
306         lsl C
307         lsl C
308         clt
309         
310 5:      
311         add r30, C
312         adc r31, r1
313         ld  Func1, Z
314         ldd Func2, Z+1
315         ldd Func3, Z+2
316         ldd Func4, Z+3 /* Func = key[sum & 3] */
317         sub r30, C
318         sbci r31, 0
319         add Func1, Sum1
320         adc Func2, Sum2
321         adc Func3, Sum3
322         adc Func4, Sum4 
323         eor Accu1, Func1
324         eor Accu2, Func2
325         eor Accu3, Func3
326         eor Accu4, Func4 /* Accu = ((V0<<4 ^ V0>>5) + V0) ^ (sum + key[sum&3])  */
327         sub V11, Accu1
328         sbc V12, Accu2
329         sbc V13, Accu3
330         sbc V14, Accu4
331         
332         movw Accu1, V01
333         movw Accu3, V03
334         movw V01, V11
335         movw V03, V13
336         movw V11, Accu1
337         movw V13, Accu3
338         
339         /* sum += delta */ /* delta == 0x9E3779B9 */
340         brtc 6f
341         subi Sum1, 0xB9
342         sbci Sum2, 0x79
343         sbci Sum3, 0x37
344         sbci Sum4, 0x9E
345         rjmp 1b
346         
347 6:      
348         dec r0
349         breq 7f
350         rjmp 1b 
351  
352 7:
353  /* write block back */
354         st X+, V01
355         st X+, V02
356         st X+, V03
357         st X+, V04
358         st X+, V11
359         st X+, V12
360         st X+, V13
361         st X+, V14
362  
363  /* epilog */
364         pop r28
365         pop r17
366         pop r16
367         pop r15
368         pop r14
369         pop r9
370         pop r8
371         pop r7
372         pop r6
373         pop r5
374         pop r4
375         pop r3
376         pop r2
377         ret
378         
379  /* #endif */
380
381 ;####################################################################
382  
383  #ifdef TWO_IN_ONE
384  /* now we use the same base-structure for enc- and decryption
385         to indicate operation mode we use the highest bit of param3 (16 bit pointer to key),
386         this is ok, since even the larges atmel today has "only" 8k of ram,
387         but you shouldn't use this feature while using external ram. 
388  */
389 .global xtea_enc
390         ori r21, 0x80
391         
392 .global xtea_dec
393 ; == xtea_dec ==
394 ; xtea decrytion function
395 ; param1: 16-bit pointer to destination for decrypted block 
396 ;  given in r25,r24
397 ; param2: 16-bit pointer to the block (64-bit) which is to derypt 
398 ;  given in r23,r22
399 ; param3: 16-bit pointer to the key (128-bit) 
400 ;  given in r21,r20
401 ;
402 /*
403 void xtea_dec(uint32_t* dest, uint32_t* v, uint32_t* k) {
404     uint32_t v0=v[0], v1=v[1], i;
405     uint32_t sum=0xC6EF3720, delta=0x9E3779B9;
406     for(i=0; i<32; i++) {
407         v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
408         sum -= delta;
409         v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
410     }
411     dest[0]=v0; dest[1]=v1;
412 }
413 */
414
415 xtea_dec:
416  /* prolog */
417         push r2
418         push r3
419         push r4
420         push r5
421         push r6
422         push r7
423         push r8
424         push r9
425         push r14
426         push r15
427         push r16
428         push r17
429         push r28 
430  /* set T-bit if we are going to encrypt, clear otherwise */
431         bst r21, 7
432         andi r21, 0x7f /* fix r21:r22 to a real addr */
433  /* load the block */
434         movw r26, r22 /* Z points to block */
435         movw r30, r20 /* X points to key   */
436         ld V01, X+
437         ld V02, X+
438         ld V03, X+
439         ld V04, X+
440         ld V11, X+
441         ld V12, X+
442         ld V13, X+
443         ld V14, X+
444         movw r26, r24 /* Z points to destination */
445  
446         ldi Sum1, 32
447         mov r0, Sum1 /* r1 is cycle-counter */
448         ldi Sum1, 0x20 /* sum = 0xC6EF3720 */
449         ldi Sum2, 0x37
450         ldi Sum3, 0xEF
451         ldi Sum4, 0xC6
452         clt
453
454 1:
455         movw Accu1, V01
456         movw Accu3, V03
457         ldi C, 4
458 2:      lsl Accu1
459         rol Accu2
460         rol Accu3
461         rol Accu4
462         dec C
463         brne 2b                 /* Accu == V0 << 4 */
464
465         movw Func1, V01
466         movw Func3, V03
467         ldi C, 5
468 3:      lsr Func4
469         ror Func3
470         ror Func2
471         ror Func1
472         dec C
473         brne 3b                 /* Func == V0 >> 5 */
474         
475         eor Accu1, Func1
476         eor Accu2, Func2
477         eor Accu3, Func3
478         eor Accu4, Func4
479         add Accu1, V01
480         adc Accu2, V02
481         adc Accu3, V03
482         adc Accu4, V04  /* Accu == ( (V0<<4)^(V0>>5) ) + V0 */
483         
484         brts 4f
485         mov C, Sum2
486         lsr C
487         andi C,(0x03 <<2)
488         set
489         rjmp 5f
490 4:      
491         mov C, Sum1     /* calc key offset */
492         andi C, 0x03
493         lsl C
494         lsl C
495         clt
496         
497 5:      
498         add r30, C
499         adc r31, r1
500         ld  Func1, Z
501         ldd Func2, Z+1
502         ldd Func3, Z+2
503         ldd Func4, Z+3 /* Func = key[sum & 3] */
504         sub r30, C
505         sbci r31, 0
506         add Func1, Sum1
507         adc Func2, Sum2
508         adc Func3, Sum3
509         adc Func4, Sum4 
510         eor Accu1, Func1
511         eor Accu2, Func2
512         eor Accu3, Func3
513         eor Accu4, Func4 /* Accu = ((V0<<4 ^ V0>>5) + V0) ^ (sum + key[sum&3])  */
514         sub V11, Accu1
515         sbc V12, Accu2
516         sbc V13, Accu3
517         sbc V14, Accu4
518         
519         movw Accu1, V01
520         movw Accu3, V03
521         movw V01, V11
522         movw V03, V13
523         movw V11, Accu1
524         movw V13, Accu3
525         
526         /* sum += delta */ /* delta == 0x9E3779B9 */
527         brtc 6f
528         subi Sum1, 0xB9
529         sbci Sum2, 0x79
530         sbci Sum3, 0x37
531         sbci Sum4, 0x9E
532         rjmp 1b
533         
534 6:      
535         dec r0
536         breq 7f
537         rjmp 1b 
538  
539 7:
540  /* write block back */
541         st X+, V01
542         st X+, V02
543         st X+, V03
544         st X+, V04
545         st X+, V11
546         st X+, V12
547         st X+, V13
548         st X+, V14
549  
550  /* epilog */
551         pop r28
552         pop r17
553         pop r16
554         pop r15
555         pop r14
556         pop r9
557         pop r8
558         pop r7
559         pop r6
560         pop r5
561         pop r4
562         pop r3
563         pop r2
564         ret
565         
566  #endif
567