]> git.cryptolib.org Git - avr-crypto-lib.git/blob - noekeon_omac.S
advances in serpent asm implementation
[avr-crypto-lib.git] / noekeon_omac.S
1 /* noekeon_omac.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  * \email   daniel.otte@rub.de
22  * \date    2008-08-06
23  * \license GPLv3 or later
24  * 
25  * 
26  * 
27  */
28
29 #include <avr/io.h>
30
31
32 .macro push_ p1:req, p2:vararg
33         push \p1
34 .ifnb \p2       
35         push_ \p2
36 .endif
37 .endm
38
39 .macro pop_ p1:req, p2:vararg
40         pop \p1
41 .ifnb \p2       
42         pop_ \p2
43 .endif
44 .endm
45
46 .macro push_range from:req, to:req
47         push \from
48 .if     \to-\from
49         push_range "(\from+1)",\to
50 .endif          
51 .endm
52
53 .macro pop_range from:req, to:req
54         pop \to
55 .if     \to-\from
56         pop_range \from,"(\to-1)"       
57 .endif
58 .endm
59
60 .macro stack_alloc size:req, reg1=r30, reg2=r31
61         in \reg1, _SFR_IO_ADDR(SPL)
62         in \reg2, _SFR_IO_ADDR(SPH)
63         sbiw r30, \size 
64         out  _SFR_IO_ADDR(SPH), \reg2
65         out  _SFR_IO_ADDR(SPL), \reg1
66 .endm
67
68 .macro stack_free size:req, reg1=r30, reg2=r31
69         in \reg1, _SFR_IO_ADDR(SPL)
70         in \reg2, _SFR_IO_ADDR(SPH)
71         adiw r30, \size 
72         out  _SFR_IO_ADDR(SPH), \reg2
73         out  _SFR_IO_ADDR(SPL), \reg1
74 .endm
75
76 push_r18_r27_func:
77         pop r31
78         pop r30
79         push_range 18, 27
80         ijmp
81
82 pop_r18_r27_func:
83         pop r31
84         pop r30
85         pop_range 18, 27
86         ijmp
87
88 .extern noekeon_enc
89
90 /*
91  * void noekeon_omac(void* dest, const void* msg, uint16_t msglength_b, 
92  *                   const void* key, uint8_t t)  
93  */
94
95 /* param dest        is passed in r24:r25
96  * param msg         is passed in r22:r23
97  * param msglength_b is passed in r20:r21
98  * param key         is passed in r18:r19
99  * param t           is passed in r16
100  */
101 .global noekeon_omac
102 noekeon_omac:
103         stack_alloc 48
104         ldi r17, 48
105 1:
106         st Z+, r1
107         dec r17
108         brne 1b
109         sbiw r30, 48
110         mov r26, r22
111         mov r22, r18
112         mov r18, r24
113         mov r24, r30
114         cpi r16, 0xff
115         breq 2f
116         st Z, r16
117         rcall push_r18_r27_func
118         rcall noekeon_enc
119         rcall pop_r18_r27_func
120         movw r30, r24  
121 2:      
122         tst r21
123         brne fullblock
124         cpi r20, 128+1
125         brlo lastblock
126 fullblock:      
127         /* copy block to stack buffer */
128         ldi r16, 16
129 1:      
130         ld r0, X+
131         ld r17, Z
132         eor r0, r17
133         st Z+, r0
134         dec r16
135         brne 1b
136         rcall push_r18_r27_func
137         rcall noekeon_enc
138         rcall pop_r18_r27_func
139         movw r30, r24
140         subi r20, 128
141         sbci r21, 0
142         rjmp 2 
143 lastblock:
144         adiw r24, 16
145         rcall push_r18_r27_func
146         rcall noekeon_enc
147         rcall pop_r18_r27_func
148
149         bst r20, 6 /* set t bit if msglength_b%128==0*/
150 2:
151         ldi r16, 16
152         clc
153         movw r30, r24 /* z points to encrypted null  vector (L) */      
154 1:      
155         ld r0, Z
156         rol r0
157         st Z+, r0
158         dec r16
159         brne 1b
160         brtc 2f
161         clt
162         rjmp 2b
163 2: /* B/P has been calculated */
164         ldi r16, 16
165         sbiw r30, 32
166 3:
167         ld r0, Z
168         ldd r17, Z+16
169         eor r0, r17
170         st Z+, r0
171         dec r16
172         brne 3b
173    /* B/P has been xored into stack buffer */
174    /* now we have to xor-in the remaining message */
175     mov r16, r20
176     subi r16, -7
177     lsr r16
178     lsr r16
179     lsr r16  /* r 1*/
180     sbiw r30, 16
181 4: 
182     ld r0, X+
183     ld r17, Z
184     eor r0, r17
185     st Z+, r0
186     dec r16
187     brne 4b
188     /* now we have only to insert the 1 at the end of message if msglength_b%128 != 0 */
189     sbiw r30, 1
190     andi r20, 0x07
191     breq 7f
192     ldi r17, 1
193 5:
194     dec r20
195     breq 6f
196     lsl r17
197     rjmp 5b  
198 6:
199         ld r0, Z
200         eor r0, r17
201         st Z, r0
202 7:
203         call noekeon_enc
204         stack_free 48
205         ret
206
207
208
209
210
211
212
213
214
215
216
217