blob: 55098e86588fbc6c3a9f7add143bf00cb5c66427 [file] [log] [blame]
/*
* Copyright (c) 2011, Intel Corporation
* Authors: Fenghua Yu <fenghua.yu@intel.com>,
* H. Peter Anvin <hpa@linux.intel.com>
*
* 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