]> git.cryptolib.org Git - avr-crypto-lib.git/blob - cscipher/cscipher_tiny_asm.S
2a4b1b1c5c991e620436a3d9ffcc0d03fbeab0f2
[avr-crypto-lib.git] / cscipher / cscipher_tiny_asm.S
1 /* cscipher_tiny_asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2010 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 #include "avr-asm-macros.S"
21
22 /*
23 uint8_t p(uint8_t a){
24         a ^= pgm_read_byte(fg_table+(a&0xf))&0xf0;
25         a ^= pgm_read_byte(fg_table+(a>>4)) &0x0f;
26         a ^= pgm_read_byte(fg_table+(a&0xf))&0xf0;
27         return a;
28 }
29 */
30
31 fg_table:
32 .byte   0xfa, 0xd6, 0xb0, 0xb2, 0x7b, 0x5e, 0x71, 0x78
33 .byte   0xed, 0xd4, 0xa5, 0xb3, 0xef, 0xdc, 0xe7, 0xf9
34
35 .global p
36 p:
37         ldi r30, lo8(fg_table)
38         ldi r31, hi8(fg_table)
39         movw r26, r30
40         mov r25, r24
41         andi r25, 0x0F
42         add r30, r25
43         adc r31, r1
44         lpm r25, Z
45         andi r25, 0xF0
46         eor r24, r25
47
48         movw r30, r26
49         mov r25, r24
50         swap r25
51         andi r25, 0x0F
52         add r30, r25
53         adc r31, r1
54         lpm r25, Z
55         andi r25, 0x0F
56         eor r24, r25
57
58         movw r30, r26
59         mov r25, r24
60         andi r25, 0x0F
61         add r30, r25
62         adc r31, r1
63         lpm r25, Z
64         andi r25, 0xF0
65         eor r24, r25
66         clr r25
67         ret
68
69 ks_const:
70 .byte   0x29,0x0d,0x61,0x40,0x9c,0xeb,0x9e,0x8f
71 .byte   0x1f,0x85,0x5f,0x58,0x5b,0x01,0x39,0x86
72 .byte   0x97,0x2e,0xd7,0xd6,0x35,0xae,0x17,0x16
73 .byte   0x21,0xb6,0x69,0x4e,0xa5,0x72,0x87,0x08
74 .byte   0x3c,0x18,0xe6,0xe7,0xfa,0xad,0xb8,0x89
75 .byte   0xb7,0x00,0xf7,0x6f,0x73,0x84,0x11,0x63
76 .byte   0x3f,0x96,0x7f,0x6e,0xbf,0x14,0x9d,0xac
77 .byte   0xa4,0x0e,0x7e,0xf6,0x20,0x4a,0x62,0x30
78 .byte   0x03,0xc5,0x4b,0x5a,0x46,0xa3,0x44,0x65
79
80 CTX_0 = 18
81 CTX_1 = 19
82 CNT   = 17
83 .global cscipher_init
84 cscipher_init:
85         push CNT
86         push_range 28, 29
87         stack_alloc 24, 28, 29
88         adiw r28, 1
89         movw r30, r24
90         movw CTX_0, r22
91         /* copy key to local tmp_key */
92         ldi r22, 16
93 10: ld r23, Z+
94         st Y+, r23
95         dec r22
96         brne 10b
97         sbiw r28, 16
98         ldi CNT, 0xff
99 10: /* main loop */
100         inc CNT
101         /* copy part of tmp_key to tmp */
102         ldi r23, 8
103 11:     ldd r22, Y+0
104         sbrc CNT, 0
105         ldd r22, Y+8
106         std Y+16, r22
107         adiw r28, 1
108         dec r23
109         brne 11b
110         adiw r28, 8 /* Y points at tmp */
111         /* xor ks constant into tmp */
112         movw r24, r28
113         ldi r22, lo8(ks_const)
114         ldi r23, hi8(ks_const)
115         mov r21, CNT
116         swap r21
117         lsr r21
118         add r22, r21
119         adc r23, r1
120         clr r21
121         ldi r20, 8
122         call memxor_P
123         /* do P transformation */
124         ldi r22, 8
125 20:     ld r24, Y
126         rcall p
127         st Y+, r24
128         dec r22
129         brne 20b
130         sbiw r28, 8 /* Y points at tmp */
131         movw r26, r28
132         sbiw r26, 8
133         sbrc CNT, 0
134         sbiw r26, 8
135         /* do T transformation */
136         movw r30, CTX_0
137         ldi r22, 8
138 30:     ldi r23, 8
139 35:     ld r24, Y
140         rol r24
141         rol r21
142         st Y+, r24
143         dec r23
144         brne 35b
145         sbiw r28, 8 /* Y points at tmp */
146         ld r24, X
147         eor r21, r24
148         st X+, r21
149         st Z+, r21
150         dec r22
151         brne 30b
152         sbiw r28, 16 /* Y points at tmp_key (again) */
153         movw CTX_0, r30
154         sbrs CNT, 3
155         rjmp 10b
156         stack_free 24
157         pop_range 28, 29
158         pop CNT
159         ret
160
161
162 round_const:
163 .byte   0xb7, 0xe1, 0x51, 0x62, 0x8a, 0xed, 0x2a, 0x6a
164 .byte   0xbf, 0x71, 0x58, 0x80, 0x9c, 0xf4, 0xf3, 0xc7
165
166 /*
167 void cscipher_enc(void *buffer, const cscipher_ctx_t *ctx){
168         uint8_t i,j,k;
169         uint8_t tmp[8];
170         for(i=0; i<8; ++i){
171                 for(j=0; j<3; ++j){
172                         if(j==0){
173                                 memxor(buffer, ctx->keys[i], 8);
174                         }else{
175                                 memxor_P(buffer, round_const+((j==1)?0:8), 8);
176                         }
177                         for(k=0; k<4; ++k){
178                                 ((uint16_t*)tmp)[k] = m(((uint16_t*)buffer)[k]);
179                         }
180                         for(k=0; k<4; ++k){
181                                 ((uint8_t*)buffer)[k]   = tmp[2*k];
182                                 ((uint8_t*)buffer)[k+4] = tmp[2*k+1];
183                         }
184                 }
185         }
186         memxor(buffer, ctx->keys[8], 8);
187 }
188 */
189 TMP_0 =  2
190 TMP_1 =  3
191 TMP_2 =  4
192 TMP_3 =  5
193 TMP_4 =  6
194 TMP_5 =  7
195 TMP_6 =  8
196 TMP_7 =  9
197 CTX_0 = 10
198 CTX_1 = 11
199 CNT_0 = 16
200 CNT_1 = 17
201 DST_0 = 12
202 DST_1 = 13
203 SRC_0 = 14
204 SRC_1 = 15
205 .global cscipher_enc
206 cscipher_enc:
207         push_range 2, 17
208         push_range 28, 29
209         movw r28, r24
210         movw CTX_0, r22
211         ldi CNT_0, 8
212         /* main loop */
213 10: ldi CNT_1, 2
214         clt
215         /* sub loop */
216 20: ldi r27, 0
217         ldi r26, TMP_0
218         movw DST_0, r26
219         ldi r30, lo8(round_const)
220         ldi r31, hi8(round_const)
221         sbrs CNT_1, 0
222         adiw r30, 8
223         sbrc CNT_1, 1
224         movw r30, CTX_0
225         movw SRC_0, r30
226         ldi r21, 4
227         /* xor and m transformation */
228 25:     ld r24, Y+
229         ld r25, Y+
230         movw r30, SRC_0
231         brts 30f
232         ld r22, Z+
233         ld r23, Z+
234         rjmp 35f
235 30:     lpm r22, Z+
236         lpm r23, Z+
237 35:
238         movw SRC_0, r30
239         eor r24, r22
240         eor r25, r23
241
242         movw r22, r24
243         mov r25, r22
244         rol r25
245         adc r25, r1
246         mov r22, r25
247         andi r22, 0x55
248         eor r22, r24
249         eor r22, r23
250         eor r23, r25
251         mov r24, r23
252         rcall p
253         mov r23, r24
254         mov r24, r22
255         rcall p
256
257         movw r26, DST_0
258         st X+, r24
259         st X+, r23
260         movw DST_0, r26
261         dec r21
262         brne 25b
263         sbrc CNT_1, 1
264         movw CTX_0, SRC_0
265         sbiw r28, 8
266         std Y+0, TMP_0
267         std Y+4, TMP_1
268         std Y+1, TMP_2
269         std Y+5, TMP_3
270         std Y+2, TMP_4
271         std Y+6, TMP_5
272         std Y+3, TMP_6
273         std Y+7, TMP_7
274         set
275         dec CNT_1
276         brpl 20b
277
278         dec CNT_0
279         brne 10b
280
281         movw r24, r28
282         movw r22, CTX_0
283         clr r21
284         ldi r20, 8
285
286         pop_range 28, 29
287         pop_range 2, 17
288         rjmp memxor
289
290 /*
291 void cscipher_dec(void *buffer, const cscipher_ctx_t *ctx){
292         uint8_t i=7,j,k;
293         uint8_t tmp[8];
294         memxor(buffer, ctx->keys[8], 8);
295         do{
296                 for(j=0; j<3; ++j){
297                         for(k=0; k<4; ++k){
298                                 tmp[2*k]   = ((uint8_t*)buffer)[k];
299                                 tmp[2*k+1] = ((uint8_t*)buffer)[4+k];
300                         }
301                         for(k=0; k<4; ++k){
302                                 ((uint16_t*)buffer)[k] = m_inv(((uint16_t*)tmp)[k]);
303                         }
304                         if(j==2){
305                                 memxor(buffer, ctx->keys[i], 8);
306                         }else{
307                                 memxor_P(buffer, round_const+((j==1)?0:8), 8);
308                         }
309
310                 }
311         }while(i--);
312 }
313
314 */
315 .global cscipher_dec
316 cscipher_dec:
317         push_range 2, 17
318         push_range 28, 29
319         movw r28, r24
320         movw r26, r22
321         adiw r26, 7*8
322         adiw r26, 8
323         movw CTX_0, r26
324         movw r22, r26
325         clr r21
326         ldi r20, 8
327         call memxor
328         ldi CNT_0, 7
329 10:
330         ldi CNT_1, 3
331 20:
332         clr r27
333         ldi r26, TMP_0
334         movw DST_0, r26
335         ldi r21, 4
336 30:
337         ldd r23, Y+4
338         ld  r24, Y+
339 /* m_inv transformation */
340 ;       mov r23, r25
341         rcall p
342         mov r22, r24
343         mov r24, r23
344         rcall p
345         eor r22, r24
346         mov r25, r24
347         mov r24, r22
348         rol r24
349         adc r24, r1
350         andi r24, 0xaa
351         eor r24, r22
352         mov r22, r24
353         rol r22
354         adc r22, r1
355         eor r25, r22
356
357         movw r26, DST_0
358         st X+, r24
359         st X+, r25
360         movw DST_0, r26
361         dec r21
362         brne 30b
363         sbiw r28, 4
364         std Y+0, TMP_0
365         std Y+1, TMP_1
366         std Y+2, TMP_2
367         std Y+3, TMP_3
368         std Y+4, TMP_4
369         std Y+5, TMP_5
370         std Y+6, TMP_6
371         std Y+7, TMP_7
372         movw r24, r28
373         clr r21
374         ldi r20, 8
375         sbrc CNT_1, 1
376         rjmp 40f
377         movw r26, CTX_0
378         sbiw r26, 8
379         movw CTX_0, r26
380         movw r22, r26
381         call memxor
382         rjmp 45f
383 40:
384         ldi r26, lo8(round_const)
385         ldi r27, hi8(round_const)
386         sbrc CNT_1, 0
387         adiw r26, 8
388         movw r22, r26
389         call memxor_P
390 45:
391
392         dec CNT_1
393         brne 20b
394         dec CNT_0
395         brpl 10b
396 90:
397         pop_range 28, 29
398         pop_range 2, 17
399         ret