X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fx86cpuid.pl;h=c45b18356bb12814d028cd92c3a94292a2b23229;hb=a39aa18644d3338087a827c6555b18bc857346fe;hp=dca37e7cd265878d04a77d6dea0235add06e4c74;hpb=a90081576c94f9f54de1755188a00ccc1760549a;p=oweals%2Fopenssl.git diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index dca37e7cd2..c45b18356b 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -1,9 +1,19 @@ -#!/usr/bin/env perl +#! /usr/bin/env perl +# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC, "${dir}perlasm", "perlasm"); require "x86asm.pl"; +$output = pop; +open OUT,">$output"; +*STDOUT=*OUT; + &asm_init($ARGV[0],"x86cpuid"); for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } @@ -168,7 +178,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &ret (); &function_end_B("OPENSSL_rdtsc"); -# This works in Ring 0 only [read MS-DOS+privileged DPMI host], +# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host], # but it's safe to call it on any [supported] 32-bit platform... # Just check for [non-]zero return value... &function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); @@ -202,6 +212,41 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &ret (); &function_end_B("OPENSSL_instrument_halt"); +# Essentially there is only one use for this function. Under DJGPP: +# +# #include +# ... +# i=OPENSSL_far_spin(_dos_ds,0x46c); +# ... +# to obtain the number of spins till closest timer interrupt. + +&function_begin_B("OPENSSL_far_spin"); + &pushf (); + &pop ("eax"); + &bt ("eax",9); + &jnc (&label("nospin")); # interrupts are disabled + + &mov ("eax",&DWP(4,"esp")); + &mov ("ecx",&DWP(8,"esp")); + &data_word (0x90d88e1e); # push %ds, mov %eax,%ds + &xor ("eax","eax"); + &mov ("edx",&DWP(0,"ecx")); + &jmp (&label("spin")); + + &align (16); +&set_label("spin"); + &inc ("eax"); + &cmp ("edx",&DWP(0,"ecx")); + &je (&label("spin")); + + &data_word (0x1f909090); # pop %ds + &ret (); + +&set_label("nospin"); + &xor ("eax","eax"); + &xor ("edx","edx"); + &ret (); +&function_end_B("OPENSSL_far_spin"); &function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); &xor ("eax","eax"); @@ -320,6 +365,31 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &ret (); &function_end_B("OPENSSL_cleanse"); +&function_begin_B("CRYPTO_memcmp"); + &push ("esi"); + &push ("edi"); + &mov ("esi",&wparam(0)); + &mov ("edi",&wparam(1)); + &mov ("ecx",&wparam(2)); + &xor ("eax","eax"); + &xor ("edx","edx"); + &cmp ("ecx",0); + &je (&label("no_data")); +&set_label("loop"); + &mov ("dl",&BP(0,"esi")); + &lea ("esi",&DWP(1,"esi")); + &xor ("dl",&BP(0,"edi")); + &lea ("edi",&DWP(1,"edi")); + &or ("al","dl"); + &dec ("ecx"); + &jnz (&label("loop")); + &neg ("eax"); + &shr ("eax",31); +&set_label("no_data"); + &pop ("edi"); + &pop ("esi"); + &ret (); +&function_end_B("CRYPTO_memcmp"); { my $lasttick = "esi"; my $lastdiff = "ebx"; @@ -422,29 +492,64 @@ my $max = "ebp"; &function_end("OPENSSL_instrument_bus2"); } -&function_begin_B("OPENSSL_ia32_rdrand"); +sub gen_random { +my $rdop = shift; +&function_begin_B("OPENSSL_ia32_${rdop}"); &mov ("ecx",8); &set_label("loop"); - &rdrand ("eax"); + &${rdop}("eax"); &jc (&label("break")); &loop (&label("loop")); &set_label("break"); &cmp ("eax",0); &cmove ("eax","ecx"); &ret (); -&function_end_B("OPENSSL_ia32_rdrand"); +&function_end_B("OPENSSL_ia32_${rdop}"); + +&function_begin_B("OPENSSL_ia32_${rdop}_bytes"); + &push ("edi"); + &push ("ebx"); + &xor ("eax","eax"); # return value + &mov ("edi",&wparam(0)); + &mov ("ebx",&wparam(1)); + + &cmp ("ebx",0); + &je (&label("done")); -&function_begin_B("OPENSSL_ia32_rdseed"); &mov ("ecx",8); &set_label("loop"); - &rdseed ("eax"); + &${rdop}("edx"); &jc (&label("break")); &loop (&label("loop")); -&set_label("break"); - &cmp ("eax",0); - &cmove ("eax","ecx"); + &jmp (&label("done")); + +&set_label("break",16); + &cmp ("ebx",4); + &jb (&label("tail")); + &mov (&DWP(0,"edi"),"edx"); + &lea ("edi",&DWP(4,"edi")); + &add ("eax",4); + &sub ("ebx",4); + &jz (&label("done")); + &mov ("ecx",8); + &jmp (&label("loop")); + +&set_label("tail",16); + &mov (&BP(0,"edi"),"dl"); + &lea ("edi",&DWP(1,"edi")); + &inc ("eax"); + &shr ("edx",8); + &dec ("ebx"); + &jnz (&label("tail")); + +&set_label("done"); + &pop ("ebx"); + &pop ("edi"); &ret (); -&function_end_B("OPENSSL_ia32_rdseed"); +&function_end_B("OPENSSL_ia32_${rdop}_bytes"); +} +&gen_random("rdrand"); +&gen_random("rdseed"); &initseg("OPENSSL_cpuid_setup"); @@ -452,3 +557,5 @@ my $max = "ebp"; &hidden("OPENSSL_ia32cap_P"); &asm_finish(); + +close STDOUT;