/* * Copyright (c) 2011, Intel Corporation * Authors: Fenghua Yu , * H. Peter Anvin * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * */ #define ENTRY(x) \ .balign 64 ; \ .globl x ; \ x: #define ENDPROC(x) \ .size x, .-x ; \ .type x, @function #define RDRAND_RETRY_LIMIT 10 #if defined(__x86_64__) ENTRY(x86_rdrand_nlong) 1: mov $RDRAND_RETRY_LIMIT, %eax 2: .byte 0x48,0x0f,0xc7,0xf2 /* rdrand %rdx */ jnc 3f mov %rdx, (%rdi) add $8, %rdi sub $1, %esi jnz 1b ret 3: sub $1, %eax rep;nop jnz 2b ret ENDPROC(x86_rdrand_nlong) #define SETPTR(var,ptr) leaq var(%rip),ptr #define PTR0 %rdi #define PTR1 %rsi #define PTR2 %rcx #define NPTR2 1 /* %rcx = %r1, only 0-7 valid here */ #elif defined(__i386__) ENTRY(x86_rdrand_nlong) push %ebp mov %esp, %ebp push %edi movl 8(%ebp), %ecx movl 12(%ebp), %edx 1: mov $RDRAND_RETRY_LIMIT, %eax 2: .byte 0x0f,0xc7,0xf7 /* rdrand %edi */ jnc 3f mov %edi, (%ecx) add $4, %ecx sub $1, %edx jnz 2b pop %edi pop %ebp ret 3: sub $1, %eax rep;nop jnz 2b pop %edi pop %ebp ret ENDPROC(x86_rdrand_nlong) #define SETPTR(var,ptr) movl $(var),ptr #define PTR0 %eax #define PTR1 %edx #define PTR2 %ecx #define NPTR2 1 /* %rcx = %r1 */ #endif #if defined(__i386__) || defined(__x86_64__) ENTRY(x86_aes_mangle) #if defined(__i386__) push %ebp mov %esp, %ebp movl 8(%ebp), %eax movl 12(%ebp), %edx #endif SETPTR(aes_round_keys, PTR2) movdqa (0*16)(PTR0), %xmm0 movdqa (1*16)(PTR0), %xmm1 movdqa (2*16)(PTR0), %xmm2 movdqa (3*16)(PTR0), %xmm3 movdqa (4*16)(PTR0), %xmm4 movdqa (5*16)(PTR0), %xmm5 movdqa (6*16)(PTR0), %xmm6 movdqa (7*16)(PTR0), %xmm7 pxor (0*16)(PTR1), %xmm0 pxor (1*16)(PTR1), %xmm1 pxor (2*16)(PTR1), %xmm2 pxor (3*16)(PTR1), %xmm3 pxor (4*16)(PTR1), %xmm4 pxor (5*16)(PTR1), %xmm5 pxor (6*16)(PTR1), %xmm6 pxor (7*16)(PTR1), %xmm7 .rept 10 .byte 0x66,0x0f,0x38,0xdc,0x00+NPTR2 /* aesenc (PTR2), %xmm0 */ .byte 0x66,0x0f,0x38,0xdc,0x08+NPTR2 /* aesenc (PTR2), %xmm1 */ .byte 0x66,0x0f,0x38,0xdc,0x10+NPTR2 /* aesenc (PTR2), %xmm2 */ .byte 0x66,0x0f,0x38,0xdc,0x18+NPTR2 /* aesenc (PTR2), %xmm3 */ .byte 0x66,0x0f,0x38,0xdc,0x20+NPTR2 /* aesenc (PTR2), %xmm4 */ .byte 0x66,0x0f,0x38,0xdc,0x28+NPTR2 /* aesenc (PTR2), %xmm5 */ .byte 0x66,0x0f,0x38,0xdc,0x30+NPTR2 /* aesenc (PTR2), %xmm6 */ .byte 0x66,0x0f,0x38,0xdc,0x38+NPTR2 /* aesenc (PTR2), %xmm7 */ add $16, PTR2 .endr .byte 0x66,0x0f,0x38,0xdd,0x00+NPTR2 /* aesenclast (PTR2), %xmm0 */ .byte 0x66,0x0f,0x38,0xdd,0x08+NPTR2 /* aesenclast (PTR2), %xmm1 */ .byte 0x66,0x0f,0x38,0xdd,0x10+NPTR2 /* aesenclast (PTR2), %xmm2 */ .byte 0x66,0x0f,0x38,0xdd,0x18+NPTR2 /* aesenclast (PTR2), %xmm3 */ .byte 0x66,0x0f,0x38,0xdd,0x20+NPTR2 /* aesenclast (PTR2), %xmm4 */ .byte 0x66,0x0f,0x38,0xdd,0x28+NPTR2 /* aesenclast (PTR2), %xmm5 */ .byte 0x66,0x0f,0x38,0xdd,0x30+NPTR2 /* aesenclast (PTR2), %xmm6 */ .byte 0x66,0x0f,0x38,0xdd,0x38+NPTR2 /* aesenclast (PTR2), %xmm7 */ movdqa %xmm0, (0*16)(PTR0) movdqa %xmm1, (1*16)(PTR0) movdqa %xmm2, (2*16)(PTR0) movdqa %xmm3, (3*16)(PTR0) movdqa %xmm4, (4*16)(PTR0) movdqa %xmm5, (5*16)(PTR0) movdqa %xmm6, (6*16)(PTR0) movdqa %xmm7, (7*16)(PTR0) movdqa %xmm0, (0*16)(PTR1) movdqa %xmm1, (1*16)(PTR1) movdqa %xmm2, (2*16)(PTR1) movdqa %xmm3, (3*16)(PTR1) movdqa %xmm4, (4*16)(PTR1) movdqa %xmm5, (5*16)(PTR1) movdqa %xmm6, (6*16)(PTR1) movdqa %xmm7, (7*16)(PTR1) #if defined(__i386__) pop %ebp #endif ret ENDPROC(x86_aes_mangle) /* * AES round keys for an arbitrary key: * 00102030405060708090A0B0C0D0E0F0 */ .section ".rodata","a" .balign 16 aes_round_keys: .long 0x00102030, 0x40506070, 0x8090A0B0, 0xC0D0E0F0 .long 0x89D810E8, 0x855ACE68, 0x2D1843D8, 0xCB128FE4 .long 0x4915598F, 0x55E5D7A0, 0xDACA94FA, 0x1F0A63F7 .long 0xFA636A28, 0x25B339C9, 0x40668A31, 0x57244D17 .long 0x24724023, 0x6966B3FA, 0x6ED27532, 0x88425B6C .long 0xC81677BC, 0x9B7AC93B, 0x25027992, 0xB0261996 .long 0xC62FE109, 0xF75EEDC3, 0xCC79395D, 0x84F9CF5D .long 0xD1876C0F, 0x79C4300A, 0xB45594AD, 0xD66FF41F .long 0xFDE3BAD2, 0x05E5D0D7, 0x3547964E, 0xF1FE37F1 .long 0xBD6E7C3D, 0xF2B5779E, 0x0B61216E, 0x8B10B689 .long 0x69C4E0D8, 0x6A7B0430, 0xD8CDB780, 0x70B4C55A .size aes_round_keys, .-aes_round_keys .bss .balign 16 aes_fwd_state: .space 16 .size aes_fwd_state, .-aes_fwd_state #endif /* i386 or x86_64 */ /* * This is necessary to keep the whole executable * from needing a writable stack. */ .section .note.GNU-stack,"",%progbits