# Copyright (c) (2012,2015,2016,2018,2019) Apple Inc. All rights reserved. # # corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which # is contained in the License.txt file distributed with corecrypto) and only to # people who accept that license. IMPORTANT: Any license rights granted to you by # Apple Inc. (if any) are limited to internal use within your organization only on # devices and computers you own or control, for the sole purpose of verifying the # security characteristics and correct functioning of the Apple Software. You may # not, directly or indirectly, redistribute the Apple Software or any portions thereof. /* This files defines _aes_encrypt_aesni and _aes_decrypt_aesni --- Intel Westmere HW AES-based implementation of _aes_encrypt and _aes_decrypt. These 2 functions SHOULD BE entried ONLY after the AES HW is verified to be available. They SHOULD NOT be called without AES HW detection. It might cause xnu to crash. The AES HW is detected 1st thing in _aes_encrypt (EncryptDecrypt.s) _aes_decrypt (EncryptDecrypt.s) and, if AES HW is detected, branch without link (ie, jump) to the functions here. The implementation here follows the examples in an Intel White Paper "Intel Advanced Encryption Standard (AES) Instruction Set" Rev.2 01 Note: Rev. 03 Final 2010 01 26 is available. Looks like some code change from Rev.2 01 */ #if (defined __i386__ || defined __x86_64__) .text .p2align 4,0x90 .globl _aes_encrypt_aesni _aes_encrypt_aesni: #if defined __i386__ movl 4(%esp), %eax // in movl 12(%esp), %edx // ctx movl 8(%esp), %ecx // out #define LOCAL_SIZE (12+16+16) // 16-byte align (-4 for return address) + 16 (xmm0) + 16 (xmm1) #define in %eax #define ctx %edx #define out %ecx #define r13 %esp #else // x86_64 #define LOCAL_SIZE (8+16+16) // 16-byte align (-8 for return address) + 16 (xmm0) + 16 (xmm1) #define in %rdi #define ctx %rdx #define out %rsi #define r13 %rsp #endif // i386 or x86_64 #if BUILDKERNEL sub $LOCAL_SIZE, r13 movaps %xmm0, (r13) #endif movups (in), %xmm0 // key length identification movl 240(ctx), %eax // key length cmp $160, %eax je L_AES_128 cmp $192, %eax je L_AES_192 cmp $224, %eax je L_AES_256 mov $-1, %eax // return ERROR #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret L_AES_128: testb $15, %dl // check whether expanded key is 16-byte aligned jne 0f // if not 16-byte aligned, aesenc xmm, m128 won't work pxor (ctx), %xmm0 aesenc 16(ctx), %xmm0 aesenc 32(ctx), %xmm0 aesenc 48(ctx), %xmm0 aesenc 64(ctx), %xmm0 aesenc 80(ctx), %xmm0 aesenc 96(ctx), %xmm0 aesenc 112(ctx), %xmm0 aesenc 128(ctx), %xmm0 aesenc 144(ctx), %xmm0 aesenclast 160(ctx), %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 0: // special case expanded key is not 16-byte aligned #if BUILDKERNEL movaps %xmm1, 16(r13) // save xmm1 into stack #endif movups (ctx), %xmm1 pxor %xmm1, %xmm0 movups 16(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 32(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 48(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 64(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 80(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 96(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 112(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 128(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 144(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 160(ctx), %xmm1 aesenclast %xmm1, %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 movaps 16(r13), %xmm1 add $LOCAL_SIZE, r13 #endif ret L_AES_192: testb $15, %dl // check whether expanded key is 16-byte aligned jne 0f // if not 16-byte aligned, aesenc xmm, m128 won't work pxor (ctx), %xmm0 aesenc 16(ctx), %xmm0 aesenc 32(ctx), %xmm0 aesenc 48(ctx), %xmm0 aesenc 64(ctx), %xmm0 aesenc 80(ctx), %xmm0 aesenc 96(ctx), %xmm0 aesenc 112(ctx), %xmm0 aesenc 128(ctx), %xmm0 aesenc 144(ctx), %xmm0 aesenc 160(ctx), %xmm0 aesenc 176(ctx), %xmm0 aesenclast 192(ctx), %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 0: // special case expanded key is not 16-byte aligned #if BUILDKERNEL movaps %xmm1, 16(r13) // save xmm1 into stack #endif movups (ctx), %xmm1 pxor %xmm1, %xmm0 movups 16(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 32(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 48(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 64(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 80(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 96(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 112(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 128(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 144(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 160(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 176(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 192(ctx), %xmm1 aesenclast %xmm1, %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 movaps 16(r13), %xmm1 add $LOCAL_SIZE, r13 #endif ret L_AES_256: testb $15, %dl // check whether expanded key is 16-byte aligned jne 0f // if not 16-byte aligned, aesenc xmm, m128 won't work pxor (ctx), %xmm0 aesenc 16(ctx), %xmm0 aesenc 32(ctx), %xmm0 aesenc 48(ctx), %xmm0 aesenc 64(ctx), %xmm0 aesenc 80(ctx), %xmm0 aesenc 96(ctx), %xmm0 aesenc 112(ctx), %xmm0 aesenc 128(ctx), %xmm0 aesenc 144(ctx), %xmm0 aesenc 160(ctx), %xmm0 aesenc 176(ctx), %xmm0 aesenc 192(ctx), %xmm0 aesenc 208(ctx), %xmm0 aesenclast 224(ctx), %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 0: // special case expanded key is not 16-byte aligned #if BUILDKERNEL movaps %xmm1, 16(r13) // save xmm1 into stack #endif movups (ctx), %xmm1 pxor %xmm1, %xmm0 movups 16(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 32(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 48(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 64(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 80(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 96(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 112(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 128(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 144(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 160(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 176(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 192(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 208(ctx), %xmm1 aesenc %xmm1, %xmm0 movups 224(ctx), %xmm1 aesenclast %xmm1, %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 movaps 16(r13), %xmm1 add $LOCAL_SIZE, r13 #endif ret .text .p2align 4,0x90 .globl _aes_decrypt_aesni _aes_decrypt_aesni: #if defined __i386__ movl 4(%esp), %eax // in movl 12(%esp), %edx // ctx movl 8(%esp), %ecx // out #endif #if BUILDKERNEL sub $LOCAL_SIZE, r13 movaps %xmm0, (r13) #endif movups (in), %xmm0 // key length identification movl 240(ctx), %eax // key length cmp $160, %eax je 0f // AES-128 cmp $192, %eax je 1f // AES-192 cmp $224, %eax je 2f // AES-256 mov $-1, %eax // return ERROR #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 0: // AES-128 testb $15, %dl // check whether expanded key is 16-byte aligned jne 9f // if not 16-byte aligned, aesenc xmm, m128 won't work pxor 160(ctx), %xmm0 aesdec 144(ctx), %xmm0 aesdec 128(ctx), %xmm0 aesdec 112(ctx), %xmm0 aesdec 96(ctx), %xmm0 aesdec 80(ctx), %xmm0 aesdec 64(ctx), %xmm0 aesdec 48(ctx), %xmm0 aesdec 32(ctx), %xmm0 aesdec 16(ctx), %xmm0 aesdeclast (ctx), %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 9: // AES-128 Decrypt : special case expanded key is not 16-byte aligned #if BUILDKERNEL movaps %xmm1, 16(r13) // save xmm1 into stack #endif movups 160(ctx), %xmm1 pxor %xmm1, %xmm0 movups 144(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 128(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 112(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 96(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 80(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 64(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 48(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 32(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 16(ctx), %xmm1 aesdec %xmm1, %xmm0 movups (ctx), %xmm1 aesdeclast %xmm1, %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 movaps 16(r13), %xmm1 add $LOCAL_SIZE, r13 #endif ret 1: // AES-192 testb $15, %dl // check whether expanded key is 16-byte aligned jne 9f // if not 16-byte aligned, aesenc xmm, m128 won't work pxor 192(ctx), %xmm0 aesdec 176(ctx), %xmm0 aesdec 160(ctx), %xmm0 aesdec 144(ctx), %xmm0 aesdec 128(ctx), %xmm0 aesdec 112(ctx), %xmm0 aesdec 96(ctx), %xmm0 aesdec 80(ctx), %xmm0 aesdec 64(ctx), %xmm0 aesdec 48(ctx), %xmm0 aesdec 32(ctx), %xmm0 aesdec 16(ctx), %xmm0 aesdeclast (ctx), %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 9: // AES-192 Decrypt : special case expanded key is not 16-byte aligned #if BUILDKERNEL movaps %xmm1, 16(r13) // save xmm1 into stack #endif movups 192(ctx), %xmm1 pxor %xmm1, %xmm0 movups 176(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 160(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 144(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 128(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 112(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 96(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 80(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 64(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 48(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 32(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 16(ctx), %xmm1 aesdec %xmm1, %xmm0 movups (ctx), %xmm1 aesdeclast %xmm1, %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 movaps 16(r13), %xmm1 add $LOCAL_SIZE, r13 #endif ret 2: // AES-256 testb $15, %dl // check whether expanded key is 16-byte aligned jne 9f // if not 16-byte aligned, aesenc xmm, m128 won't work pxor 224(ctx), %xmm0 aesdec 208(ctx), %xmm0 aesdec 192(ctx), %xmm0 aesdec 176(ctx), %xmm0 aesdec 160(ctx), %xmm0 aesdec 144(ctx), %xmm0 aesdec 128(ctx), %xmm0 aesdec 112(ctx), %xmm0 aesdec 96(ctx), %xmm0 aesdec 80(ctx), %xmm0 aesdec 64(ctx), %xmm0 aesdec 48(ctx), %xmm0 aesdec 32(ctx), %xmm0 aesdec 16(ctx), %xmm0 aesdeclast (ctx), %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 add $LOCAL_SIZE, r13 #endif ret 9: // AES-256 Decrypt : special case expanded key is not 16-byte aligned #if BUILDKERNEL movaps %xmm1, 16(r13) // save xmm1 into stack #endif movups 224(ctx), %xmm1 pxor %xmm1, %xmm0 movups 208(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 192(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 176(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 160(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 144(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 128(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 112(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 96(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 80(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 64(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 48(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 32(ctx), %xmm1 aesdec %xmm1, %xmm0 movups 16(ctx), %xmm1 aesdec %xmm1, %xmm0 movups (ctx), %xmm1 aesdeclast %xmm1, %xmm0 xorl %eax, %eax movups %xmm0, (out) #if BUILDKERNEL movaps (r13), %xmm0 movaps 16(r13), %xmm1 add $LOCAL_SIZE, r13 #endif ret #endif /* x86 based build */