default rel %define XMMWORD %define YMMWORD %define ZMMWORD EXTERN OPENSSL_cpuid_setup section .CRT$XCU rdata align=8 DQ OPENSSL_cpuid_setup common OPENSSL_ia32cap_P 16 section .text code align=64 global OPENSSL_atomic_add ALIGN 16 OPENSSL_atomic_add: mov eax,DWORD[rcx] $L$spin: lea r8,[rax*1+rdx] DB 0xf0 cmpxchg DWORD[rcx],r8d jne NEAR $L$spin mov eax,r8d DB 0x48,0x98 DB 0F3h,0C3h ;repret global OPENSSL_rdtsc ALIGN 16 OPENSSL_rdtsc: rdtsc shl rdx,32 or rax,rdx DB 0F3h,0C3h ;repret global OPENSSL_ia32_cpuid ALIGN 16 OPENSSL_ia32_cpuid: mov QWORD[8+rsp],rdi ;WIN64 prologue mov QWORD[16+rsp],rsi mov rax,rsp $L$SEH_begin_OPENSSL_ia32_cpuid: mov rdi,rcx mov r8,rbx xor eax,eax mov QWORD[8+rdi],rax cpuid mov r11d,eax xor eax,eax cmp ebx,0x756e6547 setne al mov r9d,eax cmp edx,0x49656e69 setne al or r9d,eax cmp ecx,0x6c65746e setne al or r9d,eax jz NEAR $L$intel cmp ebx,0x68747541 setne al mov r10d,eax cmp edx,0x69746E65 setne al or r10d,eax cmp ecx,0x444D4163 setne al or r10d,eax jnz NEAR $L$intel mov eax,0x80000000 cpuid cmp eax,0x80000001 jb NEAR $L$intel mov r10d,eax mov eax,0x80000001 cpuid or r9d,ecx and r9d,0x00000801 cmp r10d,0x80000008 jb NEAR $L$intel mov eax,0x80000008 cpuid movzx r10,cl inc r10 mov eax,1 cpuid bt edx,28 jnc NEAR $L$generic shr ebx,16 cmp bl,r10b ja NEAR $L$generic and edx,0xefffffff jmp NEAR $L$generic $L$intel: cmp r11d,4 mov r10d,-1 jb NEAR $L$nocacheinfo mov eax,4 mov ecx,0 cpuid mov r10d,eax shr r10d,14 and r10d,0xfff $L$nocacheinfo: mov eax,1 cpuid movd xmm0,eax and edx,0xbfefffff cmp r9d,0 jne NEAR $L$notintel or edx,0x40000000 and ah,15 cmp ah,15 jne NEAR $L$notP4 or edx,0x00100000 $L$notP4: cmp ah,6 jne NEAR $L$notintel and eax,0x0fff0ff0 cmp eax,0x00050670 je NEAR $L$knights cmp eax,0x00080650 jne NEAR $L$notintel $L$knights: and ecx,0xfbffffff $L$notintel: bt edx,28 jnc NEAR $L$generic and edx,0xefffffff cmp r10d,0 je NEAR $L$generic or edx,0x10000000 shr ebx,16 cmp bl,1 ja NEAR $L$generic and edx,0xefffffff $L$generic: and r9d,0x00000800 and ecx,0xfffff7ff or r9d,ecx mov r10d,edx cmp r11d,7 jb NEAR $L$no_extended_info mov eax,7 xor ecx,ecx cpuid bt r9d,26 jc NEAR $L$notknights and ebx,0xfff7ffff $L$notknights: movd eax,xmm0 and eax,0x0fff0ff0 cmp eax,0x00050650 jne NEAR $L$notskylakex and ebx,0xfffeffff $L$notskylakex: mov DWORD[8+rdi],ebx mov DWORD[12+rdi],ecx $L$no_extended_info: bt r9d,27 jnc NEAR $L$clear_avx xor ecx,ecx DB 0x0f,0x01,0xd0 and eax,0xe6 cmp eax,0xe6 je NEAR $L$done and DWORD[8+rdi],0x3fdeffff and eax,6 cmp eax,6 je NEAR $L$done $L$clear_avx: mov eax,0xefffe7ff and r9d,eax mov eax,0x3fdeffdf and DWORD[8+rdi],eax $L$done: shl r9,32 mov eax,r10d mov rbx,r8 or rax,r9 mov rdi,QWORD[8+rsp] ;WIN64 epilogue mov rsi,QWORD[16+rsp] DB 0F3h,0C3h ;repret $L$SEH_end_OPENSSL_ia32_cpuid: global OPENSSL_cleanse ALIGN 16 OPENSSL_cleanse: xor rax,rax cmp rdx,15 jae NEAR $L$ot cmp rdx,0 je NEAR $L$ret $L$ittle: mov BYTE[rcx],al sub rdx,1 lea rcx,[1+rcx] jnz NEAR $L$ittle $L$ret: DB 0F3h,0C3h ;repret ALIGN 16 $L$ot: test rcx,7 jz NEAR $L$aligned mov BYTE[rcx],al lea rdx,[((-1))+rdx] lea rcx,[1+rcx] jmp NEAR $L$ot $L$aligned: mov QWORD[rcx],rax lea rdx,[((-8))+rdx] test rdx,-8 lea rcx,[8+rcx] jnz NEAR $L$aligned cmp rdx,0 jne NEAR $L$ittle DB 0F3h,0C3h ;repret global CRYPTO_memcmp ALIGN 16 CRYPTO_memcmp: xor rax,rax xor r10,r10 cmp r8,0 je NEAR $L$no_data cmp r8,16 jne NEAR $L$oop_cmp mov r10,QWORD[rcx] mov r11,QWORD[8+rcx] mov r8,1 xor r10,QWORD[rdx] xor r11,QWORD[8+rdx] or r10,r11 cmovnz rax,r8 DB 0F3h,0C3h ;repret ALIGN 16 $L$oop_cmp: mov r10b,BYTE[rcx] lea rcx,[1+rcx] xor r10b,BYTE[rdx] lea rdx,[1+rdx] or al,r10b dec r8 jnz NEAR $L$oop_cmp neg rax shr rax,63 $L$no_data: DB 0F3h,0C3h ;repret global OPENSSL_wipe_cpu ALIGN 16 OPENSSL_wipe_cpu: pxor xmm0,xmm0 pxor xmm1,xmm1 pxor xmm2,xmm2 pxor xmm3,xmm3 pxor xmm4,xmm4 pxor xmm5,xmm5 xor rcx,rcx xor rdx,rdx xor r8,r8 xor r9,r9 xor r10,r10 xor r11,r11 lea rax,[8+rsp] DB 0F3h,0C3h ;repret global OPENSSL_instrument_bus ALIGN 16 OPENSSL_instrument_bus: mov r10,rcx mov rcx,rdx mov r11,rdx rdtsc mov r8d,eax mov r9d,0 clflush [r10] DB 0xf0 add DWORD[r10],r9d jmp NEAR $L$oop ALIGN 16 $L$oop: rdtsc mov edx,eax sub eax,r8d mov r8d,edx mov r9d,eax clflush [r10] DB 0xf0 add DWORD[r10],eax lea r10,[4+r10] sub rcx,1 jnz NEAR $L$oop mov rax,r11 DB 0F3h,0C3h ;repret global OPENSSL_instrument_bus2 ALIGN 16 OPENSSL_instrument_bus2: mov r10,rcx mov rcx,rdx mov r11,r8 mov QWORD[8+rsp],rcx rdtsc mov r8d,eax mov r9d,0 clflush [r10] DB 0xf0 add DWORD[r10],r9d rdtsc mov edx,eax sub eax,r8d mov r8d,edx mov r9d,eax $L$oop2: clflush [r10] DB 0xf0 add DWORD[r10],eax sub r11,1 jz NEAR $L$done2 rdtsc mov edx,eax sub eax,r8d mov r8d,edx cmp eax,r9d mov r9d,eax mov edx,0 setne dl sub rcx,rdx lea r10,[rdx*4+r10] jnz NEAR $L$oop2 $L$done2: mov rax,QWORD[8+rsp] sub rax,rcx DB 0F3h,0C3h ;repret global OPENSSL_ia32_rdrand_bytes ALIGN 16 OPENSSL_ia32_rdrand_bytes: xor rax,rax cmp rdx,0 je NEAR $L$done_rdrand_bytes mov r11,8 $L$oop_rdrand_bytes: DB 73,15,199,242 jc NEAR $L$break_rdrand_bytes dec r11 jnz NEAR $L$oop_rdrand_bytes jmp NEAR $L$done_rdrand_bytes ALIGN 16 $L$break_rdrand_bytes: cmp rdx,8 jb NEAR $L$tail_rdrand_bytes mov QWORD[rcx],r10 lea rcx,[8+rcx] add rax,8 sub rdx,8 jz NEAR $L$done_rdrand_bytes mov r11,8 jmp NEAR $L$oop_rdrand_bytes ALIGN 16 $L$tail_rdrand_bytes: mov BYTE[rcx],r10b lea rcx,[1+rcx] inc rax shr r10,8 dec rdx jnz NEAR $L$tail_rdrand_bytes $L$done_rdrand_bytes: xor r10,r10 DB 0F3h,0C3h ;repret global OPENSSL_ia32_rdseed_bytes ALIGN 16 OPENSSL_ia32_rdseed_bytes: xor rax,rax cmp rdx,0 je NEAR $L$done_rdseed_bytes mov r11,8 $L$oop_rdseed_bytes: DB 73,15,199,250 jc NEAR $L$break_rdseed_bytes dec r11 jnz NEAR $L$oop_rdseed_bytes jmp NEAR $L$done_rdseed_bytes ALIGN 16 $L$break_rdseed_bytes: cmp rdx,8 jb NEAR $L$tail_rdseed_bytes mov QWORD[rcx],r10 lea rcx,[8+rcx] add rax,8 sub rdx,8 jz NEAR $L$done_rdseed_bytes mov r11,8 jmp NEAR $L$oop_rdseed_bytes ALIGN 16 $L$tail_rdseed_bytes: mov BYTE[rcx],r10b lea rcx,[1+rcx] inc rax shr r10,8 dec rdx jnz NEAR $L$tail_rdseed_bytes $L$done_rdseed_bytes: xor r10,r10 DB 0F3h,0C3h ;repret