1 /* This files defines _aes_encrypt_key_hw and _aes_decrypt_key_hw --- Intel Westmere HW AES-based implementation
2 of _aes_encrypt_key and _aes_decrypt_key.
4 These 2 functions SHOULD BE entried ONLY after the AES HW is verified to be available.
5 They SHOULD NOT be called without AES HW detection. It might cause xnu to crash.
7 The AES HW is detected 1st thing in
8 _aes_encrypt_key (ExpandKeyForEncryption.s)
9 _aes_decrypt_key (ExpandKeyForDecryption.s)
10 and, if AES HW is detected, branch without link (ie, jump) to the functions here.
12 The implementation here follows the examples in an Intel White Paper
13 "Intel Advanced Encryption Standard (AES) Instruction Set" Rev.2 01
15 Note: Rev. 03 Final 2010 01 26 is available. Looks like some code change from Rev.2 01
23 // hw_aes_encrypt_key(key, klen, hwectx);
24 // klen = 16, 24, or 32, or (128/192/256)
26 .globl _aes_encrypt_key_hw
34 mov 8(%ebp), %eax // pointer to key
35 mov 12(%ebp), %ebx // klen
36 mov 16(%ebp), %edi // ctx
53 // for xmm registers save and restore
59 shl $3, klen // convert 16/24/32 to 128/192/256
62 cmp $128, klen // AES-128 ?
63 je L_AES_128_Encrypt_Key
64 cmp $192, klen // AES-192 ?
65 je L_AES_192_Encrypt_Key
66 cmp $256, klen // AES-256 ?
67 je L_AES_256_Encrypt_Key
68 mov $1, %eax // return error for wrong klen
69 L_Encrypt_Key_2_return:
80 L_AES_128_Encrypt_Key:
88 movl $160, 240(ctx) // write expanded key length to ctx
93 aeskeygenassist $1, %xmm1, %xmm2
94 call L_key_expansion_128
95 aeskeygenassist $2, %xmm1, %xmm2
96 call L_key_expansion_128
97 aeskeygenassist $4, %xmm1, %xmm2
98 call L_key_expansion_128
99 aeskeygenassist $8, %xmm1, %xmm2
100 call L_key_expansion_128
101 aeskeygenassist $0x10, %xmm1, %xmm2
102 call L_key_expansion_128
103 aeskeygenassist $0x20, %xmm1, %xmm2
104 call L_key_expansion_128
105 aeskeygenassist $0x40, %xmm1, %xmm2
106 call L_key_expansion_128
107 aeskeygenassist $0x80, %xmm1, %xmm2
108 call L_key_expansion_128
109 aeskeygenassist $0x1b, %xmm1, %xmm2
110 call L_key_expansion_128
111 aeskeygenassist $0x36, %xmm1, %xmm2
112 call L_key_expansion_128
115 // restore xmm registers
120 xor %eax, %eax // return 0 for success
121 jmp L_Encrypt_Key_2_return
125 pshufd $0xff, %xmm2, %xmm2
137 movups %xmm1, (ctx, cx)
140 L_AES_192_Encrypt_Key:
142 // save xmm registers
148 movl $192, 240(ctx) // write expanded key length to ctx
158 aeskeygenassist $1, %xmm3, %xmm2
159 call L_key_expansion_192
160 aeskeygenassist $2, %xmm3, %xmm2
161 call L_key_expansion_192
162 aeskeygenassist $4, %xmm3, %xmm2
163 call L_key_expansion_192
164 aeskeygenassist $8, %xmm3, %xmm2
165 call L_key_expansion_192
166 aeskeygenassist $0x10, %xmm3, %xmm2
167 call L_key_expansion_192
168 aeskeygenassist $0x20, %xmm3, %xmm2
169 call L_key_expansion_192
170 aeskeygenassist $0x40, %xmm3, %xmm2
171 call L_key_expansion_192
172 aeskeygenassist $0x80, %xmm3, %xmm2
173 call L_key_expansion_192
176 // restore xmm registers
182 xor %eax, %eax // return 0 for success
183 jmp L_Encrypt_Key_2_return
187 pshufd $0x55, %xmm2, %xmm2
201 pshufd $0xff, %xmm1, %xmm2
215 L_AES_256_Encrypt_Key:
217 // save xmm registers
223 movl $224, 240(ctx) // write expanded key length to ctx
226 movups 16(pkey), %xmm3
228 movups %xmm3, 16(ctx)
232 aeskeygenassist $1, %xmm3, %xmm2
233 call L_key_expansion_256
234 aeskeygenassist $2, %xmm3, %xmm2
235 call L_key_expansion_256
236 aeskeygenassist $4, %xmm3, %xmm2
237 call L_key_expansion_256
238 aeskeygenassist $8, %xmm3, %xmm2
239 call L_key_expansion_256
240 aeskeygenassist $0x10, %xmm3, %xmm2
241 call L_key_expansion_256
242 aeskeygenassist $0x20, %xmm3, %xmm2
243 call L_key_expansion_256
244 aeskeygenassist $0x40, %xmm3, %xmm2
245 call L_key_expansion_256_final
248 // restore xmm registers
254 xor %eax, %eax // return 0 for success
255 jmp L_Encrypt_Key_2_return
260 pshufd $0xff, %xmm2, %xmm2
276 aeskeygenassist $0, %xmm1, %xmm4
278 pshufd $0xaa, %xmm4, %xmm2
298 L_key_expansion_256_final:
300 pshufd $0xff, %xmm2, %xmm2
317 // _aes_decrypt_key_hw is implemented as
318 // 1. call _aes_encrypt_key_hw
319 // 2. use aesimc to convert the expanded round keys (except the 1st and last round keys)
323 .globl _aes_decrypt_key_hw
332 // copy input arguments for calling aes_decrypt_key_hw
347 // calling arguments %rdi/%rsi/%rdx will be used for encrypt_key
348 // %rdx (ctx) will return unchanged
349 // %rsi (klen) will (<<3) if <= 32
352 call _aes_encrypt_key_hw
355 L_decrypt_almost_done:
372 mov 12(%ebp), %eax // klen
373 mov 16(%ebp), %edx // ctx
378 shl $3, klen // convert 16/24/32 to 128/192/256
382 mov $9, cx // default is AES-128
404 jmp L_decrypt_almost_done