Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
589 | diamond | 1 | ; Implementation of AES crypto algorithm. |
2 | ; Buffer size is 0x10 bytes (128 bits), key size is not fixed. |
||
3 | ; Written by diamond in 2007. |
||
4 | uglobal |
||
5 | aes.pow_table rb 256 ; pow[a] = 3^a |
||
6 | aes.log_table rb 256 ; log[3^a] = a |
||
7 | aes.sbox rb 256 ; ShiftBytes(a) |
||
8 | aes.sbox_rev rb 256 ; ShiftBytes^{-1}(a) |
||
9 | aes.mctable rd 256 ; MixColumns(ShiftBytes(a,0,0,0)) |
||
10 | aes.mcrtable rd 256 ; MixColumns^{-1}(a,0,0,0) |
||
11 | endg |
||
12 | |||
13 | init_aes: |
||
14 | ; Byte values in SubBytes transform are interpreted as items of |
||
15 | ; GF(2^8) \cong F_2[x]/(x^8+x^4+x^3+x+1)F_2[x]. |
||
16 | ; x+1 is primitive item in this field. |
||
17 | xor ebx, ebx |
||
18 | push 1 |
||
19 | pop eax |
||
20 | .1: |
||
21 | mov [aes.pow_table+ebx], al |
||
22 | mov [aes.log_table+eax], bl |
||
23 | ; Multiplication by x+1... |
||
24 | mov cl, al ; save value |
||
25 | ; ...multiply by x with mod (x^8+x^4+x^3+x+1) = 0x11B... |
||
26 | add al, al |
||
27 | jnc @f |
||
28 | xor al, 0x1B |
||
29 | @@: |
||
30 | ; ...and add operand |
||
31 | xor al, cl |
||
32 | inc bl |
||
33 | jnz .1 |
||
34 | ; generate table for SubBytes transform |
||
35 | mov [aes.sbox+0], 0x63 |
||
36 | mov [aes.sbox_rev+0x63], bl |
||
37 | inc ebx |
||
38 | .2: |
||
39 | ; calculate inverse in GF(2^8) |
||
40 | mov al, [aes.log_table+ebx] |
||
41 | xor al, 0xFF ; equivalent to "al = 0xFF - al" |
||
42 | mov cl, [aes.pow_table+eax] |
||
43 | ; linear transform of byte as vector over F_2 |
||
44 | mov al, cl |
||
45 | rol cl, 1 |
||
46 | xor al, cl |
||
47 | rol cl, 1 |
||
48 | xor al, cl |
||
49 | rol cl, 1 |
||
50 | xor al, cl |
||
51 | rol cl, 1 |
||
52 | xor al, cl |
||
53 | xor al, 0x63 |
||
54 | mov [aes.sbox+ebx], al |
||
55 | mov [aes.sbox_rev+eax], bl |
||
56 | inc bl |
||
57 | jnz .2 |
||
58 | ; generate table for SubBytes + MixColumn transforms |
||
59 | .3: |
||
60 | mov al, [aes.sbox+ebx] ; SubBytes transform |
||
61 | mov cl, al |
||
62 | add cl, cl |
||
63 | jnc @f |
||
64 | xor cl, 0x1B |
||
65 | @@: |
||
66 | mov byte [aes.mctable+ebx*4], cl ; low byte of MixColumn(a,0,0,0) |
||
67 | mov byte [aes.mctable+ebx*4+1], al |
||
68 | mov byte [aes.mctable+ebx*4+2], al |
||
69 | xor cl, al |
||
70 | mov byte [aes.mctable+ebx*4+3], cl ; high byte of MixColumn(a,0,0,0) |
||
71 | inc bl |
||
72 | jnz .3 |
||
73 | ; generate table for reverse MixColumn transform |
||
74 | mov dword [aes.mcrtable+0], ebx |
||
75 | inc ebx |
||
76 | .4: |
||
77 | ; log_table[9]=0xC7, log_table[0xB]=0x68, log_table[0xD]=0xEE, log_table[0xE]=0xDF |
||
78 | mov cl, [aes.log_table+ebx] |
||
79 | mov al, cl |
||
80 | add al, 0xDF |
||
81 | adc al, 0 |
||
82 | mov al, [aes.pow_table+eax] |
||
83 | mov byte [aes.mcrtable+ebx*4], al |
||
84 | mov al, cl |
||
85 | add al, 0xC7 |
||
86 | adc al, 0 |
||
87 | mov al, [aes.pow_table+eax] |
||
88 | mov byte [aes.mcrtable+ebx*4+1], al |
||
89 | mov al, cl |
||
90 | add al, 0xEE |
||
91 | adc al, 0 |
||
92 | mov al, [aes.pow_table+eax] |
||
93 | mov byte [aes.mcrtable+ebx*4+2], al |
||
94 | mov al, cl |
||
95 | add al, 0x68 |
||
96 | adc al, 0 |
||
97 | mov al, [aes.pow_table+eax] |
||
98 | mov byte [aes.mcrtable+ebx*4+3], al |
||
99 | inc bl |
||
100 | jnz .4 |
||
101 | ret |
||
102 | |||
103 | aes_setkey: |
||
104 | ; in: esi->key, edx=key size in dwords, edi->AES data struc |
||
105 | lea eax, [edx+6] ; calc number of rounds (buffer size=4) |
||
106 | stosd |
||
107 | shl eax, 4 |
||
108 | lea ebx, [edi+eax+16] |
||
109 | mov ecx, edx |
||
110 | rep movsd |
||
111 | push ebx |
||
112 | mov bl, 1 |
||
113 | .0: |
||
114 | push 4 |
||
115 | pop ecx |
||
116 | @@: |
||
117 | movzx esi, byte [edi-5+ecx] |
||
118 | mov al, [aes.sbox+esi] |
||
119 | rol eax, 8 |
||
120 | loop @b |
||
121 | ror eax, 16 |
||
122 | mov esi, edx |
||
123 | neg esi |
||
124 | xor eax, [edi+esi*4] |
||
125 | xor al, bl |
||
126 | add bl, bl |
||
127 | jnc @f |
||
128 | xor bl, 0x1B |
||
129 | @@: |
||
130 | stosd |
||
131 | lea ecx, [edx-1] |
||
132 | .1: |
||
133 | cmp edi, [esp] |
||
134 | jz .ret |
||
135 | cmp edx, 8 |
||
136 | jnz @f |
||
137 | cmp ecx, 4 |
||
138 | jnz @f |
||
139 | push eax |
||
140 | movzx eax, al |
||
141 | mov al, [aes.sbox+eax] |
||
142 | mov [esp], al |
||
143 | mov al, byte [esp+1] |
||
144 | mov al, [aes.sbox+eax] |
||
145 | mov [esp+1], al |
||
146 | mov al, byte [esp+2] |
||
147 | mov al, [aes.sbox+eax] |
||
148 | mov [esp+2], al |
||
149 | mov al, byte [esp+3] |
||
150 | mov al, [aes.sbox+eax] |
||
151 | mov [esp+3], al |
||
152 | pop eax |
||
153 | @@: |
||
154 | xor eax, [edi+esi*4] |
||
155 | stosd |
||
156 | loop .1 |
||
157 | cmp edi, [esp] |
||
158 | jnz .0 |
||
159 | .ret: |
||
160 | pop eax |
||
161 | ret |
||
162 | |||
163 | aes_decode: |
||
164 | ; in: esi->in, ebx->out, edi->AES state |
||
165 | push ebx ebp |
||
166 | push dword [esi+12] |
||
167 | push dword [esi+8] |
||
168 | push dword [esi+4] |
||
169 | push dword [esi] |
||
170 | mov esi, esp |
||
171 | ; reverse final round |
||
172 | mov ebp, [edi] ; number of rounds |
||
173 | mov ecx, ebp |
||
174 | shl ecx, 4 |
||
175 | lea edi, [edi+ecx+4] ; edi->last round key |
||
176 | ; load buffer into registers |
||
177 | mov eax, [esi] |
||
178 | mov ebx, [esi+4] |
||
179 | mov ecx, [esi+8] |
||
180 | mov edx, [esi+12] |
||
181 | ; (AddRoundKey) |
||
182 | xor eax, [edi] |
||
183 | xor ebx, [edi+4] |
||
184 | xor ecx, [edi+8] |
||
185 | xor edx, [edi+12] |
||
186 | ; (ShiftRows) |
||
187 | .loop0: |
||
188 | xchg ch, dh |
||
189 | xchg bh, ch |
||
190 | xchg ah, bh |
||
191 | rol eax, 16 |
||
192 | rol ebx, 16 |
||
193 | rol ecx, 16 |
||
194 | rol edx, 16 |
||
195 | xchg al, cl |
||
196 | xchg bl, dl |
||
197 | xchg ah, bh |
||
198 | xchg bh, ch |
||
199 | xchg ch, dh |
||
200 | rol eax, 16 |
||
201 | rol ebx, 16 |
||
202 | rol ecx, 16 |
||
203 | rol edx, 16 |
||
204 | ; (SubBytes) |
||
205 | mov [esi], eax |
||
206 | mov [esi+4], ebx |
||
207 | mov [esi+8], ecx |
||
208 | mov [esi+12], edx |
||
209 | mov ecx, 16 |
||
210 | @@: |
||
211 | movzx eax, byte [esi] |
||
212 | mov al, [aes.sbox_rev+eax] |
||
213 | mov byte [esi], al |
||
214 | add esi, 1 |
||
215 | sub ecx, 1 |
||
216 | jnz @b |
||
217 | sub esi, 16 |
||
218 | sub edi, 16 |
||
219 | ; reverse normal rounds |
||
220 | sub ebp, 1 |
||
221 | jz .done |
||
222 | mov eax, [esi] |
||
223 | mov ebx, [esi+4] |
||
224 | mov ecx, [esi+8] |
||
225 | mov edx, [esi+12] |
||
226 | push esi edi |
||
227 | ; (AddRoundKey) |
||
228 | xor eax, [edi] |
||
229 | xor ebx, [edi+4] |
||
230 | xor ecx, [edi+8] |
||
231 | xor edx, [edi+12] |
||
232 | ; (MixColumns) |
||
233 | macro mix_reg reg { |
||
234 | movzx esi, reg#l |
||
235 | mov edi, [aes.mcrtable+esi*4] |
||
236 | movzx esi, reg#h |
||
237 | rol e#reg#x, 16 |
||
238 | mov esi, [aes.mcrtable+esi*4] |
||
239 | rol esi, 8 |
||
240 | xor edi, esi |
||
241 | movzx esi, reg#l |
||
242 | mov esi, [aes.mcrtable+esi*4] |
||
243 | rol esi, 16 |
||
244 | xor edi, esi |
||
245 | movzx esi, reg#h |
||
246 | mov esi, [aes.mcrtable+esi*4] |
||
247 | ror esi, 8 |
||
248 | xor edi, esi |
||
249 | mov e#reg#x, edi |
||
250 | } |
||
251 | mix_reg a |
||
252 | mix_reg b |
||
253 | mix_reg c |
||
254 | mix_reg d |
||
255 | purge mix_reg |
||
256 | pop edi esi |
||
257 | jmp .loop0 |
||
258 | .done: |
||
259 | ; (AddRoundKey) |
||
260 | mov esi, [esp+20] |
||
261 | pop eax |
||
262 | xor eax, [edi] |
||
263 | mov [esi], eax |
||
264 | pop eax |
||
265 | xor eax, [edi+4] |
||
266 | mov [esi+4], eax |
||
267 | pop eax |
||
268 | xor eax, [edi+8] |
||
269 | mov [esi+8], eax |
||
270 | pop eax |
||
271 | xor eax, [edi+12] |
||
272 | mov [esi+12], eax |
||
273 | pop ebp ebx |
||
274 | ret |