Compare commits

...

23 Commits

Author SHA1 Message Date
Andy Polyakov
d8a23532dd crypto/modes/modes_lcl.h: let STRICT_ALIGNMENT be on ARMv7.
While ARMv7 in general is capable of unaligned access, not all instructions
actually are. And trouble is that compiler doesn't seem to differentiate
those capable and incapable of unaligned access. Side effect is that kernel
goes into endless loop retrying same instruction triggering unaligned trap.
Problem was observed in xts128.c and ccm128.c modules. It's possible to
resolve it by using (volatile u32*) casts, but letting STRICT_ALIGNMENT
be feels more appropriate.

(cherry picked from commit 3bdd80521a)
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
2015-05-20 09:18:57 +02:00
Andy Polyakov
8a09500d9c util/incore update that allows FINGERPRINT_premain-free build.
As for complementary fips.c modification. Goal is to ensure that
FIPS_signature does not end up in .bss segment, one guaranteed to
be zeroed upon program start-up. One would expect explicitly
initialized values to end up in .data segment, but it turned out
that values explicitly initialized with zeros can end up in .bss.
The modification does not affect program flow, because first byte
was the only one of significance [to FINGERPRINT_premain].

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 34f39b062c)
2015-05-13 18:05:22 +02:00
Andy Polyakov
0ae1672287 Add support for Android 5, both 32- and 64-bit cases.
Special note about additional -pie flag in android-armv7. The initial
reason for adding it is that Android 5 refuses to execute non-PIE
binaries. But what about older systems and previously validated
platforms? It should be noted that flag is not used when compiling
object code, fipscanister.o in this context, only when linking
applications, *supplementary* fips_algvs used during validation
procedure.

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 6db8e3bdc9)

Resolved conflicts:
	test/fips_algvs.c
2015-05-13 18:04:56 +02:00
Andy Polyakov
292c1f34ec Additional vxWorks target.
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 50e2a0ea46)
2015-05-13 18:03:45 +02:00
Andy Polyakov
f447329da7 Configure: add ios-cross target with ARM assembly support.
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 97fbb0c88c)

Resolved conflicts:
	Configure
	config
2015-05-13 18:02:21 +02:00
Andy Polyakov
80b1e89bbc Add iOS-specific armv4cpud.S module.
Normally it would be generated from a perlasm module, but doing so
would affect existing armv4cpuid.S, which in turn would formally void
previously validated platforms. Hense separate module is generated.

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 5837e90f08)
2015-05-13 18:00:07 +02:00
Andy Polyakov
bb98f6bef6 Adapt ARM assembly pack for iOS.
This is achieved by filtering perlasm output through arm-xlate.pl. But note
that it's done only if "flavour" argument is not 'void'. As 'void' is
default value for other ARM targets, permasm output is not actually
filtered on previously validated platforms.

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 874faf2ffb)
2015-05-13 17:59:22 +02:00
Andy Polyakov
728b53058e Configure: engage ARMv8 assembly pack in ios64-cross target.
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit c6d109051d)

Resolved Conflicts:
	Configure
2015-05-13 17:57:37 +02:00
Andy Polyakov
3b3114770a Engage ARMv8 assembly pack.
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit 083ed53def)
2015-05-13 17:49:37 +02:00
Andy Polyakov
9b5db104ec Add ARMv8 assembly pack.
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
(cherry picked from commit b84813ec01)
2015-05-13 17:49:18 +02:00
Andy Polyakov
788715cecf Configure: add ios64 target.
Reviewed-by: Steve Marquess <marquess@openssl.org>
(cherry picked from commit b06f7d9ac0)
2014-10-23 21:03:52 +02:00
Andy Polyakov
cfcd27d35d Add iOS-specific FIPS addendum code.
Reviewed-by: Steve Marquess <marquess@openssl.org>
2014-10-23 21:02:33 +02:00
Rich Salz
177118fc2b RT2849: Redundant check of "dsa" variable.
In the current code, the check isn't redundant.
And in fact the REAL check was missing.
This avoids a NULL-deref crash.

Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
2014-09-08 11:02:54 -04:00
Dr. Stephen Henson
551ed53b2a Fix copy for CCM, GCM and XTS.
Internal pointers in CCM, GCM and XTS contexts should either be
NULL or set to point to the appropriate key schedule. This needs
to be adjusted when copying contexts.

Combination of 2 commits:
370bf1d708
c2fd5d79ff
2014-07-11 21:44:47 +01:00
Dr. Stephen Henson
6ea511211c Only cleanse sbuf if it is not NULL.
PR#2339
2014-07-05 22:32:39 +01:00
Alan Hryngle
114216bca0 Check return smaller of ret and f.
PR#3418.
(cherry picked from commit d4909f9a8dbbda9c5d140476b34a8f80b02b51f3)
2014-07-05 22:27:42 +01:00
Andy Polyakov
493119b1a8 cryptlib.c: fix typo in WIN32 version of OPENSSL_showfatal. 2014-04-02 21:48:56 +02:00
Dr. Stephen Henson
6fb0806b01 Add verbose option to fips_test_suite to give additional details of
all operations.

Add ecdsa test.

Test crypto operations are inhibited on test failures.

Test on demand POST.
2013-01-23 02:57:36 +00:00
Dr. Stephen Henson
950e2889e1 Now GMAC is fixed remove workaround. 2013-01-16 14:20:01 +00:00
Dr. Stephen Henson
043c341366 Add .gitignore 2013-01-10 23:29:59 +00:00
Dr. Stephen Henson
b1adc971b4 Make DES3 and ECDSA self tests continue with remaining cases on
failure.

Make fips_test_suite induced failure work on every possible subtest instead
of just categories of subtest.
2012-12-28 20:19:10 +00:00
Andy Polyakov
9f3f7ce9e8 VC-32.pl: fix typo [from HEAD].
Submitted by: Pierre Delaage
2012-12-16 19:42:44 +00:00
Andy Polyakov
9abbb6aa89 Cumulative updates from HEAD. 2012-10-29 22:26:27 +00:00
52 changed files with 4912 additions and 200 deletions

70
.gitignore vendored Normal file
View File

@@ -0,0 +1,70 @@
# Object files
*.o
# Top level excludes
/Makefile.bak
/Makefile
/*.a
/include
/*.pc
/rehash.time
# Most *.c files under test/ are symlinks
/test/*.c
# Apart from these
!/test/asn1test.c
!/test/methtest.c
!/test/dummytest.c
!/test/igetest.c
!/test/r160test.c
!/test/fips_algvs.c
# Certificate symbolic links
*.0
# Links under apps
/apps/CA.pl
/apps/md4.c
# Auto generated headers
/crypto/buildinf.h
/crypto/opensslconf.h
# Auto generated assembly language source files
*.s
!/crypto/bn/asm/pa-risc2.s
!/crypto/bn/asm/pa-risc2W.s
# Executables
/apps/openssl
/test/sha256t
/test/sha512t
/test/*test
/test/fips_aesavs
/test/fips_desmovs
/test/fips_dhvs
/test/fips_drbgvs
/test/fips_dssvs
/test/fips_ecdhvs
/test/fips_ecdsavs
/test/fips_rngvs
/test/fips_test_suite
*.so*
*.dylib*
*.dll*
# Exceptions
!/test/bctest
!/crypto/des/times/486-50.sol
# Misc auto generated files
/tools/c_rehash
/test/evptests.txt
lib
Makefile.save
*.bak
# FIPS module specific files.
/fips/fips_auth.h
/fips/fips_standalone_sha1
/fips/fipscanister.o.sha1

View File

@@ -136,6 +136,7 @@ my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::
my $mips64_asm=":bn-mips.o mips-mont.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o sha512-mips.o::::::::";
my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o s390x-gf2m.o::aes_ctr.o aes-s390x.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::ghash-s390x.o:";
my $armv4_asm="armcap.o armv4cpuid.o:bn_asm.o armv4-mont.o armv4-gf2m.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::ghash-armv4.o::void";
my $aarch64_asm="armcap.o arm64cpuid.o mem_clr.o:::aes_core.o aes_cbc.o aesv8-armx.o:::sha1-armv8.o sha256-armv8.o sha512-armv8.o:::::::ghashv8-armx.o:";
my $parisc11_asm="pariscid.o:bn_asm.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::32";
my $parisc20_asm="pariscid.o:pa-risc2W.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::64";
my $ppc32_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::::";
@@ -401,7 +402,8 @@ my %table=(
# Android: linux-* but without -DTERMIO and pointers to headers and libs.
"android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-pie%-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android64-aarch64","gcc:-mandroid -fPIC -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-pie%-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${aarch64_asm}:linux64:dlfcn:linux-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### *BSD [do see comment about ${BSDthreads} above!]
"BSD-generic32","gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -581,7 +583,23 @@ my %table=(
"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
# iPhoneOS/iOS
"iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
#
# It takes three prior-set environment variables to make it work:
#
# CROSS_COMPILE=/where/toolchain/is/usr/bin/ [note ending slash]
# CROSS_TOP=/where/SDKs/are
# CROSS_SDK=iPhoneOSx.y.sdk
#
# Exact paths vary with Xcode releases, but for couple of last ones
# they would look like this:
#
# CROSS_COMPILE=`xcode-select --print-path`/Toolchains/XcodeDefault.xctoolchain/usr/bin/
# CROSS_TOP=`xcode-select --print-path`/Platforms/iPhoneOS.platform/Developer
# CROSS_SDK=iPhoneOS7.0.sdk
#
"iphoneos-cross","cc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"ios-cross","cc:-O3 -arch armv7 -mios-version-min=7.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:armcap.o armv4cpuid_ios.o:bn_asm.o armv4-mont.o armv4-gf2m.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::ghash-armv4.o::ios32:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
"ios64-cross","cc:-O3 -arch arm64 -mios-version-min=7.0.0 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR -RC4_CHUNK DES_INT DES_UNROLL -BF_PTR:${aarch64_asm}:ios64:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
##### A/UX
"aux3-gcc","gcc:-O2 -DTERMIO::(unknown):AUX:-lbsd:RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::",
@@ -598,6 +616,7 @@ my %table=(
##### VxWorks for various targets
"vxworks-ppc60x","ccppc:-D_REENTRANT -mrtp -mhard-float -mstrict-align -fno-implicit-fp -DPPC32_fp60x -O2 -fstrength-reduce -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common:::::",
"vxworks-ppcgen","ccppc:-D_REENTRANT -mrtp -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon:::::",
"vxworks-ppcgen-kernel","ccppc:-D_REENTRANT -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/h -I\$(WIND_BASE)/target/h/wrn/coreip:::VXWORKS::::::",
"vxworks-ppc405","ccppc:-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
"vxworks-ppc750","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG):::VXWORKS:-r:::::",
"vxworks-ppc750-debug","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG -g:::VXWORKS:-r:::::",
@@ -1560,7 +1579,7 @@ if ($rmd160_obj =~ /\.o$/)
}
if ($aes_obj =~ /\.o$/)
{
$cflags.=" -DAES_ASM";
$cflags.=" -DAES_ASM" if ($aes_obj =~ m/\baes\-/);
# aes_ctr.o is not a real file, only indication that assembler
# module implements AES_ctr32_encrypt...
$cflags.=" -DAES_CTR_ASM" if ($aes_obj =~ s/\s*aes_ctr\.o//);
@@ -1581,7 +1600,7 @@ else {
$wp_obj="wp_block.o";
}
$cmll_obj=$cmll_enc unless ($cmll_obj =~ /.o$/);
if ($modes_obj =~ /ghash/)
if ($modes_obj =~ /ghash\-/)
{
$cflags.=" -DGHASH_ASM";
}

36
TABLE
View File

@@ -3465,8 +3465,42 @@ $ranlib =
$arflags =
$multilib =
*** ios64-cross
$cc = cc
$cflags = -O3 -arch arm64 -mios-version-min=7.0.0 -isysroot $(CROSS_TOP)/SDKs/$(CROSS_SDK) -fno-common
$unistd =
$thread_cflag = -D_REENTRANT
$sys_id = iOS
$lflags = -Wl,-search_paths_first%
$bn_ops = SIXTY_FOUR_BIT_LONG RC4_CHAR -RC4_CHUNK DES_INT DES_UNROLL -BF_PTR
$cpuid_obj =
$bn_obj =
$ec_obj =
$des_obj =
$aes_obj =
$bf_obj =
$md5_obj =
$sha1_obj =
$cast_obj =
$rc4_obj =
$rmd160_obj =
$rc5_obj =
$wp_obj =
$cmll_obj =
$modes_obj =
$engines_obj =
$perlasm_scheme = void
$dso_scheme = dlfcn
$shared_target= darwin-shared
$shared_cflag = -fPIC -fno-common
$shared_ldflag = -dynamiclib
$shared_extension = .$(SHLIB_MAJOR).$(SHLIB_MINOR).dylib
$ranlib =
$arflags =
$multilib =
*** iphoneos-cross
$cc = llvm-gcc
$cc = cc
$cflags = -O3 -isysroot $(CROSS_TOP)/SDKs/$(CROSS_SDK) -fomit-frame-pointer -fno-common
$unistd =
$thread_cflag = -D_REENTRANT

10
config
View File

@@ -375,6 +375,10 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in
echo "nsr-tandem-nsk"; exit 0;
;;
vxworks:kernel*)
echo "${MACHINE}-kernel-vxworks"; exit 0;
;;
vxworks*)
echo "${MACHINE}-whatever-vxworks"; exit 0;
;;
@@ -576,6 +580,10 @@ case "$GUESSOS" in
*-*-iphoneos)
options="$options -arch%20${MACHINE}"
OUT="iphoneos-cross" ;;
armv7-*-ios)
OUT="ios-cross" ;;
arm64-*-ios*)
OUT="ios64-cross" ;;
alpha-*-linux2)
ISA=`awk '/cpu model/{print$4;exit(0);}' /proc/cpuinfo`
case ${ISA:-generic} in
@@ -601,6 +609,7 @@ case "$GUESSOS" in
;;
ppc-*-linux2) OUT="linux-ppc" ;;
ppc60x-*-vxworks*) OUT="vxworks-ppc60x" ;;
ppcgen-kernel-vxworks*) OUT="vxworks-ppcgen-kernel" ;;
ppcgen-*-vxworks*) OUT="vxworks-ppcgen" ;;
pentium-*-vxworks*) OUT="vxworks-pentium" ;;
simlinux-*-vxworks*) OUT="vxworks-simlinux" ;;
@@ -852,6 +861,7 @@ case "$GUESSOS" in
*-*-qnx6) OUT="QNX6" ;;
x86-*-android|i?86-*-android) OUT="android-x86" ;;
armv[7-9]*-*-android) OUT="android-armv7" ;;
aarch64-*-android) OUT="android64-aarch64" ;;
*) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
esac

View File

@@ -87,6 +87,7 @@ ppccpuid.s: ppccpuid.pl; $(PERL) ppccpuid.pl $(PERLASM_SCHEME) $@
pariscid.s: pariscid.pl; $(PERL) pariscid.pl $(PERLASM_SCHEME) $@
alphacpuid.s: alphacpuid.pl
$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
arm64cpuid.S: arm64cpuid.pl; $(PERL) arm64cpuid.pl $(PERLASM_SCHEME) > $@
subdirs:
@target=all; $(RECURSIVE_MAKE)

View File

@@ -78,6 +78,10 @@ aes-parisc.s: asm/aes-parisc.pl
aes-mips.S: asm/aes-mips.pl
$(PERL) asm/aes-mips.pl $(PERLASM_SCHEME) $@
aesv8-armx.S: asm/aesv8-armx.pl
$(PERL) asm/aesv8-armx.pl $(PERLASM_SCHEME) $@
aesv8-armx.o: aesv8-armx.S
# GNU make "catch all"
aes-%.S: asm/aes-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
aes-armv4.o: aes-armv4.S

View File

@@ -32,8 +32,20 @@
# Profiler-assisted and platform-specific optimization resulted in 16%
# improvement on Cortex A8 core and ~21.5 cycles per byte.
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
$s0="r0";
$s1="r1";
@@ -171,7 +183,12 @@ AES_encrypt:
stmdb sp!,{r1,r4-r12,lr}
mov $rounds,r0 @ inp
mov $key,r2
#ifdef __APPLE__
mov $tbl,#AES_encrypt-AES_Te
sub $tbl,r3,$tbl @ Te
#else
sub $tbl,r3,#AES_encrypt-AES_Te @ Te
#endif
#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...
@@ -425,7 +442,12 @@ AES_set_encrypt_key:
bne .Labrt
.Lok: stmdb sp!,{r4-r12,lr}
#ifdef __APPLE__
mov $tbl,#AES_set_encrypt_key-AES_Te-1024
sub $tbl,r3,$tbl @ Te4
#else
sub $tbl,r3,#AES_set_encrypt_key-AES_Te-1024 @ Te4
#endif
mov $rounds,r0 @ inp
mov lr,r1 @ bits
@@ -886,7 +908,12 @@ AES_decrypt:
stmdb sp!,{r1,r4-r12,lr}
mov $rounds,r0 @ inp
mov $key,r2
#ifdef __APPLE__
mov $tbl,#AES_decrypt-AES_Td
sub $tbl,r3,$tbl @ Td
#else
sub $tbl,r3,#AES_decrypt-AES_Td @ Td
#endif
#if __ARM_ARCH__<7
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
ldrb $t1,[$rounds,#2] @ manner...

View File

@@ -0,0 +1,968 @@
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
#
# This module implements support for ARMv8 AES instructions. The
# module is endian-agnostic in sense that it supports both big- and
# little-endian cases. As does it support both 32- and 64-bit modes
# of operation. Latter is achieved by limiting amount of utilized
# registers to 16, which implies additional NEON load and integer
# instructions. This has no effect on mighty Apple A7, where results
# are literally equal to the theoretical estimates based on AES
# instruction latencies and issue rates. On Cortex-A53, an in-order
# execution core, this costs up to 10-15%, which is partially
# compensated by implementing dedicated code path for 128-bit
# CBC encrypt case. On Cortex-A57 parallelizable mode performance
# seems to be limited by sheer amount of NEON instructions...
#
# Performance in cycles per byte processed with 128-bit key:
#
# CBC enc CBC dec CTR
# Apple A7 2.39 1.20 1.20
# Cortex-A53 2.45 1.87 1.94
# Cortex-A57 3.64 1.34 1.32
$flavour = shift;
$output = shift;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
$prefix="aes_v8";
$code=<<___;
#include "arm_arch.h"
#if __ARM_ARCH__>=7
.text
___
$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
$code.=".fpu neon\n.code 32\n" if ($flavour !~ /64/);
# Assembler mnemonics are an eclectic mix of 32- and 64-bit syntax,
# NEON is mostly 32-bit mnemonics, integer - mostly 64. Goal is to
# maintain both 32- and 64-bit codes within single module and
# transliterate common code to either flavour with regex vodoo.
#
{{{
my ($inp,$bits,$out,$ptr,$rounds)=("x0","w1","x2","x3","w12");
my ($zero,$rcon,$mask,$in0,$in1,$tmp,$key)=
$flavour=~/64/? map("q$_",(0..6)) : map("q$_",(0..3,8..10));
$code.=<<___;
.align 5
.Lrcon:
.long 0x01,0x01,0x01,0x01
.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat
.long 0x1b,0x1b,0x1b,0x1b
.globl ${prefix}_set_encrypt_key
.type ${prefix}_set_encrypt_key,%function
.align 5
${prefix}_set_encrypt_key:
.Lenc_key:
___
$code.=<<___ if ($flavour =~ /64/);
stp x29,x30,[sp,#-16]!
add x29,sp,#0
___
$code.=<<___;
mov $ptr,#-1
cmp $inp,#0
b.eq .Lenc_key_abort
cmp $out,#0
b.eq .Lenc_key_abort
mov $ptr,#-2
cmp $bits,#128
b.lt .Lenc_key_abort
cmp $bits,#256
b.gt .Lenc_key_abort
tst $bits,#0x3f
b.ne .Lenc_key_abort
adr $ptr,.Lrcon
cmp $bits,#192
veor $zero,$zero,$zero
vld1.8 {$in0},[$inp],#16
mov $bits,#8 // reuse $bits
vld1.32 {$rcon,$mask},[$ptr],#32
b.lt .Loop128
b.eq .L192
b .L256
.align 4
.Loop128:
vtbl.8 $key,{$in0},$mask
vext.8 $tmp,$zero,$in0,#12
vst1.32 {$in0},[$out],#16
aese $key,$zero
subs $bits,$bits,#1
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $key,$key,$rcon
veor $in0,$in0,$tmp
vshl.u8 $rcon,$rcon,#1
veor $in0,$in0,$key
b.ne .Loop128
vld1.32 {$rcon},[$ptr]
vtbl.8 $key,{$in0},$mask
vext.8 $tmp,$zero,$in0,#12
vst1.32 {$in0},[$out],#16
aese $key,$zero
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $key,$key,$rcon
veor $in0,$in0,$tmp
vshl.u8 $rcon,$rcon,#1
veor $in0,$in0,$key
vtbl.8 $key,{$in0},$mask
vext.8 $tmp,$zero,$in0,#12
vst1.32 {$in0},[$out],#16
aese $key,$zero
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $key,$key,$rcon
veor $in0,$in0,$tmp
veor $in0,$in0,$key
vst1.32 {$in0},[$out]
add $out,$out,#0x50
mov $rounds,#10
b .Ldone
.align 4
.L192:
vld1.8 {$in1},[$inp],#8
vmov.i8 $key,#8 // borrow $key
vst1.32 {$in0},[$out],#16
vsub.i8 $mask,$mask,$key // adjust the mask
.Loop192:
vtbl.8 $key,{$in1},$mask
vext.8 $tmp,$zero,$in0,#12
vst1.32 {$in1},[$out],#8
aese $key,$zero
subs $bits,$bits,#1
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in0,$in0,$tmp
vdup.32 $tmp,${in0}[3]
veor $tmp,$tmp,$in1
veor $key,$key,$rcon
vext.8 $in1,$zero,$in1,#12
vshl.u8 $rcon,$rcon,#1
veor $in1,$in1,$tmp
veor $in0,$in0,$key
veor $in1,$in1,$key
vst1.32 {$in0},[$out],#16
b.ne .Loop192
mov $rounds,#12
add $out,$out,#0x20
b .Ldone
.align 4
.L256:
vld1.8 {$in1},[$inp]
mov $bits,#7
mov $rounds,#14
vst1.32 {$in0},[$out],#16
.Loop256:
vtbl.8 $key,{$in1},$mask
vext.8 $tmp,$zero,$in0,#12
vst1.32 {$in1},[$out],#16
aese $key,$zero
subs $bits,$bits,#1
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in0,$in0,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $key,$key,$rcon
veor $in0,$in0,$tmp
vshl.u8 $rcon,$rcon,#1
veor $in0,$in0,$key
vst1.32 {$in0},[$out],#16
b.eq .Ldone
vdup.32 $key,${in0}[3] // just splat
vext.8 $tmp,$zero,$in1,#12
aese $key,$zero
veor $in1,$in1,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in1,$in1,$tmp
vext.8 $tmp,$zero,$tmp,#12
veor $in1,$in1,$tmp
veor $in1,$in1,$key
b .Loop256
.Ldone:
str $rounds,[$out]
mov $ptr,#0
.Lenc_key_abort:
mov x0,$ptr // return value
`"ldr x29,[sp],#16" if ($flavour =~ /64/)`
ret
.size ${prefix}_set_encrypt_key,.-${prefix}_set_encrypt_key
.globl ${prefix}_set_decrypt_key
.type ${prefix}_set_decrypt_key,%function
.align 5
${prefix}_set_decrypt_key:
___
$code.=<<___ if ($flavour =~ /64/);
stp x29,x30,[sp,#-16]!
add x29,sp,#0
___
$code.=<<___ if ($flavour !~ /64/);
stmdb sp!,{r4,lr}
___
$code.=<<___;
bl .Lenc_key
cmp x0,#0
b.ne .Ldec_key_abort
sub $out,$out,#240 // restore original $out
mov x4,#-16
add $inp,$out,x12,lsl#4 // end of key schedule
vld1.32 {v0.16b},[$out]
vld1.32 {v1.16b},[$inp]
vst1.32 {v0.16b},[$inp],x4
vst1.32 {v1.16b},[$out],#16
.Loop_imc:
vld1.32 {v0.16b},[$out]
vld1.32 {v1.16b},[$inp]
aesimc v0.16b,v0.16b
aesimc v1.16b,v1.16b
vst1.32 {v0.16b},[$inp],x4
vst1.32 {v1.16b},[$out],#16
cmp $inp,$out
b.hi .Loop_imc
vld1.32 {v0.16b},[$out]
aesimc v0.16b,v0.16b
vst1.32 {v0.16b},[$inp]
eor x0,x0,x0 // return value
.Ldec_key_abort:
___
$code.=<<___ if ($flavour !~ /64/);
ldmia sp!,{r4,pc}
___
$code.=<<___ if ($flavour =~ /64/);
ldp x29,x30,[sp],#16
ret
___
$code.=<<___;
.size ${prefix}_set_decrypt_key,.-${prefix}_set_decrypt_key
___
}}}
{{{
sub gen_block () {
my $dir = shift;
my ($e,$mc) = $dir eq "en" ? ("e","mc") : ("d","imc");
my ($inp,$out,$key)=map("x$_",(0..2));
my $rounds="w3";
my ($rndkey0,$rndkey1,$inout)=map("q$_",(0..3));
$code.=<<___;
.globl ${prefix}_${dir}crypt
.type ${prefix}_${dir}crypt,%function
.align 5
${prefix}_${dir}crypt:
ldr $rounds,[$key,#240]
vld1.32 {$rndkey0},[$key],#16
vld1.8 {$inout},[$inp]
sub $rounds,$rounds,#2
vld1.32 {$rndkey1},[$key],#16
.Loop_${dir}c:
aes$e $inout,$rndkey0
vld1.32 {$rndkey0},[$key],#16
aes$mc $inout,$inout
subs $rounds,$rounds,#2
aes$e $inout,$rndkey1
vld1.32 {$rndkey1},[$key],#16
aes$mc $inout,$inout
b.gt .Loop_${dir}c
aes$e $inout,$rndkey0
vld1.32 {$rndkey0},[$key]
aes$mc $inout,$inout
aes$e $inout,$rndkey1
veor $inout,$inout,$rndkey0
vst1.8 {$inout},[$out]
ret
.size ${prefix}_${dir}crypt,.-${prefix}_${dir}crypt
___
}
&gen_block("en");
&gen_block("de");
}}}
{{{
my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my $enc="w5";
my ($rounds,$cnt,$key_,$step,$step1)=($enc,"w6","x7","x8","x12");
my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
my ($dat,$tmp,$rndzero_n_last)=($dat0,$tmp0,$tmp1);
### q8-q15 preloaded key schedule
$code.=<<___;
.globl ${prefix}_cbc_encrypt
.type ${prefix}_cbc_encrypt,%function
.align 5
${prefix}_cbc_encrypt:
___
$code.=<<___ if ($flavour =~ /64/);
stp x29,x30,[sp,#-16]!
add x29,sp,#0
___
$code.=<<___ if ($flavour !~ /64/);
mov ip,sp
stmdb sp!,{r4-r8,lr}
vstmdb sp!,{d8-d15} @ ABI specification says so
ldmia ip,{r4-r5} @ load remaining args
___
$code.=<<___;
subs $len,$len,#16
mov $step,#16
b.lo .Lcbc_abort
cclr $step,eq
cmp $enc,#0 // en- or decrypting?
ldr $rounds,[$key,#240]
and $len,$len,#-16
vld1.8 {$ivec},[$ivp]
vld1.8 {$dat},[$inp],$step
vld1.32 {q8-q9},[$key] // load key schedule...
sub $rounds,$rounds,#6
add $key_,$key,x5,lsl#4 // pointer to last 7 round keys
sub $rounds,$rounds,#2
vld1.32 {q10-q11},[$key_],#32
vld1.32 {q12-q13},[$key_],#32
vld1.32 {q14-q15},[$key_],#32
vld1.32 {$rndlast},[$key_]
add $key_,$key,#32
mov $cnt,$rounds
b.eq .Lcbc_dec
cmp $rounds,#2
veor $dat,$dat,$ivec
veor $rndzero_n_last,q8,$rndlast
b.eq .Lcbc_enc128
.Loop_cbc_enc:
aese $dat,q8
vld1.32 {q8},[$key_],#16
aesmc $dat,$dat
subs $cnt,$cnt,#2
aese $dat,q9
vld1.32 {q9},[$key_],#16
aesmc $dat,$dat
b.gt .Loop_cbc_enc
aese $dat,q8
aesmc $dat,$dat
subs $len,$len,#16
aese $dat,q9
aesmc $dat,$dat
cclr $step,eq
aese $dat,q10
aesmc $dat,$dat
add $key_,$key,#16
aese $dat,q11
aesmc $dat,$dat
vld1.8 {q8},[$inp],$step
aese $dat,q12
aesmc $dat,$dat
veor q8,q8,$rndzero_n_last
aese $dat,q13
aesmc $dat,$dat
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
aese $dat,q14
aesmc $dat,$dat
aese $dat,q15
mov $cnt,$rounds
veor $ivec,$dat,$rndlast
vst1.8 {$ivec},[$out],#16
b.hs .Loop_cbc_enc
b .Lcbc_done
.align 5
.Lcbc_enc128:
vld1.32 {$in0-$in1},[$key_]
aese $dat,q8
aesmc $dat,$dat
b .Lenter_cbc_enc128
.Loop_cbc_enc128:
aese $dat,q8
aesmc $dat,$dat
vst1.8 {$ivec},[$out],#16
.Lenter_cbc_enc128:
aese $dat,q9
aesmc $dat,$dat
subs $len,$len,#16
aese $dat,$in0
aesmc $dat,$dat
cclr $step,eq
aese $dat,$in1
aesmc $dat,$dat
aese $dat,q10
aesmc $dat,$dat
aese $dat,q11
aesmc $dat,$dat
vld1.8 {q8},[$inp],$step
aese $dat,q12
aesmc $dat,$dat
aese $dat,q13
aesmc $dat,$dat
aese $dat,q14
aesmc $dat,$dat
veor q8,q8,$rndzero_n_last
aese $dat,q15
veor $ivec,$dat,$rndlast
b.hs .Loop_cbc_enc128
vst1.8 {$ivec},[$out],#16
b .Lcbc_done
___
{
my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
$code.=<<___;
.align 5
.Lcbc_dec:
vld1.8 {$dat2},[$inp],#16
subs $len,$len,#32 // bias
add $cnt,$rounds,#2
vorr $in1,$dat,$dat
vorr $dat1,$dat,$dat
vorr $in2,$dat2,$dat2
b.lo .Lcbc_dec_tail
vorr $dat1,$dat2,$dat2
vld1.8 {$dat2},[$inp],#16
vorr $in0,$dat,$dat
vorr $in1,$dat1,$dat1
vorr $in2,$dat2,$dat2
.Loop3x_cbc_dec:
aesd $dat0,q8
aesd $dat1,q8
aesd $dat2,q8
vld1.32 {q8},[$key_],#16
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
subs $cnt,$cnt,#2
aesd $dat0,q9
aesd $dat1,q9
aesd $dat2,q9
vld1.32 {q9},[$key_],#16
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
b.gt .Loop3x_cbc_dec
aesd $dat0,q8
aesd $dat1,q8
aesd $dat2,q8
veor $tmp0,$ivec,$rndlast
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
veor $tmp1,$in0,$rndlast
aesd $dat0,q9
aesd $dat1,q9
aesd $dat2,q9
veor $tmp2,$in1,$rndlast
subs $len,$len,#0x30
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
vorr $ivec,$in2,$in2
mov.lo x6,$len // x6, $cnt, is zero at this point
aesd $dat0,q12
aesd $dat1,q12
aesd $dat2,q12
add $inp,$inp,x6 // $inp is adjusted in such way that
// at exit from the loop $dat1-$dat2
// are loaded with last "words"
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
mov $key_,$key
aesd $dat0,q13
aesd $dat1,q13
aesd $dat2,q13
vld1.8 {$in0},[$inp],#16
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
vld1.8 {$in1},[$inp],#16
aesd $dat0,q14
aesd $dat1,q14
aesd $dat2,q14
vld1.8 {$in2},[$inp],#16
aesimc $dat0,$dat0
aesimc $dat1,$dat1
aesimc $dat2,$dat2
vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0]
aesd $dat0,q15
aesd $dat1,q15
aesd $dat2,q15
add $cnt,$rounds,#2
veor $tmp0,$tmp0,$dat0
veor $tmp1,$tmp1,$dat1
veor $dat2,$dat2,$tmp2
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
vorr $dat0,$in0,$in0
vst1.8 {$tmp0},[$out],#16
vorr $dat1,$in1,$in1
vst1.8 {$tmp1},[$out],#16
vst1.8 {$dat2},[$out],#16
vorr $dat2,$in2,$in2
b.hs .Loop3x_cbc_dec
cmn $len,#0x30
b.eq .Lcbc_done
nop
.Lcbc_dec_tail:
aesd $dat1,q8
aesd $dat2,q8
vld1.32 {q8},[$key_],#16
aesimc $dat1,$dat1
aesimc $dat2,$dat2
subs $cnt,$cnt,#2
aesd $dat1,q9
aesd $dat2,q9
vld1.32 {q9},[$key_],#16
aesimc $dat1,$dat1
aesimc $dat2,$dat2
b.gt .Lcbc_dec_tail
aesd $dat1,q8
aesd $dat2,q8
aesimc $dat1,$dat1
aesimc $dat2,$dat2
aesd $dat1,q9
aesd $dat2,q9
aesimc $dat1,$dat1
aesimc $dat2,$dat2
aesd $dat1,q12
aesd $dat2,q12
aesimc $dat1,$dat1
aesimc $dat2,$dat2
cmn $len,#0x20
aesd $dat1,q13
aesd $dat2,q13
aesimc $dat1,$dat1
aesimc $dat2,$dat2
veor $tmp1,$ivec,$rndlast
aesd $dat1,q14
aesd $dat2,q14
aesimc $dat1,$dat1
aesimc $dat2,$dat2
veor $tmp2,$in1,$rndlast
aesd $dat1,q15
aesd $dat2,q15
b.eq .Lcbc_dec_one
veor $tmp1,$tmp1,$dat1
veor $tmp2,$tmp2,$dat2
vorr $ivec,$in2,$in2
vst1.8 {$tmp1},[$out],#16
vst1.8 {$tmp2},[$out],#16
b .Lcbc_done
.Lcbc_dec_one:
veor $tmp1,$tmp1,$dat2
vorr $ivec,$in2,$in2
vst1.8 {$tmp1},[$out],#16
.Lcbc_done:
vst1.8 {$ivec},[$ivp]
.Lcbc_abort:
___
}
$code.=<<___ if ($flavour !~ /64/);
vldmia sp!,{d8-d15}
ldmia sp!,{r4-r8,pc}
___
$code.=<<___ if ($flavour =~ /64/);
ldr x29,[sp],#16
ret
___
$code.=<<___;
.size ${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt
___
}}}
{{{
my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4));
my ($rounds,$cnt,$key_)=("w5","w6","x7");
my ($ctr,$tctr0,$tctr1,$tctr2)=map("w$_",(8..10,12));
my $step="x12"; # aliases with $tctr2
my ($dat0,$dat1,$in0,$in1,$tmp0,$tmp1,$ivec,$rndlast)=map("q$_",(0..7));
my ($dat2,$in2,$tmp2)=map("q$_",(10,11,9));
my ($dat,$tmp)=($dat0,$tmp0);
### q8-q15 preloaded key schedule
$code.=<<___;
.globl ${prefix}_ctr32_encrypt_blocks
.type ${prefix}_ctr32_encrypt_blocks,%function
.align 5
${prefix}_ctr32_encrypt_blocks:
___
$code.=<<___ if ($flavour =~ /64/);
stp x29,x30,[sp,#-16]!
add x29,sp,#0
___
$code.=<<___ if ($flavour !~ /64/);
mov ip,sp
stmdb sp!,{r4-r10,lr}
vstmdb sp!,{d8-d15} @ ABI specification says so
ldr r4, [ip] @ load remaining arg
___
$code.=<<___;
ldr $rounds,[$key,#240]
ldr $ctr, [$ivp, #12]
vld1.32 {$dat0},[$ivp]
vld1.32 {q8-q9},[$key] // load key schedule...
sub $rounds,$rounds,#4
mov $step,#16
cmp $len,#2
add $key_,$key,x5,lsl#4 // pointer to last 5 round keys
sub $rounds,$rounds,#2
vld1.32 {q12-q13},[$key_],#32
vld1.32 {q14-q15},[$key_],#32
vld1.32 {$rndlast},[$key_]
add $key_,$key,#32
mov $cnt,$rounds
cclr $step,lo
#ifndef __ARMEB__
rev $ctr, $ctr
#endif
vorr $dat1,$dat0,$dat0
add $tctr1, $ctr, #1
vorr $dat2,$dat0,$dat0
add $ctr, $ctr, #2
vorr $ivec,$dat0,$dat0
rev $tctr1, $tctr1
vmov.32 ${dat1}[3],$tctr1
b.ls .Lctr32_tail
rev $tctr2, $ctr
sub $len,$len,#3 // bias
vmov.32 ${dat2}[3],$tctr2
b .Loop3x_ctr32
.align 4
.Loop3x_ctr32:
aese $dat0,q8
aese $dat1,q8
aese $dat2,q8
vld1.32 {q8},[$key_],#16
aesmc $dat0,$dat0
aesmc $dat1,$dat1
aesmc $dat2,$dat2
subs $cnt,$cnt,#2
aese $dat0,q9
aese $dat1,q9
aese $dat2,q9
vld1.32 {q9},[$key_],#16
aesmc $dat0,$dat0
aesmc $dat1,$dat1
aesmc $dat2,$dat2
b.gt .Loop3x_ctr32
aese $dat0,q8
aese $dat1,q8
aese $dat2,q8
mov $key_,$key
aesmc $tmp0,$dat0
vld1.8 {$in0},[$inp],#16
aesmc $tmp1,$dat1
aesmc $dat2,$dat2
vorr $dat0,$ivec,$ivec
aese $tmp0,q9
vld1.8 {$in1},[$inp],#16
aese $tmp1,q9
aese $dat2,q9
vorr $dat1,$ivec,$ivec
aesmc $tmp0,$tmp0
vld1.8 {$in2},[$inp],#16
aesmc $tmp1,$tmp1
aesmc $tmp2,$dat2
vorr $dat2,$ivec,$ivec
add $tctr0,$ctr,#1
aese $tmp0,q12
aese $tmp1,q12
aese $tmp2,q12
veor $in0,$in0,$rndlast
add $tctr1,$ctr,#2
aesmc $tmp0,$tmp0
aesmc $tmp1,$tmp1
aesmc $tmp2,$tmp2
veor $in1,$in1,$rndlast
add $ctr,$ctr,#3
aese $tmp0,q13
aese $tmp1,q13
aese $tmp2,q13
veor $in2,$in2,$rndlast
rev $tctr0,$tctr0
aesmc $tmp0,$tmp0
vld1.32 {q8},[$key_],#16 // re-pre-load rndkey[0]
aesmc $tmp1,$tmp1
aesmc $tmp2,$tmp2
vmov.32 ${dat0}[3], $tctr0
rev $tctr1,$tctr1
aese $tmp0,q14
aese $tmp1,q14
aese $tmp2,q14
vmov.32 ${dat1}[3], $tctr1
rev $tctr2,$ctr
aesmc $tmp0,$tmp0
aesmc $tmp1,$tmp1
aesmc $tmp2,$tmp2
vmov.32 ${dat2}[3], $tctr2
subs $len,$len,#3
aese $tmp0,q15
aese $tmp1,q15
aese $tmp2,q15
mov $cnt,$rounds
veor $in0,$in0,$tmp0
veor $in1,$in1,$tmp1
veor $in2,$in2,$tmp2
vld1.32 {q9},[$key_],#16 // re-pre-load rndkey[1]
vst1.8 {$in0},[$out],#16
vst1.8 {$in1},[$out],#16
vst1.8 {$in2},[$out],#16
b.hs .Loop3x_ctr32
adds $len,$len,#3
b.eq .Lctr32_done
cmp $len,#1
mov $step,#16
cclr $step,eq
.Lctr32_tail:
aese $dat0,q8
aese $dat1,q8
vld1.32 {q8},[$key_],#16
aesmc $dat0,$dat0
aesmc $dat1,$dat1
subs $cnt,$cnt,#2
aese $dat0,q9
aese $dat1,q9
vld1.32 {q9},[$key_],#16
aesmc $dat0,$dat0
aesmc $dat1,$dat1
b.gt .Lctr32_tail
aese $dat0,q8
aese $dat1,q8
aesmc $dat0,$dat0
aesmc $dat1,$dat1
aese $dat0,q9
aese $dat1,q9
aesmc $dat0,$dat0
aesmc $dat1,$dat1
vld1.8 {$in0},[$inp],$step
aese $dat0,q12
aese $dat1,q12
vld1.8 {$in1},[$inp]
aesmc $dat0,$dat0
aesmc $dat1,$dat1
aese $dat0,q13
aese $dat1,q13
aesmc $dat0,$dat0
aesmc $dat1,$dat1
aese $dat0,q14
aese $dat1,q14
veor $in0,$in0,$rndlast
aesmc $dat0,$dat0
aesmc $dat1,$dat1
veor $in1,$in1,$rndlast
aese $dat0,q15
aese $dat1,q15
cmp $len,#1
veor $in0,$in0,$dat0
veor $in1,$in1,$dat1
vst1.8 {$in0},[$out],#16
b.eq .Lctr32_done
vst1.8 {$in1},[$out]
.Lctr32_done:
___
$code.=<<___ if ($flavour !~ /64/);
vldmia sp!,{d8-d15}
ldmia sp!,{r4-r10,pc}
___
$code.=<<___ if ($flavour =~ /64/);
ldr x29,[sp],#16
ret
___
$code.=<<___;
.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks
___
}}}
$code.=<<___;
#endif
___
########################################
if ($flavour =~ /64/) { ######## 64-bit code
my %opcode = (
"aesd" => 0x4e285800, "aese" => 0x4e284800,
"aesimc"=> 0x4e287800, "aesmc" => 0x4e286800 );
local *unaes = sub {
my ($mnemonic,$arg)=@_;
$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o &&
sprintf ".inst\t0x%08x\t//%s %s",
$opcode{$mnemonic}|$1|($2<<5),
$mnemonic,$arg;
};
foreach(split("\n",$code)) {
s/\`([^\`]*)\`/eval($1)/geo;
s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo; # old->new registers
s/@\s/\/\//o; # old->new style commentary
#s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or
s/cclr\s+([wx])([^,]+),\s*([a-z]+)/csel $1$2,$1zr,$1$2,$3/o or
s/mov\.([a-z]+)\s+([wx][0-9]+),\s*([wx][0-9]+)/csel $2,$3,$2,$1/o or
s/vmov\.i8/movi/o or # fix up legacy mnemonics
s/vext\.8/ext/o or
s/vrev32\.8/rev32/o or
s/vtst\.8/cmtst/o or
s/vshr/ushr/o or
s/^(\s+)v/$1/o or # strip off v prefix
s/\bbx\s+lr\b/ret/o;
# fix up remainig legacy suffixes
s/\.[ui]?8//o;
m/\],#8/o and s/\.16b/\.8b/go;
s/\.[ui]?32//o and s/\.16b/\.4s/go;
s/\.[ui]?64//o and s/\.16b/\.2d/go;
s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o;
print $_,"\n";
}
} else { ######## 32-bit code
my %opcode = (
"aesd" => 0xf3b00340, "aese" => 0xf3b00300,
"aesimc"=> 0xf3b003c0, "aesmc" => 0xf3b00380 );
local *unaes = sub {
my ($mnemonic,$arg)=@_;
if ($arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)/o) {
my $word = $opcode{$mnemonic}|(($1&7)<<13)|(($1&8)<<19)
|(($2&7)<<1) |(($2&8)<<2);
# since ARMv7 instructions are always encoded little-endian.
# correct solution is to use .inst directive, but older
# assemblers don't implement it:-(
sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
$word&0xff,($word>>8)&0xff,
($word>>16)&0xff,($word>>24)&0xff,
$mnemonic,$arg;
}
};
sub unvtbl {
my $arg=shift;
$arg =~ m/q([0-9]+),\s*\{q([0-9]+)\},\s*q([0-9]+)/o &&
sprintf "vtbl.8 d%d,{q%d},d%d\n\t".
"vtbl.8 d%d,{q%d},d%d", 2*$1,$2,2*$3, 2*$1+1,$2,2*$3+1;
}
sub unvdup32 {
my $arg=shift;
$arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o &&
sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;
}
sub unvmov32 {
my $arg=shift;
$arg =~ m/q([0-9]+)\[([0-3])\],(.*)/o &&
sprintf "vmov.32 d%d[%d],%s",2*$1+($2>>1),$2&1,$3;
}
foreach(split("\n",$code)) {
s/\`([^\`]*)\`/eval($1)/geo;
s/\b[wx]([0-9]+)\b/r$1/go; # new->old registers
s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go; # new->old registers
s/\/\/\s?/@ /o; # new->old style commentary
# fix up remainig new-style suffixes
s/\{q([0-9]+)\},\s*\[(.+)\],#8/sprintf "{d%d},[$2]!",2*$1/eo or
s/\],#[0-9]+/]!/o;
s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or
s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or
s/vtbl\.8\s+(.*)/unvtbl($1)/geo or
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
s/vmov\.32\s+(.*)/unvmov32($1)/geo or
s/^(\s+)b\./$1b/o or
s/^(\s+)mov\./$1mov/o or
s/^(\s+)ret/$1bx\tlr/o;
print $_,"\n";
}
}
close STDOUT;

68
crypto/arm64cpuid.pl Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env perl
$flavour = shift;
$output = shift;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
$code.=<<___;
#include "arm_arch.h"
.text
.arch armv8-a+crypto
.align 5
.globl _armv7_neon_probe
.type _armv7_neon_probe,%function
_armv7_neon_probe:
orr v15.16b, v15.16b, v15.16b
ret
.size _armv7_neon_probe,.-_armv7_neon_probe
.globl _armv7_tick
.type _armv7_tick,%function
_armv7_tick:
#ifdef __APPLE__
mrs x0, CNTPCT_EL0
#else
mrs x0, CNTVCT_EL0
#endif
ret
.size _armv7_tick,.-_armv7_tick
.globl _armv8_aes_probe
.type _armv8_aes_probe,%function
_armv8_aes_probe:
aese v0.16b, v0.16b
ret
.size _armv8_aes_probe,.-_armv8_aes_probe
.globl _armv8_sha1_probe
.type _armv8_sha1_probe,%function
_armv8_sha1_probe:
sha1h s0, s0
ret
.size _armv8_sha1_probe,.-_armv8_sha1_probe
.globl _armv8_sha256_probe
.type _armv8_sha256_probe,%function
_armv8_sha256_probe:
sha256su0 v0.4s, v0.4s
ret
.size _armv8_sha256_probe,.-_armv8_sha256_probe
.globl _armv8_pmull_probe
.type _armv8_pmull_probe,%function
_armv8_pmull_probe:
pmull v0.1q, v0.1d, v0.1d
ret
.size _armv8_pmull_probe,.-_armv8_pmull_probe
___
print $code;
close STDOUT;

View File

@@ -10,13 +10,22 @@
# define __ARMEL__
# endif
# elif defined(__GNUC__)
# if defined(__aarch64__)
# define __ARM_ARCH__ 8
# if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
# define __ARMEB__
# else
# define __ARMEL__
# endif
/*
* Why doesn't gcc define __ARM_ARCH__? Instead it defines
* bunch of below macros. See all_architectires[] table in
* gcc/config/arm/arm.c. On a side note it defines
* __ARMEL__/__ARMEB__ for little-/big-endian.
*/
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
# elif defined(__ARM_ARCH_8A__)
# define __ARM_ARCH__ 8
# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH__ 7
@@ -42,10 +51,14 @@
#if !__ASSEMBLER__
extern unsigned int OPENSSL_armcap_P;
#endif
#define ARMV7_NEON (1<<0)
#define ARMV7_TICK (1<<1)
#endif
#define ARMV8_AES (1<<2)
#define ARMV8_SHA1 (1<<3)
#define ARMV8_SHA256 (1<<4)
#define ARMV8_PMULL (1<<5)
#endif
#endif

View File

@@ -20,6 +20,10 @@ static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
*/
void _armv7_neon_probe(void);
unsigned int _armv7_tick(void);
void _armv8_aes_probe(void);
void _armv8_sha1_probe(void);
void _armv8_sha256_probe(void);
void _armv8_pmull_probe(void);
unsigned int OPENSSL_rdtsc(void)
{
@@ -68,6 +72,28 @@ void OPENSSL_cpuid_setup(void)
{
_armv7_neon_probe();
OPENSSL_armcap_P |= ARMV7_NEON;
#ifdef __aarch64__
if (sigsetjmp(ill_jmp,1) == 0)
{
_armv8_pmull_probe();
OPENSSL_armcap_P |= ARMV8_PMULL|ARMV8_AES;
}
else if (sigsetjmp(ill_jmp,1) == 0)
{
_armv8_aes_probe();
OPENSSL_armcap_P |= ARMV8_AES;
}
if (sigsetjmp(ill_jmp,1) == 0)
{
_armv8_sha1_probe();
OPENSSL_armcap_P |= ARMV8_SHA1;
}
if (sigsetjmp(ill_jmp,1) == 0)
{
_armv8_sha256_probe();
OPENSSL_armcap_P |= ARMV8_SHA256;
}
#endif
}
if (sigsetjmp(ill_jmp,1) == 0)
{

210
crypto/armv4cpuid_ios.S Normal file
View File

@@ -0,0 +1,210 @@
#include "arm_arch.h"
.text
.code 32
.align 5
.globl _OPENSSL_atomic_add
_OPENSSL_atomic_add:
#if __ARM_ARCH__>=6
Ladd: ldrex r2,[r0]
add r3,r2,r1
strex r2,r3,[r0]
cmp r2,#0
bne Ladd
mov r0,r3
bx lr
#else
stmdb sp!,{r4,r5,r6,lr}
ldr r2,Lspinlock
adr r3,Lspinlock
mov r4,r0
mov r5,r1
add r6,r3,r2 @ &spinlock
b .+8
Lspin: bl sched_yield
mov r0,#-1
swp r0,r0,[r6]
cmp r0,#0
bne Lspin
ldr r2,[r4]
add r2,r2,r5
str r2,[r4]
str r0,[r6] @ release spinlock
ldmia sp!,{r4,r5,r6,lr}
tst lr,#1
moveq pc,lr
.word 0xe12fff1e @ bx lr
#endif
.globl _OPENSSL_cleanse
_OPENSSL_cleanse:
eor ip,ip,ip
cmp r1,#7
subhs r1,r1,#4
bhs Lot
cmp r1,#0
beq Lcleanse_done
Little:
strb ip,[r0],#1
subs r1,r1,#1
bhi Little
b Lcleanse_done
Lot: tst r0,#3
beq Laligned
strb ip,[r0],#1
sub r1,r1,#1
b Lot
Laligned:
str ip,[r0],#4
subs r1,r1,#4
bhs Laligned
adds r1,r1,#4
bne Little
Lcleanse_done:
#if __ARM_ARCH__>=5
bx lr
#else
tst lr,#1
moveq pc,lr
.word 0xe12fff1e @ bx lr
#endif
.align 5
.globl __armv7_neon_probe
__armv7_neon_probe:
vorr q0,q0,q0
bx lr
.globl __armv7_tick
__armv7_tick:
#ifdef __APPLE__
mrrc p15,0,r0,r1,c14 @ CNTPCT
#else
mrrc p15,1,r0,r1,c14 @ CNTVCT
#endif
bx lr
.globl __armv8_aes_probe
__armv8_aes_probe:
.byte 0x00,0x03,0xb0,0xf3 @ aese.8 q0,q0
bx lr
.globl __armv8_sha1_probe
__armv8_sha1_probe:
.byte 0x40,0x0c,0x00,0xf2 @ sha1c.32 q0,q0,q0
bx lr
.globl __armv8_sha256_probe
__armv8_sha256_probe:
.byte 0x40,0x0c,0x00,0xf3 @ sha256h.32 q0,q0,q0
bx lr
.globl __armv8_pmull_probe
__armv8_pmull_probe:
.byte 0x00,0x0e,0xa0,0xf2 @ vmull.p64 q0,d0,d0
bx lr
.globl _OPENSSL_wipe_cpu
_OPENSSL_wipe_cpu:
ldr r0,LOPENSSL_armcap
adr r1,LOPENSSL_armcap
ldr r0,[r1,r0]
#ifdef __APPLE__
ldr r0,[r0]
#endif
eor r2,r2,r2
eor r3,r3,r3
eor ip,ip,ip
tst r0,#1
beq Lwipe_done
veor q0, q0, q0
veor q1, q1, q1
veor q2, q2, q2
veor q3, q3, q3
veor q8, q8, q8
veor q9, q9, q9
veor q10, q10, q10
veor q11, q11, q11
veor q12, q12, q12
veor q13, q13, q13
veor q14, q14, q14
veor q15, q15, q15
Lwipe_done:
mov r0,sp
#if __ARM_ARCH__>=5
bx lr
#else
tst lr,#1
moveq pc,lr
.word 0xe12fff1e @ bx lr
#endif
.globl _OPENSSL_instrument_bus
_OPENSSL_instrument_bus:
eor r0,r0,r0
#if __ARM_ARCH__>=5
bx lr
#else
tst lr,#1
moveq pc,lr
.word 0xe12fff1e @ bx lr
#endif
.globl _OPENSSL_instrument_bus2
_OPENSSL_instrument_bus2:
eor r0,r0,r0
#if __ARM_ARCH__>=5
bx lr
#else
tst lr,#1
moveq pc,lr
.word 0xe12fff1e @ bx lr
#endif
.align 5
LOPENSSL_armcap:
.word OPENSSL_armcap_P-.
#if __ARM_ARCH__>=6
.align 5
#else
Lspinlock:
.word atomic_add_spinlock-Lspinlock
.align 5
.data
.align 2
atomic_add_spinlock:
.word
#endif
.comm _OPENSSL_armcap_P,4
.non_lazy_symbol_pointer
OPENSSL_armcap_P:
.indirect_symbol _OPENSSL_armcap_P
.long 0
.private_extern _OPENSSL_armcap_P

View File

@@ -21,8 +21,20 @@
# runs in even less cycles, ~30, improvement is measurable only on
# longer keys. One has to optimize code elsewhere to get NEON glow...
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; }
sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; }
@@ -170,11 +182,18 @@ bn_GF2m_mul_2x2:
#if __ARM_ARCH__>=7
ldr r12,.LOPENSSL_armcap
.Lpic: ldr r12,[pc,r12]
#ifdef __APPLE__
ldr r12,[r12]
#endif
tst r12,#1
beq .Lialu
veor $A1,$A1
#ifdef __APPLE__
vmov $B1,r3,r3 @ two copies of b1
#else
vmov.32 $B1,r3,r3 @ two copies of b1
#endif
vmov.32 ${A1}[0],r1 @ a1
veor $A0,$A0

View File

@@ -23,8 +23,20 @@
# than 1/2KB. Windows CE port would be trivial, as it's exclusively
# about decorations, ABI and instruction syntax are identical.
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
$num="r0"; # starts as num argument, but holds &tp[num-1]
$ap="r1";

View File

@@ -297,7 +297,7 @@ void OPENSSL_showfatal (const char *fmta,...)
DWORD out;
va_start (ap,fmta);
len=_vsnprintf((char *)buf,sizeof(buf),fmt,ap);
len=_vsnprintf((char *)buf,sizeof(buf),fmta,ap);
WriteFile(h,buf,len<0?sizeof(buf):(DWORD)len,&out,NULL);
va_end (ap);
return;

View File

@@ -471,6 +471,35 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
{ return &aes_##keylen##_##mode; }
#endif
#if defined(OPENSSL_CPUID_OBJ) && defined(__aarch64__)
#include "arm_arch.h"
#if __ARM_ARCH__>=7
# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
# define HWAES_encrypt aes_v8_encrypt
# define HWAES_decrypt aes_v8_decrypt
# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
#endif
#endif
#if defined(HWAES_CAPABLE)
int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
void HWAES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void HWAES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key);
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, const int enc);
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t len, const AES_KEY *key, const unsigned char ivec[16]);
#endif
#define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
@@ -489,6 +518,19 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
mode = ctx->cipher->flags & EVP_CIPH_MODE;
if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
&& !enc)
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE)
{
ret = HWAES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
dat->block = (block128_f)HWAES_decrypt;
dat->stream.cbc = NULL;
#ifdef HWAES_cbc_encrypt
if (mode==EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
#endif
}
else
#endif
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
{
@@ -517,6 +559,26 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
NULL;
}
else
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE)
{
ret = HWAES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
dat->block = (block128_f)HWAES_encrypt;
dat->stream.cbc = NULL;
#ifdef HWAES_cbc_encrypt
if (mode==EVP_CIPH_CBC_MODE)
dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
else
#endif
#ifdef HWAES_ctr32_encrypt_blocks
if (mode==EVP_CIPH_CTR_MODE)
dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
else
#endif
(void)0; /* terminate potentially open 'else' */
}
else
#endif
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
{
@@ -795,6 +857,28 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
/* Extra padding: tag appended to record */
return EVP_GCM_TLS_TAG_LEN;
case EVP_CTRL_COPY:
{
EVP_CIPHER_CTX *out = ptr;
EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
if (gctx->gcm.key)
{
if (gctx->gcm.key != &gctx->ks)
return 0;
gctx_out->gcm.key = &gctx_out->ks;
}
if (gctx->iv == c->iv)
gctx_out->iv = out->iv;
else
{
gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
if (!gctx_out->iv)
return 0;
memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
}
return 1;
}
default:
return -1;
@@ -809,6 +893,21 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
return 1;
if (key)
{ do {
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE)
{
HWAES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
(block128_f)HWAES_encrypt);
#ifdef HWAES_ctr32_encrypt_blocks
gctx->ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
#else
gctx->ctr = NULL;
#endif
break;
}
else
#endif
#ifdef BSAES_CAPABLE
if (BSAES_CAPABLE)
{
@@ -1016,7 +1115,8 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
#define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
| EVP_CIPH_CUSTOM_COPY)
BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,
EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
@@ -1028,7 +1128,25 @@ BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,
static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
EVP_AES_XTS_CTX *xctx = c->cipher_data;
if (type != EVP_CTRL_INIT)
if (type == EVP_CTRL_COPY)
{
EVP_CIPHER_CTX *out = ptr;
EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
if (xctx->xts.key1)
{
if (xctx->xts.key1 != &xctx->ks1)
return 0;
xctx_out->xts.key1 = &xctx_out->ks1;
}
if (xctx->xts.key2)
{
if (xctx->xts.key2 != &xctx->ks2)
return 0;
xctx_out->xts.key2 = &xctx_out->ks2;
}
return 1;
}
else if (type != EVP_CTRL_INIT)
return -1;
/* key1 and key2 are used as an indicator both key and IV are set */
xctx->xts.key1 = NULL;
@@ -1047,6 +1165,29 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
{
xctx->stream = NULL;
/* key_len is two AES keys */
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE)
{
if (enc)
{
HWAES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
xctx->xts.block1 = (block128_f)HWAES_encrypt;
}
else
{
HWAES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
xctx->xts.block1 = (block128_f)HWAES_decrypt;
}
HWAES_set_encrypt_key(key + ctx->key_len/2,
ctx->key_len * 4, &xctx->ks2);
xctx->xts.block2 = (block128_f)HWAES_encrypt;
xctx->xts.key1 = &xctx->ks1;
break;
}
else
#endif
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE)
{
@@ -1125,7 +1266,8 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
#define aes_xts_cleanup NULL
#define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
| EVP_CIPH_CUSTOM_COPY)
BLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
BLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
@@ -1175,6 +1317,19 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
cctx->len_set = 0;
return 1;
case EVP_CTRL_COPY:
{
EVP_CIPHER_CTX *out = ptr;
EVP_AES_CCM_CTX *cctx_out = out->cipher_data;
if (cctx->ccm.key)
{
if (cctx->ccm.key != &cctx->ks)
return 0;
cctx_out->ccm.key = &cctx_out->ks;
}
return 1;
}
default:
return -1;
@@ -1189,6 +1344,19 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
return 1;
if (key) do
{
#ifdef HWAES_CAPABLE
if (HWAES_CAPABLE)
{
HWAES_set_encrypt_key(key,ctx->key_len*8,&cctx->ks);
CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
&cctx->ks, (block128_f)HWAES_encrypt);
cctx->str = NULL;
cctx->key_set = 1;
break;
}
else
#endif
#ifdef VPAES_CAPABLE
if (VPAES_CAPABLE)
{

View File

@@ -56,11 +56,14 @@ ghash-alpha.s: asm/ghash-alpha.pl
$(PERL) $< | $(CC) -E - | tee $@ > /dev/null
ghash-parisc.s: asm/ghash-parisc.pl
$(PERL) asm/ghash-parisc.pl $(PERLASM_SCHEME) $@
ghashv8-armx.S: asm/ghashv8-armx.pl
$(PERL) asm/ghashv8-armx.pl $(PERLASM_SCHEME) $@
# GNU make "catch all"
ghash-%.S: asm/ghash-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
ghash-armv4.o: ghash-armv4.S
ghashv8-armx.o: ghashv8-armx.S
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

View File

@@ -57,8 +57,20 @@
# *native* byte order on current platform. See gcm128.c for working
# example...
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
$Xi="r0"; # argument block
$Htbl="r1";
@@ -112,6 +124,11 @@ $code=<<___;
.text
.code 32
#ifdef __APPLE__
#define ldrplb ldrbpl
#define ldrneb ldrbne
#endif
.type rem_4bit,%object
.align 5
rem_4bit:
@@ -326,9 +343,9 @@ $code.=<<___;
.align 4
gcm_gmult_neon:
sub $Htbl,#16 @ point at H in GCM128_CTX
vld1.64 `&Dhi("$IN")`,[$Xi,:64]!@ load Xi
vld1.64 `&Dhi("$IN")`,[$Xi]! @ load Xi
vmov.i32 $mod,#0xe1 @ our irreducible polynomial
vld1.64 `&Dlo("$IN")`,[$Xi,:64]!
vld1.64 `&Dlo("$IN")`,[$Xi]!
vshr.u64 $mod,#32
vldmia $Htbl,{$Hhi-$Hlo} @ load H
veor $zero,$zero
@@ -349,9 +366,9 @@ gcm_gmult_neon:
.type gcm_ghash_neon,%function
.align 4
gcm_ghash_neon:
vld1.64 `&Dhi("$Z")`,[$Xi,:64]! @ load Xi
vld1.64 `&Dhi("$Z")`,[$Xi]! @ load Xi
vmov.i32 $mod,#0xe1 @ our irreducible polynomial
vld1.64 `&Dlo("$Z")`,[$Xi,:64]!
vld1.64 `&Dlo("$Z")`,[$Xi]!
vshr.u64 $mod,#32
vldmia $Xi,{$Hhi-$Hlo} @ load H
veor $zero,$zero
@@ -410,8 +427,8 @@ gcm_ghash_neon:
vrev64.8 $Z,$Z
#endif
sub $Xi,#16
vst1.64 `&Dhi("$Z")`,[$Xi,:64]! @ write out Xi
vst1.64 `&Dlo("$Z")`,[$Xi,:64]
vst1.64 `&Dhi("$Z")`,[$Xi]! @ write out Xi
vst1.64 `&Dlo("$Z")`,[$Xi]
bx lr
.size gcm_ghash_neon,.-gcm_ghash_neon

View File

@@ -0,0 +1,376 @@
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
#
# GHASH for ARMv8 Crypto Extension, 64-bit polynomial multiplication.
#
# June 2014
#
# Initial version was developed in tight cooperation with Ard
# Biesheuvel <ard.biesheuvel@linaro.org> from bits-n-pieces from
# other assembly modules. Just like aesv8-armx.pl this module
# supports both AArch32 and AArch64 execution modes.
#
# July 2014
#
# Implement 2x aggregated reduction [see ghash-x86.pl for background
# information].
#
# Current performance in cycles per processed byte:
#
# PMULL[2] 32-bit NEON(*)
# Apple A7 0.92 5.62
# Cortex-A53 1.01 8.39
# Cortex-A57 1.17 7.61
#
# (*) presented for reference/comparison purposes;
$flavour = shift;
$output = shift;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
$Xi="x0"; # argument block
$Htbl="x1";
$inp="x2";
$len="x3";
$inc="x12";
{
my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14));
$code=<<___;
#include "arm_arch.h"
.text
___
$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
$code.=".fpu neon\n.code 32\n" if ($flavour !~ /64/);
$code.=<<___;
.global gcm_init_v8
.type gcm_init_v8,%function
.align 4
gcm_init_v8:
vld1.64 {$t1},[x1] @ load H
vmov.i8 $xC2,#0xe1
vshl.i64 $xC2,$xC2,#57 @ 0xc2.0
vext.8 $IN,$t1,$t1,#8
vshr.u64 $t2,$xC2,#63
vdup.32 $t1,${t1}[1]
vext.8 $t0,$t2,$xC2,#8 @ t0=0xc2....01
vshr.u64 $t2,$IN,#63
vshr.s32 $t1,$t1,#31 @ broadcast carry bit
vand $t2,$t2,$t0
vshl.i64 $IN,$IN,#1
vext.8 $t2,$t2,$t2,#8
vand $t0,$t0,$t1
vorr $IN,$IN,$t2 @ H<<<=1
veor $H,$IN,$t0 @ twisted H
vst1.64 {$H},[x0],#16
@ calculate H^2
vext.8 $t0,$H,$H,#8 @ Karatsuba pre-processing
vpmull.p64 $Xl,$H,$H
veor $t0,$t0,$H
vpmull2.p64 $Xh,$H,$H
vpmull.p64 $Xm,$t0,$t0
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
veor $Xm,$Xm,$t1
veor $Xm,$Xm,$t2
vpmull.p64 $t2,$Xl,$xC2 @ 1st phase
vmov $Xh#lo,$Xm#hi @ Xh|Xm - 256-bit result
vmov $Xm#hi,$Xl#lo @ Xm is rotated Xl
veor $Xl,$Xm,$t2
vext.8 $t2,$Xl,$Xl,#8 @ 2nd phase
vpmull.p64 $Xl,$Xl,$xC2
veor $t2,$t2,$Xh
veor $H2,$Xl,$t2
vext.8 $t1,$H2,$H2,#8 @ Karatsuba pre-processing
veor $t1,$t1,$H2
vext.8 $Hhl,$t0,$t1,#8 @ pack Karatsuba pre-processed
vst1.64 {$Hhl-$H2},[x0]
ret
.size gcm_init_v8,.-gcm_init_v8
.global gcm_gmult_v8
.type gcm_gmult_v8,%function
.align 4
gcm_gmult_v8:
vld1.64 {$t1},[$Xi] @ load Xi
vmov.i8 $xC2,#0xe1
vld1.64 {$H-$Hhl},[$Htbl] @ load twisted H, ...
vshl.u64 $xC2,$xC2,#57
#ifndef __ARMEB__
vrev64.8 $t1,$t1
#endif
vext.8 $IN,$t1,$t1,#8
vpmull.p64 $Xl,$H,$IN @ H.lo<6C>Xi.lo
veor $t1,$t1,$IN @ Karatsuba pre-processing
vpmull2.p64 $Xh,$H,$IN @ H.hi<68>Xi.hi
vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)<29>(Xi.lo+Xi.hi)
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
veor $Xm,$Xm,$t1
veor $Xm,$Xm,$t2
vpmull.p64 $t2,$Xl,$xC2 @ 1st phase
vmov $Xh#lo,$Xm#hi @ Xh|Xm - 256-bit result
vmov $Xm#hi,$Xl#lo @ Xm is rotated Xl
veor $Xl,$Xm,$t2
vext.8 $t2,$Xl,$Xl,#8 @ 2nd phase
vpmull.p64 $Xl,$Xl,$xC2
veor $t2,$t2,$Xh
veor $Xl,$Xl,$t2
#ifndef __ARMEB__
vrev64.8 $Xl,$Xl
#endif
vext.8 $Xl,$Xl,$Xl,#8
vst1.64 {$Xl},[$Xi] @ write out Xi
ret
.size gcm_gmult_v8,.-gcm_gmult_v8
.global gcm_ghash_v8
.type gcm_ghash_v8,%function
.align 4
gcm_ghash_v8:
___
$code.=<<___ if ($flavour !~ /64/);
vstmdb sp!,{d8-d15}
___
$code.=<<___;
vld1.64 {$Xl},[$Xi] @ load [rotated] Xi
subs $len,$len,#32
vmov.i8 $xC2,#0xe1
mov $inc,#16
vld1.64 {$H-$Hhl},[$Htbl],#32 @ load twisted H, ..., H^2
vld1.64 {$H2},[$Htbl]
cclr $inc,eq
vext.8 $Xl,$Xl,$Xl,#8
vld1.64 {$t0},[$inp],#16 @ load [rotated] I[0]
vshl.u64 $xC2,$xC2,#57 @ 0xc2.0
#ifndef __ARMEB__
vrev64.8 $t0,$t0
vrev64.8 $Xl,$Xl
#endif
vext.8 $IN,$t0,$t0,#8
b.lo .Lodd_tail_v8
___
{ my ($Xln,$Xmn,$Xhn,$In) = map("q$_",(4..7));
#######
# Xi+2 =[H*(Ii+1 + Xi+1)] mod P =
# [(H*Ii+1) + (H*Xi+1)] mod P =
# [(H*Ii+1) + H^2*(Ii+Xi)] mod P
#
$code.=<<___;
vld1.64 {$t1},[$inp],$inc @ load [rotated] I[1]
#ifndef __ARMEB__
vrev64.8 $t1,$t1
#endif
vext.8 $In,$t1,$t1,#8
veor $IN,$IN,$Xl @ I[i]^=Xi
vpmull.p64 $Xln,$H,$In @ H<>Ii+1
veor $t1,$t1,$In @ Karatsuba pre-processing
vpmull2.p64 $Xhn,$H,$In
b .Loop_mod2x_v8
.align 4
.Loop_mod2x_v8:
vext.8 $t2,$IN,$IN,#8
subs $len,$len,#32
vpmull.p64 $Xl,$H2,$IN @ H^2.lo<6C>Xi.lo
cclr $inc,lo
vpmull.p64 $Xmn,$Hhl,$t1
veor $t2,$t2,$IN @ Karatsuba pre-processing
vpmull2.p64 $Xh,$H2,$IN @ H^2.hi<68>Xi.hi
veor $Xl,$Xl,$Xln @ accumulate
vpmull2.p64 $Xm,$Hhl,$t2 @ (H^2.lo+H^2.hi)<29>(Xi.lo+Xi.hi)
vld1.64 {$t0},[$inp],$inc @ load [rotated] I[i]
veor $Xh,$Xh,$Xhn
cclr $inc,eq
veor $Xm,$Xm,$Xmn
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
veor $Xm,$Xm,$t1
vld1.64 {$t1},[$inp],$inc @ load [rotated] I[i+1]
#ifndef __ARMEB__
vrev64.8 $t0,$t0
#endif
veor $Xm,$Xm,$t2
vpmull.p64 $t2,$Xl,$xC2 @ 1st phase
#ifndef __ARMEB__
vrev64.8 $t1,$t1
#endif
vmov $Xh#lo,$Xm#hi @ Xh|Xm - 256-bit result
vmov $Xm#hi,$Xl#lo @ Xm is rotated Xl
vext.8 $In,$t1,$t1,#8
vext.8 $IN,$t0,$t0,#8
veor $Xl,$Xm,$t2
vpmull.p64 $Xln,$H,$In @ H<>Ii+1
veor $IN,$IN,$Xh @ accumulate $IN early
vext.8 $t2,$Xl,$Xl,#8 @ 2nd phase
vpmull.p64 $Xl,$Xl,$xC2
veor $IN,$IN,$t2
veor $t1,$t1,$In @ Karatsuba pre-processing
veor $IN,$IN,$Xl
vpmull2.p64 $Xhn,$H,$In
b.hs .Loop_mod2x_v8
veor $Xh,$Xh,$t2
vext.8 $IN,$t0,$t0,#8 @ re-construct $IN
adds $len,$len,#32
veor $Xl,$Xl,$Xh @ re-construct $Xl
b.eq .Ldone_v8
___
}
$code.=<<___;
.Lodd_tail_v8:
vext.8 $t2,$Xl,$Xl,#8
veor $IN,$IN,$Xl @ inp^=Xi
veor $t1,$t0,$t2 @ $t1 is rotated inp^Xi
vpmull.p64 $Xl,$H,$IN @ H.lo<6C>Xi.lo
veor $t1,$t1,$IN @ Karatsuba pre-processing
vpmull2.p64 $Xh,$H,$IN @ H.hi<68>Xi.hi
vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)<29>(Xi.lo+Xi.hi)
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
veor $Xm,$Xm,$t1
veor $Xm,$Xm,$t2
vpmull.p64 $t2,$Xl,$xC2 @ 1st phase
vmov $Xh#lo,$Xm#hi @ Xh|Xm - 256-bit result
vmov $Xm#hi,$Xl#lo @ Xm is rotated Xl
veor $Xl,$Xm,$t2
vext.8 $t2,$Xl,$Xl,#8 @ 2nd phase
vpmull.p64 $Xl,$Xl,$xC2
veor $t2,$t2,$Xh
veor $Xl,$Xl,$t2
.Ldone_v8:
#ifndef __ARMEB__
vrev64.8 $Xl,$Xl
#endif
vext.8 $Xl,$Xl,$Xl,#8
vst1.64 {$Xl},[$Xi] @ write out Xi
___
$code.=<<___ if ($flavour !~ /64/);
vldmia sp!,{d8-d15}
___
$code.=<<___;
ret
.size gcm_ghash_v8,.-gcm_ghash_v8
___
}
$code.=<<___;
.asciz "GHASH for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
___
if ($flavour =~ /64/) { ######## 64-bit code
sub unvmov {
my $arg=shift;
$arg =~ m/q([0-9]+)#(lo|hi),\s*q([0-9]+)#(lo|hi)/o &&
sprintf "ins v%d.d[%d],v%d.d[%d]",$1,($2 eq "lo")?0:1,$3,($4 eq "lo")?0:1;
}
foreach(split("\n",$code)) {
s/cclr\s+([wx])([^,]+),\s*([a-z]+)/csel $1$2,$1zr,$1$2,$3/o or
s/vmov\.i8/movi/o or # fix up legacy mnemonics
s/vmov\s+(.*)/unvmov($1)/geo or
s/vext\.8/ext/o or
s/vshr\.s/sshr\.s/o or
s/vshr/ushr/o or
s/^(\s+)v/$1/o or # strip off v prefix
s/\bbx\s+lr\b/ret/o;
s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo; # old->new registers
s/@\s/\/\//o; # old->new style commentary
# fix up remainig legacy suffixes
s/\.[ui]?8(\s)/$1/o;
s/\.[uis]?32//o and s/\.16b/\.4s/go;
m/\.p64/o and s/\.16b/\.1q/o; # 1st pmull argument
m/l\.p64/o and s/\.16b/\.1d/go; # 2nd and 3rd pmull arguments
s/\.[uisp]?64//o and s/\.16b/\.2d/go;
s/\.[42]([sd])\[([0-3])\]/\.$1\[$2\]/o;
print $_,"\n";
}
} else { ######## 32-bit code
sub unvdup32 {
my $arg=shift;
$arg =~ m/q([0-9]+),\s*q([0-9]+)\[([0-3])\]/o &&
sprintf "vdup.32 q%d,d%d[%d]",$1,2*$2+($3>>1),$3&1;
}
sub unvpmullp64 {
my ($mnemonic,$arg)=@_;
if ($arg =~ m/q([0-9]+),\s*q([0-9]+),\s*q([0-9]+)/o) {
my $word = 0xf2a00e00|(($1&7)<<13)|(($1&8)<<19)
|(($2&7)<<17)|(($2&8)<<4)
|(($3&7)<<1) |(($3&8)<<2);
$word |= 0x00010001 if ($mnemonic =~ "2");
# since ARMv7 instructions are always encoded little-endian.
# correct solution is to use .inst directive, but older
# assemblers don't implement it:-(
sprintf ".byte\t0x%02x,0x%02x,0x%02x,0x%02x\t@ %s %s",
$word&0xff,($word>>8)&0xff,
($word>>16)&0xff,($word>>24)&0xff,
$mnemonic,$arg;
}
}
foreach(split("\n",$code)) {
s/\b[wx]([0-9]+)\b/r$1/go; # new->old registers
s/\bv([0-9])\.[12468]+[bsd]\b/q$1/go; # new->old registers
s/\/\/\s?/@ /o; # new->old style commentary
# fix up remainig new-style suffixes
s/\],#[0-9]+/]!/o;
s/cclr\s+([^,]+),\s*([a-z]+)/mov$2 $1,#0/o or
s/vdup\.32\s+(.*)/unvdup32($1)/geo or
s/v?(pmull2?)\.p64\s+(.*)/unvpmullp64($1,$2)/geo or
s/\bq([0-9]+)#(lo|hi)/sprintf "d%d",2*$1+($2 eq "hi")/geo or
s/^(\s+)b\./$1b/o or
s/^(\s+)ret/$1bx\tlr/o;
print $_,"\n";
}
}
close STDOUT; # enforce flush

View File

@@ -645,7 +645,7 @@ static void gcm_gmult_1bit(u64 Xi[2],const u64 H[2])
#endif
#if TABLE_BITS==4 && defined(GHASH_ASM)
#if TABLE_BITS==4 && (defined(GHASH_ASM) || defined(OPENSSL_CPUID_OBJ))
# if !defined(I386_ONLY) && \
(defined(__i386) || defined(__i386__) || \
defined(__x86_64) || defined(__x86_64__) || \
@@ -666,13 +666,22 @@ void gcm_ghash_4bit_mmx(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len
void gcm_gmult_4bit_x86(u64 Xi[2],const u128 Htable[16]);
void gcm_ghash_4bit_x86(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
# endif
# elif defined(__arm__) || defined(__arm)
# elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
# include "arm_arch.h"
# if __ARM_ARCH__>=7
# define GHASH_ASM_ARM
# define GCM_FUNCREF_4BIT
# if defined(__aarch64__)
# define PMULL_CAPABLE (OPENSSL_armcap_P & ARMV8_PMULL)
# endif
# if defined(__arm__) || defined(__arm)
# define NEON_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
# endif
void gcm_gmult_neon(u64 Xi[2],const u128 Htable[16]);
void gcm_ghash_neon(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
void gcm_init_v8(u128 Htable[16],const u64 Xi[2]);
void gcm_gmult_v8(u64 Xi[2],const u128 Htable[16]);
void gcm_ghash_v8(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len);
# endif
# elif defined(_TMS320C6400_PLUS)
# define GHASH_ASM_C64Xplus
@@ -740,10 +749,20 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
ctx->ghash = gcm_ghash_4bit;
# endif
# elif defined(GHASH_ASM_ARM)
if (OPENSSL_armcap_P & ARMV7_NEON) {
# ifdef PMULL_CAPABLE
if (PMULL_CAPABLE) {
gcm_init_v8(ctx->Htable,ctx->H.u);
ctx->gmult = gcm_gmult_v8;
ctx->ghash = gcm_ghash_v8;
} else
# endif
# ifdef NEON_CAPABLE
if (NEON_CAPABLE) {
ctx->gmult = gcm_gmult_neon;
ctx->ghash = gcm_ghash_neon;
} else {
} else
# endif
{
gcm_init_4bit(ctx->Htable,ctx->H.u);
ctx->gmult = gcm_gmult_4bit;
ctx->ghash = gcm_ghash_4bit;

View File

@@ -29,10 +29,7 @@ typedef unsigned char u8;
#if defined(__i386) || defined(__i386__) || \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
defined(__s390__) || defined(__s390x__) || \
( (defined(__arm__) || defined(__arm)) && \
(defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)) )
defined(__s390__) || defined(__s390x__)
# undef STRICT_ALIGNMENT
#endif

165
crypto/perlasm/arm-xlate.pl Normal file
View File

@@ -0,0 +1,165 @@
#!/usr/bin/env perl
# ARM assembler distiller by <appro>.
my $flavour = shift;
my $output = shift;
open STDOUT,">$output" || die "can't open $output: $!";
$flavour = "linux32" if (!$flavour or $flavour eq "void");
my %GLOBALS;
my $dotinlocallabels=($flavour=~/linux/)?1:0;
################################################################
# directives which need special treatment on different platforms
################################################################
my $arch = sub {
if ($flavour =~ /linux/) { ".arch\t".join(',',@_); }
else { ""; }
};
my $fpu = sub {
if ($flavour =~ /linux/) { ".fpu\t".join(',',@_); }
else { ""; }
};
my $hidden = sub {
if ($flavour =~ /ios/) { ".private_extern\t".join(',',@_); }
else { ".hidden\t".join(',',@_); }
};
my $comm = sub {
my @args = split(/,\s*/,shift);
my $name = @args[0];
my $global = \$GLOBALS{$name};
my $ret;
if ($flavour =~ /ios32/) {
$ret = ".comm\t_$name,@args[1]\n";
$ret .= ".non_lazy_symbol_pointer\n";
$ret .= "$name:\n";
$ret .= ".indirect_symbol\t_$name\n";
$ret .= ".long\t0";
$name = "_$name";
} else { $ret = ".comm\t".join(',',@args); }
$$global = $name;
$ret;
};
my $globl = sub {
my $name = shift;
my $global = \$GLOBALS{$name};
my $ret;
SWITCH: for ($flavour) {
/ios/ && do { $name = "_$name";
last;
};
}
$ret = ".globl $name" if (!$ret);
$$global = $name;
$ret;
};
my $global = $globl;
my $extern = sub {
&$globl(@_);
return; # return nothing
};
my $type = sub {
if ($flavour =~ /linux/) { ".type\t".join(',',@_); }
else { ""; }
};
my $size = sub {
if ($flavour =~ /linux/) { ".size\t".join(',',@_); }
else { ""; }
};
my $inst = sub {
if ($flavour =~ /linux/) { ".inst\t".join(',',@_); }
else { ".long\t".join(',',@_); }
};
my $asciz = sub {
my $line = join(",",@_);
if ($line =~ /^"(.*)"$/)
{ ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; }
else
{ ""; }
};
sub range {
my ($r,$sfx,$start,$end) = @_;
join(",",map("$r$_$sfx",($start..$end)));
}
sub expand_line {
my $line = shift;
my @ret = ();
pos($line)=0;
while ($line =~ m/\G[^@\/\{\"]*/g) {
if ($line =~ m/\G(@|\/\/|$)/gc) {
last;
}
elsif ($line =~ m/\G\{/gc) {
my $saved_pos = pos($line);
$line =~ s/\G([rdqv])([0-9]+)([^\-]*)\-\1([0-9]+)\3/range($1,$3,$2,$4)/e;
pos($line) = $saved_pos;
$line =~ m/\G[^\}]*\}/g;
}
elsif ($line =~ m/\G\"/gc) {
$line =~ m/\G[^\"]*\"/g;
}
}
$line =~ s/\b(\w+)/$GLOBALS{$1} or $1/ge;
return $line;
}
while($line=<>) {
if ($line =~ m/^\s*(#|@|\/\/)/) { print $line; next; }
$line =~ s|/\*.*\*/||; # get rid of C-style comments...
$line =~ s|^\s+||; # ... and skip white spaces in beginning...
$line =~ s|\s+$||; # ... and at the end
{
$line =~ s|[\b\.]L(\w{2,})|L$1|g; # common denominator for Locallabel
$line =~ s|\bL(\w{2,})|\.L$1|g if ($dotinlocallabels);
}
{
$line =~ s|(^[\.\w]+)\:\s*||;
my $label = $1;
if ($label) {
printf "%s:",($GLOBALS{$label} or $label);
}
}
if ($line !~ m/^[#@]/) {
$line =~ s|^\s*(\.?)(\S+)\s*||;
my $c = $1; $c = "\t" if ($c eq "");
my $mnemonic = $2;
my $opcode;
if ($mnemonic =~ m/([^\.]+)\.([^\.]+)/) {
$opcode = eval("\$$1_$2");
} else {
$opcode = eval("\$$mnemonic");
}
my $arg=expand_line($line);
if (ref($opcode) eq 'CODE') {
$line = &$opcode($arg);
} elsif ($mnemonic) {
$line = $c.$mnemonic;
$line.= "\t$arg" if ($arg);
}
}
print $line if ($line);
print "\n";
}
close STDOUT;

View File

@@ -494,7 +494,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
if (padding == RSA_X931_PADDING)
{
BN_sub(f, rsa->n, ret);
if (BN_cmp(ret, f))
if (BN_cmp(ret, f) > 0)
res = f;
else
res = ret;

View File

@@ -90,6 +90,9 @@ sha512-%.S: asm/sha512-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@
sha1-armv4-large.o: sha1-armv4-large.S
sha256-armv4.o: sha256-armv4.S
sha512-armv4.o: sha512-armv4.S
sha1-armv8.o: sha1-armv8.S
sha256-armv8.o: sha256-armv8.S
sha512-armv8.o: sha512-armv8.S
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

View File

@@ -52,8 +52,20 @@
# Profiler-assisted and platform-specific optimization resulted in 10%
# improvement on Cortex A8 core and 12.2 cycles per byte.
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
$ctx="r0";
$inp="r1";

View File

@@ -0,0 +1,343 @@
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
#
# SHA1 for ARMv8.
#
# Performance in cycles per processed byte and improvement coefficient
# over code generated with "default" compiler:
#
# hardware-assisted software(*)
# Apple A7 2.31 4.13 (+14%)
# Cortex-A53 2.19 8.73 (+108%)
# Cortex-A57 2.35 7.88 (+74%)
#
# (*) Software results are presented mostly for reference purposes.
$flavour = shift;
$output = shift;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
($ctx,$inp,$num)=("x0","x1","x2");
@Xw=map("w$_",(3..17,19));
@Xx=map("x$_",(3..17,19));
@V=($A,$B,$C,$D,$E)=map("w$_",(20..24));
($t0,$t1,$t2,$K)=map("w$_",(25..28));
sub BODY_00_19 {
my ($i,$a,$b,$c,$d,$e)=@_;
my $j=($i+2)&15;
$code.=<<___ if ($i<15 && !($i&1));
lsr @Xx[$i+1],@Xx[$i],#32
___
$code.=<<___ if ($i<14 && !($i&1));
ldr @Xx[$i+2],[$inp,#`($i+2)*4-64`]
___
$code.=<<___ if ($i<14 && ($i&1));
#ifdef __ARMEB__
ror @Xx[$i+1],@Xx[$i+1],#32
#else
rev32 @Xx[$i+1],@Xx[$i+1]
#endif
___
$code.=<<___ if ($i<14);
bic $t0,$d,$b
and $t1,$c,$b
ror $t2,$a,#27
add $d,$d,$K // future e+=K
orr $t0,$t0,$t1
add $e,$e,$t2 // e+=rot(a,5)
ror $b,$b,#2
add $d,$d,@Xw[($i+1)&15] // future e+=X[i]
add $e,$e,$t0 // e+=F(b,c,d)
___
$code.=<<___ if ($i==19);
movz $K,#0xeba1
movk $K,#0x6ed9,lsl#16
___
$code.=<<___ if ($i>=14);
eor @Xw[$j],@Xw[$j],@Xw[($j+2)&15]
bic $t0,$d,$b
and $t1,$c,$b
ror $t2,$a,#27
eor @Xw[$j],@Xw[$j],@Xw[($j+8)&15]
add $d,$d,$K // future e+=K
orr $t0,$t0,$t1
add $e,$e,$t2 // e+=rot(a,5)
eor @Xw[$j],@Xw[$j],@Xw[($j+13)&15]
ror $b,$b,#2
add $d,$d,@Xw[($i+1)&15] // future e+=X[i]
add $e,$e,$t0 // e+=F(b,c,d)
ror @Xw[$j],@Xw[$j],#31
___
}
sub BODY_40_59 {
my ($i,$a,$b,$c,$d,$e)=@_;
my $j=($i+2)&15;
$code.=<<___ if ($i==59);
movz $K,#0xc1d6
movk $K,#0xca62,lsl#16
___
$code.=<<___;
orr $t0,$b,$c
and $t1,$b,$c
eor @Xw[$j],@Xw[$j],@Xw[($j+2)&15]
ror $t2,$a,#27
and $t0,$t0,$d
add $d,$d,$K // future e+=K
eor @Xw[$j],@Xw[$j],@Xw[($j+8)&15]
add $e,$e,$t2 // e+=rot(a,5)
orr $t0,$t0,$t1
ror $b,$b,#2
eor @Xw[$j],@Xw[$j],@Xw[($j+13)&15]
add $d,$d,@Xw[($i+1)&15] // future e+=X[i]
add $e,$e,$t0 // e+=F(b,c,d)
ror @Xw[$j],@Xw[$j],#31
___
}
sub BODY_20_39 {
my ($i,$a,$b,$c,$d,$e)=@_;
my $j=($i+2)&15;
$code.=<<___ if ($i==39);
movz $K,#0xbcdc
movk $K,#0x8f1b,lsl#16
___
$code.=<<___ if ($i<78);
eor @Xw[$j],@Xw[$j],@Xw[($j+2)&15]
eor $t0,$d,$b
ror $t2,$a,#27
add $d,$d,$K // future e+=K
eor @Xw[$j],@Xw[$j],@Xw[($j+8)&15]
eor $t0,$t0,$c
add $e,$e,$t2 // e+=rot(a,5)
ror $b,$b,#2
eor @Xw[$j],@Xw[$j],@Xw[($j+13)&15]
add $d,$d,@Xw[($i+1)&15] // future e+=X[i]
add $e,$e,$t0 // e+=F(b,c,d)
ror @Xw[$j],@Xw[$j],#31
___
$code.=<<___ if ($i==78);
ldp @Xw[1],@Xw[2],[$ctx]
eor $t0,$d,$b
ror $t2,$a,#27
add $d,$d,$K // future e+=K
eor $t0,$t0,$c
add $e,$e,$t2 // e+=rot(a,5)
ror $b,$b,#2
add $d,$d,@Xw[($i+1)&15] // future e+=X[i]
add $e,$e,$t0 // e+=F(b,c,d)
___
$code.=<<___ if ($i==79);
ldp @Xw[3],@Xw[4],[$ctx,#8]
eor $t0,$d,$b
ror $t2,$a,#27
eor $t0,$t0,$c
add $e,$e,$t2 // e+=rot(a,5)
ror $b,$b,#2
ldr @Xw[5],[$ctx,#16]
add $e,$e,$t0 // e+=F(b,c,d)
___
}
$code.=<<___;
#include "arm_arch.h"
.text
.extern OPENSSL_armcap_P
.globl sha1_block_data_order
.type sha1_block_data_order,%function
.align 6
sha1_block_data_order:
ldr x16,.LOPENSSL_armcap_P
adr x17,.LOPENSSL_armcap_P
add x16,x16,x17
ldr w16,[x16]
tst w16,#ARMV8_SHA1
b.ne .Lv8_entry
stp x29,x30,[sp,#-96]!
add x29,sp,#0
stp x19,x20,[sp,#16]
stp x21,x22,[sp,#32]
stp x23,x24,[sp,#48]
stp x25,x26,[sp,#64]
stp x27,x28,[sp,#80]
ldp $A,$B,[$ctx]
ldp $C,$D,[$ctx,#8]
ldr $E,[$ctx,#16]
.Loop:
ldr @Xx[0],[$inp],#64
movz $K,#0x7999
sub $num,$num,#1
movk $K,#0x5a82,lsl#16
#ifdef __ARMEB__
ror $Xx[0],@Xx[0],#32
#else
rev32 @Xx[0],@Xx[0]
#endif
add $E,$E,$K // warm it up
add $E,$E,@Xw[0]
___
for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
$code.=<<___;
add $B,$B,@Xw[2]
add $C,$C,@Xw[3]
add $A,$A,@Xw[1]
add $D,$D,@Xw[4]
add $E,$E,@Xw[5]
stp $A,$B,[$ctx]
stp $C,$D,[$ctx,#8]
str $E,[$ctx,#16]
cbnz $num,.Loop
ldp x19,x20,[sp,#16]
ldp x21,x22,[sp,#32]
ldp x23,x24,[sp,#48]
ldp x25,x26,[sp,#64]
ldp x27,x28,[sp,#80]
ldr x29,[sp],#96
ret
.size sha1_block_data_order,.-sha1_block_data_order
___
{{{
my ($ABCD,$E,$E0,$E1)=map("v$_.16b",(0..3));
my @MSG=map("v$_.16b",(4..7));
my @Kxx=map("v$_.4s",(16..19));
my ($W0,$W1)=("v20.4s","v21.4s");
my $ABCD_SAVE="v22.16b";
$code.=<<___;
.type sha1_block_armv8,%function
.align 6
sha1_block_armv8:
.Lv8_entry:
stp x29,x30,[sp,#-16]!
add x29,sp,#0
adr x4,.Lconst
eor $E,$E,$E
ld1.32 {$ABCD},[$ctx],#16
ld1.32 {$E}[0],[$ctx]
sub $ctx,$ctx,#16
ld1.32 {@Kxx[0]-@Kxx[3]},[x4]
.Loop_hw:
ld1 {@MSG[0]-@MSG[3]},[$inp],#64
sub $num,$num,#1
rev32 @MSG[0],@MSG[0]
rev32 @MSG[1],@MSG[1]
add.i32 $W0,@Kxx[0],@MSG[0]
rev32 @MSG[2],@MSG[2]
orr $ABCD_SAVE,$ABCD,$ABCD // offload
add.i32 $W1,@Kxx[0],@MSG[1]
rev32 @MSG[3],@MSG[3]
sha1h $E1,$ABCD
sha1c $ABCD,$E,$W0 // 0
add.i32 $W0,@Kxx[$j],@MSG[2]
sha1su0 @MSG[0],@MSG[1],@MSG[2]
___
for ($j=0,$i=1;$i<20-3;$i++) {
my $f=("c","p","m","p")[$i/5];
$code.=<<___;
sha1h $E0,$ABCD // $i
sha1$f $ABCD,$E1,$W1
add.i32 $W1,@Kxx[$j],@MSG[3]
sha1su1 @MSG[0],@MSG[3]
___
$code.=<<___ if ($i<20-4);
sha1su0 @MSG[1],@MSG[2],@MSG[3]
___
($E0,$E1)=($E1,$E0); ($W0,$W1)=($W1,$W0);
push(@MSG,shift(@MSG)); $j++ if ((($i+3)%5)==0);
}
$code.=<<___;
sha1h $E0,$ABCD // $i
sha1p $ABCD,$E1,$W1
add.i32 $W1,@Kxx[$j],@MSG[3]
sha1h $E1,$ABCD // 18
sha1p $ABCD,$E0,$W0
sha1h $E0,$ABCD // 19
sha1p $ABCD,$E1,$W1
add.i32 $E,$E,$E0
add.i32 $ABCD,$ABCD,$ABCD_SAVE
cbnz $num,.Loop_hw
st1.32 {$ABCD},[$ctx],#16
st1.32 {$E}[0],[$ctx]
ldr x29,[sp],#16
ret
.size sha1_block_armv8,.-sha1_block_armv8
.align 6
.Lconst:
.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19
.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39
.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59
.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79
.LOPENSSL_armcap_P:
.quad OPENSSL_armcap_P-.
.asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
.comm OPENSSL_armcap_P,4,4
___
}}}
{ my %opcode = (
"sha1c" => 0x5e000000, "sha1p" => 0x5e001000,
"sha1m" => 0x5e002000, "sha1su0" => 0x5e003000,
"sha1h" => 0x5e280800, "sha1su1" => 0x5e281800 );
sub unsha1 {
my ($mnemonic,$arg)=@_;
$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o
&&
sprintf ".inst\t0x%08x\t//%s %s",
$opcode{$mnemonic}|$1|($2<<5)|($3<<16),
$mnemonic,$arg;
}
}
foreach(split("\n",$code)) {
s/\`([^\`]*)\`/eval($1)/geo;
s/\b(sha1\w+)\s+([qv].*)/unsha1($1,$2)/geo;
s/\.\w?32\b//o and s/\.16b/\.4s/go;
m/(ld|st)1[^\[]+\[0\]/o and s/\.4s/\.s/go;
print $_,"\n";
}
close STDOUT;

View File

@@ -23,8 +23,20 @@
# Profiler-assisted and platform-specific optimization resulted in 16%
# improvement on Cortex A8 core and ~17 cycles per processed byte.
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
$ctx="r0"; $t0="r0";
$inp="r1"; $t3="r1";

View File

@@ -38,8 +38,20 @@ $hi="HI";
$lo="LO";
# ====================================================================
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
$flavour = shift;
if ($flavour=~/^\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
else { while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} }
if ($flavour && $flavour ne "void") {
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open STDOUT,"| \"$^X\" $xlate $flavour $output";
} else {
open STDOUT,">$output";
}
$ctx="r0"; # parameter block
$inp="r1";
@@ -221,17 +233,21 @@ WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
.size K512,.-K512
.LOPENSSL_armcap:
.word OPENSSL_armcap_P-sha512_block_data_order
.word OPENSSL_armcap_P-.Lsha512_block_data_order
.skip 32-4
.global sha512_block_data_order
.type sha512_block_data_order,%function
sha512_block_data_order:
.Lsha512_block_data_order:
sub r3,pc,#8 @ sha512_block_data_order
add $len,$inp,$len,lsl#7 @ len to point at the end of inp
#if __ARM_ARCH__>=7
ldr r12,.LOPENSSL_armcap
ldr r12,[r3,r12] @ OPENSSL_armcap_P
#ifdef __APPLE__
ldr r12,[r12]
#endif
tst r12,#1
bne .LNEON
#endif

View File

@@ -0,0 +1,428 @@
#!/usr/bin/env perl
#
# ====================================================================
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
# project. The module is, however, dual licensed under OpenSSL and
# CRYPTOGAMS licenses depending on where you obtain it. For further
# details see http://www.openssl.org/~appro/cryptogams/.
# ====================================================================
#
# SHA256/512 for ARMv8.
#
# Performance in cycles per processed byte and improvement coefficient
# over code generated with "default" compiler:
#
# SHA256-hw SHA256(*) SHA512
# Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**))
# Cortex-A53 2.38 15.6 (+110%) 10.1 (+190%(***))
# Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***))
#
# (*) Software SHA256 results are of lesser relevance, presented
# mostly for informational purposes.
# (**) The result is a trade-off: it's possible to improve it by
# 10% (or by 1 cycle per round), but at the cost of 20% loss
# on Cortex-A53 (or by 4 cycles per round).
# (***) Super-impressive coefficients over gcc-generated code are
# indication of some compiler "pathology", most notably code
# generated with -mgeneral-regs-only is significanty faster
# and lags behind assembly only by 50-90%.
$flavour=shift;
$output=shift;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
if ($output =~ /512/) {
$BITS=512;
$SZ=8;
@Sigma0=(28,34,39);
@Sigma1=(14,18,41);
@sigma0=(1, 8, 7);
@sigma1=(19,61, 6);
$rounds=80;
$reg_t="x";
} else {
$BITS=256;
$SZ=4;
@Sigma0=( 2,13,22);
@Sigma1=( 6,11,25);
@sigma0=( 7,18, 3);
@sigma1=(17,19,10);
$rounds=64;
$reg_t="w";
}
$func="sha${BITS}_block_data_order";
($ctx,$inp,$num,$Ktbl)=map("x$_",(0..2,30));
@X=map("$reg_t$_",(3..15,0..2));
@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("$reg_t$_",(20..27));
($t0,$t1,$t2,$t3)=map("$reg_t$_",(16,17,19,28));
sub BODY_00_xx {
my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_;
my $j=($i+1)&15;
my ($T0,$T1,$T2)=(@X[($i-8)&15],@X[($i-9)&15],@X[($i-10)&15]);
$T0=@X[$i+3] if ($i<11);
$code.=<<___ if ($i<16);
#ifndef __ARMEB__
rev @X[$i],@X[$i] // $i
#endif
___
$code.=<<___ if ($i<13 && ($i&1));
ldp @X[$i+1],@X[$i+2],[$inp],#2*$SZ
___
$code.=<<___ if ($i==13);
ldp @X[14],@X[15],[$inp]
___
$code.=<<___ if ($i>=14);
ldr @X[($i-11)&15],[sp,#`$SZ*(($i-11)%4)`]
___
$code.=<<___ if ($i>0 && $i<16);
add $a,$a,$t1 // h+=Sigma0(a)
___
$code.=<<___ if ($i>=11);
str @X[($i-8)&15],[sp,#`$SZ*(($i-8)%4)`]
___
# While ARMv8 specifies merged rotate-n-logical operation such as
# 'eor x,y,z,ror#n', it was found to negatively affect performance
# on Apple A7. The reason seems to be that it requires even 'y' to
# be available earlier. This means that such merged instruction is
# not necessarily best choice on critical path... On the other hand
# Cortex-A5x handles merged instructions much better than disjoint
# rotate and logical... See (**) footnote above.
$code.=<<___ if ($i<15);
ror $t0,$e,#$Sigma1[0]
add $h,$h,$t2 // h+=K[i]
eor $T0,$e,$e,ror#`$Sigma1[2]-$Sigma1[1]`
and $t1,$f,$e
bic $t2,$g,$e
add $h,$h,@X[$i&15] // h+=X[i]
orr $t1,$t1,$t2 // Ch(e,f,g)
eor $t2,$a,$b // a^b, b^c in next round
eor $t0,$t0,$T0,ror#$Sigma1[1] // Sigma1(e)
ror $T0,$a,#$Sigma0[0]
add $h,$h,$t1 // h+=Ch(e,f,g)
eor $t1,$a,$a,ror#`$Sigma0[2]-$Sigma0[1]`
add $h,$h,$t0 // h+=Sigma1(e)
and $t3,$t3,$t2 // (b^c)&=(a^b)
add $d,$d,$h // d+=h
eor $t3,$t3,$b // Maj(a,b,c)
eor $t1,$T0,$t1,ror#$Sigma0[1] // Sigma0(a)
add $h,$h,$t3 // h+=Maj(a,b,c)
ldr $t3,[$Ktbl],#$SZ // *K++, $t2 in next round
//add $h,$h,$t1 // h+=Sigma0(a)
___
$code.=<<___ if ($i>=15);
ror $t0,$e,#$Sigma1[0]
add $h,$h,$t2 // h+=K[i]
ror $T1,@X[($j+1)&15],#$sigma0[0]
and $t1,$f,$e
ror $T2,@X[($j+14)&15],#$sigma1[0]
bic $t2,$g,$e
ror $T0,$a,#$Sigma0[0]
add $h,$h,@X[$i&15] // h+=X[i]
eor $t0,$t0,$e,ror#$Sigma1[1]
eor $T1,$T1,@X[($j+1)&15],ror#$sigma0[1]
orr $t1,$t1,$t2 // Ch(e,f,g)
eor $t2,$a,$b // a^b, b^c in next round
eor $t0,$t0,$e,ror#$Sigma1[2] // Sigma1(e)
eor $T0,$T0,$a,ror#$Sigma0[1]
add $h,$h,$t1 // h+=Ch(e,f,g)
and $t3,$t3,$t2 // (b^c)&=(a^b)
eor $T2,$T2,@X[($j+14)&15],ror#$sigma1[1]
eor $T1,$T1,@X[($j+1)&15],lsr#$sigma0[2] // sigma0(X[i+1])
add $h,$h,$t0 // h+=Sigma1(e)
eor $t3,$t3,$b // Maj(a,b,c)
eor $t1,$T0,$a,ror#$Sigma0[2] // Sigma0(a)
eor $T2,$T2,@X[($j+14)&15],lsr#$sigma1[2] // sigma1(X[i+14])
add @X[$j],@X[$j],@X[($j+9)&15]
add $d,$d,$h // d+=h
add $h,$h,$t3 // h+=Maj(a,b,c)
ldr $t3,[$Ktbl],#$SZ // *K++, $t2 in next round
add @X[$j],@X[$j],$T1
add $h,$h,$t1 // h+=Sigma0(a)
add @X[$j],@X[$j],$T2
___
($t2,$t3)=($t3,$t2);
}
$code.=<<___;
#include "arm_arch.h"
.text
.extern OPENSSL_armcap_P
.globl $func
.type $func,%function
.align 6
$func:
___
$code.=<<___ if ($SZ==4);
ldr x16,.LOPENSSL_armcap_P
adr x17,.LOPENSSL_armcap_P
add x16,x16,x17
ldr w16,[x16]
tst w16,#ARMV8_SHA256
b.ne .Lv8_entry
___
$code.=<<___;
stp x29,x30,[sp,#-128]!
add x29,sp,#0
stp x19,x20,[sp,#16]
stp x21,x22,[sp,#32]
stp x23,x24,[sp,#48]
stp x25,x26,[sp,#64]
stp x27,x28,[sp,#80]
sub sp,sp,#4*$SZ
ldp $A,$B,[$ctx] // load context
ldp $C,$D,[$ctx,#2*$SZ]
ldp $E,$F,[$ctx,#4*$SZ]
add $num,$inp,$num,lsl#`log(16*$SZ)/log(2)` // end of input
ldp $G,$H,[$ctx,#6*$SZ]
adr $Ktbl,.LK$BITS
stp $ctx,$num,[x29,#96]
.Loop:
ldp @X[0],@X[1],[$inp],#2*$SZ
ldr $t2,[$Ktbl],#$SZ // *K++
eor $t3,$B,$C // magic seed
str $inp,[x29,#112]
___
for ($i=0;$i<16;$i++) { &BODY_00_xx($i,@V); unshift(@V,pop(@V)); }
$code.=".Loop_16_xx:\n";
for (;$i<32;$i++) { &BODY_00_xx($i,@V); unshift(@V,pop(@V)); }
$code.=<<___;
cbnz $t2,.Loop_16_xx
ldp $ctx,$num,[x29,#96]
ldr $inp,[x29,#112]
sub $Ktbl,$Ktbl,#`$SZ*($rounds+1)` // rewind
ldp @X[0],@X[1],[$ctx]
ldp @X[2],@X[3],[$ctx,#2*$SZ]
add $inp,$inp,#14*$SZ // advance input pointer
ldp @X[4],@X[5],[$ctx,#4*$SZ]
add $A,$A,@X[0]
ldp @X[6],@X[7],[$ctx,#6*$SZ]
add $B,$B,@X[1]
add $C,$C,@X[2]
add $D,$D,@X[3]
stp $A,$B,[$ctx]
add $E,$E,@X[4]
add $F,$F,@X[5]
stp $C,$D,[$ctx,#2*$SZ]
add $G,$G,@X[6]
add $H,$H,@X[7]
cmp $inp,$num
stp $E,$F,[$ctx,#4*$SZ]
stp $G,$H,[$ctx,#6*$SZ]
b.ne .Loop
ldp x19,x20,[x29,#16]
add sp,sp,#4*$SZ
ldp x21,x22,[x29,#32]
ldp x23,x24,[x29,#48]
ldp x25,x26,[x29,#64]
ldp x27,x28,[x29,#80]
ldp x29,x30,[sp],#128
ret
.size $func,.-$func
.align 6
.type .LK$BITS,%object
.LK$BITS:
___
$code.=<<___ if ($SZ==8);
.quad 0x428a2f98d728ae22,0x7137449123ef65cd
.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
.quad 0x3956c25bf348b538,0x59f111f1b605d019
.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
.quad 0xd807aa98a3030242,0x12835b0145706fbe
.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
.quad 0x9bdc06a725c71235,0xc19bf174cf692694
.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
.quad 0x983e5152ee66dfab,0xa831c66d2db43210
.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
.quad 0x06ca6351e003826f,0x142929670a0e6e70
.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
.quad 0x650a73548baf63de,0x766a0abb3c77b2a8
.quad 0x81c2c92e47edaee6,0x92722c851482353b
.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
.quad 0xc24b8b70d0f89791,0xc76c51a30654be30
.quad 0xd192e819d6ef5218,0xd69906245565a910
.quad 0xf40e35855771202a,0x106aa07032bbd1b8
.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
.quad 0x748f82ee5defb2fc,0x78a5636f43172f60
.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
.quad 0x90befffa23631e28,0xa4506cebde82bde9
.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
.quad 0xca273eceea26619c,0xd186b8c721c0c207
.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
.quad 0x113f9804bef90dae,0x1b710b35131c471b
.quad 0x28db77f523047d84,0x32caab7b40c72493
.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
.quad 0 // terminator
___
$code.=<<___ if ($SZ==4);
.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
.long 0 //terminator
___
$code.=<<___;
.size .LK$BITS,.-.LK$BITS
.align 3
.LOPENSSL_armcap_P:
.quad OPENSSL_armcap_P-.
.asciz "SHA$BITS block transform for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
___
if ($SZ==4) {
my $Ktbl="x3";
my ($ABCD,$EFGH,$abcd)=map("v$_.16b",(0..2));
my @MSG=map("v$_.16b",(4..7));
my ($W0,$W1)=("v16.4s","v17.4s");
my ($ABCD_SAVE,$EFGH_SAVE)=("v18.16b","v19.16b");
$code.=<<___;
.type sha256_block_armv8,%function
.align 6
sha256_block_armv8:
.Lv8_entry:
stp x29,x30,[sp,#-16]!
add x29,sp,#0
ld1.32 {$ABCD,$EFGH},[$ctx]
adr $Ktbl,.LK256
.Loop_hw:
ld1 {@MSG[0]-@MSG[3]},[$inp],#64
sub $num,$num,#1
ld1.32 {$W0},[$Ktbl],#16
rev32 @MSG[0],@MSG[0]
rev32 @MSG[1],@MSG[1]
rev32 @MSG[2],@MSG[2]
rev32 @MSG[3],@MSG[3]
orr $ABCD_SAVE,$ABCD,$ABCD // offload
orr $EFGH_SAVE,$EFGH,$EFGH
___
for($i=0;$i<12;$i++) {
$code.=<<___;
ld1.32 {$W1},[$Ktbl],#16
add.i32 $W0,$W0,@MSG[0]
sha256su0 @MSG[0],@MSG[1]
orr $abcd,$ABCD,$ABCD
sha256h $ABCD,$EFGH,$W0
sha256h2 $EFGH,$abcd,$W0
sha256su1 @MSG[0],@MSG[2],@MSG[3]
___
($W0,$W1)=($W1,$W0); push(@MSG,shift(@MSG));
}
$code.=<<___;
ld1.32 {$W1},[$Ktbl],#16
add.i32 $W0,$W0,@MSG[0]
orr $abcd,$ABCD,$ABCD
sha256h $ABCD,$EFGH,$W0
sha256h2 $EFGH,$abcd,$W0
ld1.32 {$W0},[$Ktbl],#16
add.i32 $W1,$W1,@MSG[1]
orr $abcd,$ABCD,$ABCD
sha256h $ABCD,$EFGH,$W1
sha256h2 $EFGH,$abcd,$W1
ld1.32 {$W1},[$Ktbl]
add.i32 $W0,$W0,@MSG[2]
sub $Ktbl,$Ktbl,#$rounds*$SZ-16 // rewind
orr $abcd,$ABCD,$ABCD
sha256h $ABCD,$EFGH,$W0
sha256h2 $EFGH,$abcd,$W0
add.i32 $W1,$W1,@MSG[3]
orr $abcd,$ABCD,$ABCD
sha256h $ABCD,$EFGH,$W1
sha256h2 $EFGH,$abcd,$W1
add.i32 $ABCD,$ABCD,$ABCD_SAVE
add.i32 $EFGH,$EFGH,$EFGH_SAVE
cbnz $num,.Loop_hw
st1.32 {$ABCD,$EFGH},[$ctx]
ldr x29,[sp],#16
ret
.size sha256_block_armv8,.-sha256_block_armv8
___
}
$code.=<<___;
.comm OPENSSL_armcap_P,4,4
___
{ my %opcode = (
"sha256h" => 0x5e004000, "sha256h2" => 0x5e005000,
"sha256su0" => 0x5e282800, "sha256su1" => 0x5e006000 );
sub unsha256 {
my ($mnemonic,$arg)=@_;
$arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+))?/o
&&
sprintf ".inst\t0x%08x\t//%s %s",
$opcode{$mnemonic}|$1|($2<<5)|($3<<16),
$mnemonic,$arg;
}
}
foreach(split("\n",$code)) {
s/\`([^\`]*)\`/eval($1)/geo;
s/\b(sha256\w+)\s+([qv].*)/unsha256($1,$2)/geo;
s/\.\w?32\b//o and s/\.16b/\.4s/go;
m/(ld|st)1[^\[]+\[0\]/o and s/\.4s/\.s/go;
print $_,"\n";
}
close STDOUT;

4
e_os.h
View File

@@ -306,7 +306,7 @@ static unsigned int _strlen31(const char *str)
# undef isupper
# undef isxdigit
# endif
# if defined(_MSC_VER) && !defined(_DLL) && defined(stdin)
# if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin)
# if _MSC_VER>=1300
# undef stdin
# undef stdout
@@ -332,8 +332,10 @@ static unsigned int _strlen31(const char *str)
# endif
# endif
# endif
# if !defined(OPENSSL_FIPSCANISTER)
# include <io.h>
# include <fcntl.h>
# endif
# ifdef OPENSSL_SYS_WINCE
# define OPENSSL_NO_POSIX_IO

View File

@@ -208,8 +208,6 @@ static void gcmtest(FILE *in, FILE *out, int encrypt)
ct = OPENSSL_malloc(ptlen);
rv = FIPS_cipher(&ctx, ct, pt, ptlen);
}
else
FIPS_cipher(&ctx, iv, iv, 0);
FIPS_cipher(&ctx, NULL, NULL, 0);
FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG,
taglen, tag);
@@ -244,8 +242,6 @@ static void gcmtest(FILE *in, FILE *out, int encrypt)
pt = OPENSSL_malloc(ptlen);
rv = FIPS_cipher(&ctx, pt, ct, ptlen);
}
else
FIPS_cipher(&ctx, iv, iv, 0);
rv = FIPS_cipher(&ctx, NULL, NULL, 0);
if (rv < 0)
fprintf(out, "FAIL" RESP_EOL);

View File

@@ -83,7 +83,7 @@ static const struct
int FIPS_selftest_des()
{
int n, ret = 0;
int n, ret = 1;
EVP_CIPHER_CTX ctx;
FIPS_cipher_ctx_init(&ctx);
@@ -93,10 +93,8 @@ int FIPS_selftest_des()
if (!fips_cipher_test(FIPS_TEST_CIPHER, &ctx, EVP_des_ede3_ecb(),
tests3[n].key, NULL,
tests3[n].plaintext, tests3[n].ciphertext, 8))
goto err;
ret = 0;
}
ret = 1;
err:
FIPS_cipher_ctx_cleanup(&ctx);
if (ret == 0)
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);

View File

@@ -553,6 +553,11 @@ static void keypair(FILE *in, FILE *out)
int n=atoi(value);
dsa = FIPS_dsa_new();
if (!dsa)
{
fprintf(stderr, "DSA allocation error\n");
exit(1);
}
if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
NULL, NULL, NULL, NULL))
{
@@ -579,7 +584,6 @@ static void keypair(FILE *in, FILE *out)
do_bn_print_name(out, "Y",dsa->pub_key);
fputs(RESP_EOL, out);
}
if (dsa)
FIPS_dsa_free(dsa);
}
}

View File

@@ -143,7 +143,7 @@ int FIPS_selftest_ecdsa()
EC_KEY *ec = NULL;
BIGNUM *x = NULL, *y = NULL, *d = NULL;
EVP_PKEY pk;
int rv = 0;
int rv = 0, test_err = 0;
size_t i;
for (i = 0; i < sizeof(test_ec_data)/sizeof(EC_SELFTEST_DATA); i++)
@@ -173,11 +173,11 @@ int FIPS_selftest_ecdsa()
if (!fips_pkey_signature_test(FIPS_TEST_SIGNATURE, &pk, NULL, 0,
NULL, 0, EVP_sha512(), 0,
ecd->name))
goto err;
test_err = 1;
EC_KEY_free(ec);
ec = NULL;
}
if (test_err == 0)
rv = 1;
err:

View File

@@ -151,7 +151,7 @@ extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
#ifdef _TMS320C6X
const
#endif
unsigned char FIPS_signature [20] = { 0 };
unsigned char FIPS_signature [20] = { 0, 0xff };
__fips_constseg
static const char FIPS_hmac_key[]="etaonrishdlcupfm";

View File

@@ -29,6 +29,7 @@ const void *FIPS_text_end(void);
#if !defined(FIPS_REF_POINT_IS_CROSS_COMPILER_AWARE)
# if (defined(__ANDROID__) && (defined(__arm__) || defined(__arm) || \
defined(__aarch64__) || \
defined(__i386__)|| defined(__i386))) || \
(defined(__vxworks) && (defined(__ppc__) || defined(__ppc) || \
defined(__mips__)|| defined(__mips))) || \

View File

@@ -40,12 +40,46 @@ int main(int argc, char *argv[])
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/ecdsa.h>
#include <openssl/dh.h>
#include <openssl/fips.h>
#include <openssl/fips_rand.h>
#include "fips_utl.h"
static int verbose = 0;
static int fips_module_mode_set_verbose(int mode, const char *pass)
{
int rv;
if (verbose)
printf("Attempting to %s FIPS mode\n", mode ? "Enter" : "Leave");
rv = FIPS_module_mode_set(mode, pass);
if (verbose)
printf("FIPS_module_mode() returned %d\n", FIPS_module_mode());
return rv;
}
static void do_print_rsa_key(RSA *rsa)
{
if (!verbose)
return;
do_bn_print_name(stdout, "RSA key modulus value", rsa->e);
do_bn_print_name(stdout, "RSA key publicExponent value", rsa->n);
do_bn_print_name(stdout, "RSA key pricateExponent value", rsa->d);
do_bn_print_name(stdout, "RSA key prime1 value", rsa->p);
do_bn_print_name(stdout, "RSA key prime2 value", rsa->q);
do_bn_print_name(stdout, "RSA key exponent1 value", rsa->dmp1);
do_bn_print_name(stdout, "RSA key exponent2 value", rsa->dmq1);
do_bn_print_name(stdout, "RSA key coefficient value", rsa->iqmp);
}
static void do_print_buf(char *name, unsigned char *buf, int buflen)
{
if (verbose)
OutputValue(name, buf, buflen, stdout, 0);
}
/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
*/
static int FIPS_aes_test(void)
@@ -57,14 +91,30 @@ static int FIPS_aes_test(void)
unsigned char plaintext[16] = "etaonrishdlcu";
EVP_CIPHER_CTX ctx;
FIPS_cipher_ctx_init(&ctx);
if (verbose)
{
do_print_buf("Key", key, sizeof(key));
do_print_buf("Plaintext", plaintext, sizeof(plaintext));
}
if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 1) <= 0)
goto err;
FIPS_cipher(&ctx, citmp, plaintext, 16);
if (verbose)
{
do_print_buf("Ciphertext", citmp, sizeof(plaintext));
printf("AES 128 bit ECB mode decryption started\n");
}
if (FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 0) <= 0)
goto err;
FIPS_cipher(&ctx, pltmp, citmp, 16);
do_print_buf("Recovered Plaintext", pltmp, sizeof(plaintext));
if (memcmp(pltmp, plaintext, 16))
{
printf("Comparison failure!!\n");
goto err;
}
if (verbose)
printf("Comparison success.\n");
ret = 1;
err:
FIPS_cipher_ctx_cleanup(&ctx);
@@ -83,6 +133,13 @@ static int FIPS_aes_gcm_test(void)
unsigned char plaintext[16] = "etaonrishdlcu";
EVP_CIPHER_CTX ctx;
FIPS_cipher_ctx_init(&ctx);
if (verbose)
{
do_print_buf("Key", key, sizeof(key));
do_print_buf("IV", key, sizeof(iv));
do_print_buf("Plaintext", plaintext, sizeof(plaintext));
do_print_buf("AAD", aad, sizeof(aad));
}
if (FIPS_cipherinit(&ctx, EVP_aes_128_gcm(), key, iv, 1) <= 0)
goto err;
FIPS_cipher(&ctx, NULL, aad, sizeof(aad));
@@ -91,6 +148,12 @@ static int FIPS_aes_gcm_test(void)
if (!FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 16, tagtmp))
goto err;
if (verbose)
{
do_print_buf("Ciphertext", citmp, sizeof(citmp));
do_print_buf("Tag", tagtmp, sizeof(tagtmp));
}
if (FIPS_cipherinit(&ctx, EVP_aes_128_gcm(), key, iv, 0) <= 0)
goto err;
if (!FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, 16, tagtmp))
@@ -103,8 +166,17 @@ static int FIPS_aes_gcm_test(void)
if (FIPS_cipher(&ctx, NULL, NULL, 0) < 0)
goto err;
if (verbose)
do_print_buf("Recovered Plaintext", pltmp, sizeof(plaintext));
if (memcmp(pltmp, plaintext, 16))
{
if (verbose)
printf("Comparison failure!!\n");
goto err;
}
printf("Comparison sucess.\n");
ret = 1;
err:
@@ -122,20 +194,110 @@ static int FIPS_des3_test(void)
unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
EVP_CIPHER_CTX ctx;
FIPS_cipher_ctx_init(&ctx);
if (verbose)
{
do_print_buf("Key", key, sizeof(key));
do_print_buf("Plaintext", plaintext, sizeof(plaintext));
}
if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 1) <= 0)
goto err;
FIPS_cipher(&ctx, citmp, plaintext, 8);
if (verbose)
{
do_print_buf("Ciphertext", citmp, sizeof(plaintext));
printf("DES3 ECB mode decryption\n");
}
if (FIPS_cipherinit(&ctx, EVP_des_ede3_ecb(), key, NULL, 0) <= 0)
goto err;
FIPS_cipher(&ctx, pltmp, citmp, 8);
if (verbose)
do_print_buf("Recovered Plaintext", pltmp, sizeof(plaintext));
if (memcmp(pltmp, plaintext, 8))
{
if (verbose)
printf("Comparison failure!!\n");
goto err;
}
if (verbose)
printf("Comparison success\n");
ret = 1;
err:
FIPS_cipher_ctx_cleanup(&ctx);
return ret;
}
/*
* ECDSA: generate keys and sign, verify input plaintext.
*/
static int FIPS_ecdsa_test(void)
{
EC_KEY *ec = NULL;
unsigned char dgst[] = "etaonrishdlc";
int r = 0;
ECDSA_SIG *sig = NULL;
ERR_clear_error();
ec = FIPS_ec_key_new_by_curve_name(NID_X9_62_prime256v1);
if (!ec)
goto end;
if (!FIPS_ec_key_generate_key(ec))
goto end;
if (verbose)
{
BIGNUM *Qx, *Qy;
BN_CTX *ctx;
const EC_GROUP *grp;
const EC_POINT *pt;
const BIGNUM *priv;
Qx = BN_new();
Qy = BN_new();
ctx = BN_CTX_new();
grp = EC_KEY_get0_group(ec);
pt = EC_KEY_get0_public_key(ec);
priv = EC_KEY_get0_private_key(ec);
printf("EC Key using P-256\n");
if (!EC_POINT_get_affine_coordinates_GFp(grp, pt, Qx, Qy, ctx))
goto end;
do_bn_print_name(stdout, "ECDSA key x coordinate", Qx);
do_bn_print_name(stdout, "ECDSA key y coordinate", Qy);
do_bn_print_name(stdout, "ECDSA key private value", priv);
BN_free(Qx);
BN_free(Qy);
BN_CTX_free(ctx);
printf("Signing string \"%s\" using SHA256\n", dgst);
}
sig = FIPS_ecdsa_sign(ec, dgst, sizeof(dgst) -1, EVP_sha256());
if (!sig)
{
if (verbose)
printf("Signing Failed!!\n");
goto end;
}
if (verbose)
{
printf("Signing successful\n");
do_bn_print_name(stdout, "ECDSA signature r value", sig->r);
do_bn_print_name(stdout, "ECDSA signature s value", sig->s);
}
r = FIPS_ecdsa_verify(ec, dgst, sizeof(dgst) -1, EVP_sha256(), sig);
if (verbose)
printf("ECDSA verification %s\n", r ? "Successful." : "Failed!!");
end:
if (sig)
FIPS_ecdsa_sig_free(sig);
if (ec)
FIPS_ec_key_free(ec);
if (r != 1)
return 0;
return 1;
}
/*
* DSA: generate keys and sign, verify input plaintext.
*/
@@ -157,11 +319,34 @@ static int FIPS_dsa_test(int bad)
if (bad)
BN_add_word(dsa->pub_key, 1);
if (verbose)
{
do_bn_print_name(stdout, "DSA key p value", dsa->p);
do_bn_print_name(stdout, "DSA key q value", dsa->q);
do_bn_print_name(stdout, "DSA key g value", dsa->g);
do_bn_print_name(stdout, "DSA key public_key value", dsa->pub_key);
do_bn_print_name(stdout, "DSA key private key value", dsa->priv_key);
printf("Signing string \"%s\" using SHA256\n", dgst);
}
sig = FIPS_dsa_sign(dsa, dgst, sizeof(dgst) -1, EVP_sha256());
if (!sig)
{
if (verbose)
printf("Signing Failed!!\n");
goto end;
}
if (verbose)
{
printf("Signing successful\n");
do_bn_print_name(stdout, "DSA signature r value", sig->r);
do_bn_print_name(stdout, "DSA signature s value", sig->s);
}
r = FIPS_dsa_verify(dsa, dgst, sizeof(dgst) -1, EVP_sha256(), sig);
if (verbose)
printf("DSA verification %s\n", r ? "Successful." : "Failed!!");
end:
if (sig)
FIPS_dsa_sig_free(sig);
@@ -196,12 +381,30 @@ static int FIPS_rsa_test(int bad)
if (bad)
BN_add_word(key->n, 1);
if (verbose)
{
do_print_rsa_key(key);
printf("Signing string \"%s\" using SHA256\n", input_ptext);
}
if (!FIPS_rsa_sign(key, input_ptext, sizeof(input_ptext) - 1, EVP_sha256(),
RSA_PKCS1_PADDING, 0, NULL, buf, &slen))
{
if (verbose)
printf("RSA Signing failed!!\n");
goto end;
}
if (verbose)
{
printf("RSA signing successul\n");
do_print_buf("RSA signature", buf, slen);
}
r = FIPS_rsa_verify(key, input_ptext, sizeof(input_ptext) - 1, EVP_sha256(),
RSA_PKCS1_PADDING, 0, NULL, buf, slen);
if (verbose)
printf("RSA Verification %s\n", r == 1 ? "Successful" : "Failed!!");
end:
if (key)
FIPS_rsa_free(key);
@@ -223,6 +426,11 @@ static int FIPS_sha1_test()
ERR_clear_error();
if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha1())) return 0;
if (verbose)
{
printf("Digesting string %s\n", str);
do_print_buf("Digest value", md, sizeof(md));
}
if (memcmp(md,digest,sizeof(md)))
return 0;
return 1;
@@ -242,6 +450,11 @@ static int FIPS_sha256_test()
ERR_clear_error();
if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha256())) return 0;
if (verbose)
{
printf("Digesting string %s\n", str);
do_print_buf("Digest value", md, sizeof(md));
}
if (memcmp(md,digest,sizeof(md)))
return 0;
return 1;
@@ -263,6 +476,11 @@ static int FIPS_sha512_test()
ERR_clear_error();
if (!FIPS_digest(str,sizeof(str) - 1,md, NULL, EVP_sha512())) return 0;
if (verbose)
{
printf("Digesting string %s\n", str);
do_print_buf("Digest value", md, sizeof(md));
}
if (memcmp(md,digest,sizeof(md)))
return 0;
return 1;
@@ -284,8 +502,19 @@ static int FIPS_hmac_sha1_test()
ERR_clear_error();
if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
if (verbose)
{
do_print_buf("HMAC key", key, sizeof(key) -1);
do_print_buf("HMAC input", iv, sizeof(iv) -1);
do_print_buf("HMAC output", out, outlen);
}
if (memcmp(out,kaval,outlen))
{
if (verbose)
printf("HMAC comparison failed!!\n");
return 0;
}
printf("HMAC comparison successful.\n");
return 1;
}
@@ -305,6 +534,19 @@ static int FIPS_hmac_sha224_test()
ERR_clear_error();
if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
if (verbose)
{
do_print_buf("HMAC key", key, sizeof(key) -1);
do_print_buf("HMAC input", iv, sizeof(iv) -1);
do_print_buf("HMAC output", out, outlen);
}
if (memcmp(out,kaval,outlen))
{
if (verbose)
printf("HMAC comparison failed!!\n");
return 0;
}
printf("HMAC comparison successful.\n");
if (memcmp(out,kaval,outlen))
return 0;
return 1;
@@ -326,8 +568,19 @@ static int FIPS_hmac_sha256_test()
ERR_clear_error();
if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
if (verbose)
{
do_print_buf("HMAC key", key, sizeof(key) -1);
do_print_buf("HMAC input", iv, sizeof(iv) -1);
do_print_buf("HMAC output", out, outlen);
}
if (memcmp(out,kaval,outlen))
{
if (verbose)
printf("HMAC comparison failed!!\n");
return 0;
}
printf("HMAC comparison successful.\n");
return 1;
}
@@ -348,8 +601,19 @@ static int FIPS_hmac_sha384_test()
ERR_clear_error();
if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
if (verbose)
{
do_print_buf("HMAC key", key, sizeof(key) -1);
do_print_buf("HMAC input", iv, sizeof(iv) -1);
do_print_buf("HMAC output", out, outlen);
}
if (memcmp(out,kaval,outlen))
{
if (verbose)
printf("HMAC comparison failed!!\n");
return 0;
}
printf("HMAC comparison successful.\n");
return 1;
}
@@ -371,8 +635,19 @@ static int FIPS_hmac_sha512_test()
ERR_clear_error();
if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
if (verbose)
{
do_print_buf("HMAC key", key, sizeof(key) -1);
do_print_buf("HMAC input", iv, sizeof(iv) -1);
do_print_buf("HMAC output", out, outlen);
}
if (memcmp(out,kaval,outlen))
{
if (verbose)
printf("HMAC comparison failed!!\n");
return 0;
}
printf("HMAC comparison successful.\n");
return 1;
}
@@ -407,18 +682,15 @@ static int FIPS_cmac_aes128_test()
out = OPENSSL_malloc(outlen);
if (!CMAC_Final(ctx, out, &outlen))
goto end;
#if 0
{
char *hexout = OPENSSL_malloc(outlen * 2 + 1);
bin2hex(out, outlen, hexout);
printf("CMAC-AES128: res = %s\n", hexout);
OPENSSL_free(hexout);
}
r = 1;
#else
if (!memcmp(out,kaval,outlen))
r = 1;
#endif
if (verbose)
{
do_print_buf("CMAC key", key, sizeof(key));
do_print_buf("CMAC input", data, sizeof(data) -1);
do_print_buf("CMAC output", out, outlen);
printf("CMAC comparison %s\n", r == 1 ? "successful." : "Failed!!");
}
end:
CMAC_CTX_free(ctx);
if (out)
@@ -458,18 +730,15 @@ static int FIPS_cmac_aes192_test()
out = OPENSSL_malloc(outlen);
if (!CMAC_Final(ctx, out, &outlen))
goto end;
#if 0
{
char *hexout = OPENSSL_malloc(outlen * 2 + 1);
bin2hex(out, outlen, hexout);
printf("CMAC-AES192: res = %s\n", hexout);
OPENSSL_free(hexout);
}
r = 1;
#else
if (!memcmp(out,kaval,outlen))
r = 1;
#endif
if (verbose)
{
do_print_buf("CMAC key", key, sizeof(key));
do_print_buf("CMAC input", data, sizeof(data) -1);
do_print_buf("CMAC output", out, outlen);
printf("CMAC comparison %s\n", r == 1 ? "successful." : "Failed!!");
}
end:
CMAC_CTX_free(ctx);
if (out)
@@ -510,18 +779,15 @@ static int FIPS_cmac_aes256_test()
out = OPENSSL_malloc(outlen);
if (!CMAC_Final(ctx, out, &outlen))
goto end;
#if 0
{
char *hexout = OPENSSL_malloc(outlen * 2 + 1);
bin2hex(out, outlen, hexout);
printf("CMAC-AES256: res = %s\n", hexout);
OPENSSL_free(hexout);
}
r = 1;
#else
if (!memcmp(out,kaval,outlen))
r = 1;
#endif
if (verbose)
{
do_print_buf("CMAC key", key, sizeof(key));
do_print_buf("CMAC input", data, sizeof(data) -1);
do_print_buf("CMAC output", out, outlen);
printf("CMAC comparison %s\n", r == 1 ? "successful." : "Failed!!");
}
end:
CMAC_CTX_free(ctx);
if (out)
@@ -560,18 +826,15 @@ static int FIPS_cmac_tdea3_test()
out = OPENSSL_malloc(outlen);
if (!CMAC_Final(ctx, out, &outlen))
goto end;
#if 0
{
char *hexout = OPENSSL_malloc(outlen * 2 + 1);
bin2hex(out, outlen, hexout);
printf("CMAC-TDEA3: res = %s\n", hexout);
OPENSSL_free(hexout);
}
r = 1;
#else
if (!memcmp(out,kaval,outlen))
r = 1;
#endif
if (verbose)
{
do_print_buf("CMAC key", key, sizeof(key));
do_print_buf("CMAC input", data, sizeof(data) -1);
do_print_buf("CMAC output", out, outlen);
printf("CMAC comparison %s\n", r == 1 ? "successful." : "Failed!!");
}
end:
CMAC_CTX_free(ctx);
if (out)
@@ -627,7 +890,11 @@ static int Zeroize()
for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
printf("\n");
RAND_bytes(userkey, sizeof userkey);
printf("\tchar buffer key after overwriting: \n\t\t");
printf("\tchar buffer key after overwriting with random key: \n\t\t");
for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
printf("\n");
OPENSSL_cleanse(userkey, sizeof(userkey));
printf("\tchar buffer key after zeroization: \n\t\t");
for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
printf("\n");
@@ -747,9 +1014,13 @@ static const char * Fail(const char *msg)
return msg;
}
static void test_msg(const char *msg, int result)
{
printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
#define test_msg(msg, rtest) \
{ \
int rv; \
if (verbose) \
printf("%s...started\n", msg); \
rv = rtest; \
printf("%s...%s\n", msg, rv ? "successful" : Fail("Failed!")); \
}
/* Table of IDs for POST translating between NIDs and names */
@@ -810,13 +1081,15 @@ static const char *lookup_id(int id)
static int fail_id = -1;
static int fail_sub = -1;
static int fail_key = -1;
static int sub_num = -1, sub_count = -1;
static int sub_fail_num = -1;
static int st_err, post_quiet = 0;
static int post_cb(int op, int id, int subid, void *ex)
{
const char *idstr, *exstr = "";
char asctmp[20];
char asctmp[20], teststr[80];
int keytype = -1;
int exp_fail = 0;
#ifdef FIPS_POST_TIME
@@ -935,6 +1208,16 @@ static int post_cb(int op, int id, int subid, void *ex)
&& (fail_sub == -1 || fail_sub == subid))
exp_fail = 1;
if (sub_num > 0)
{
if (sub_fail_num == sub_num)
exp_fail = 1;
sprintf(teststr, "\t\t%s %s (POST subtest #%d) test",
idstr, exstr, sub_num);
}
else
sprintf(teststr, "\t\t%s %s test", idstr, exstr);
switch(op)
{
case FIPS_POST_BEGIN:
@@ -945,9 +1228,16 @@ static int post_cb(int op, int id, int subid, void *ex)
clock_gettime(CLOCK_REALTIME, &tstart);
#endif
printf("\tPOST started\n");
sub_num = 1;
break;
case FIPS_POST_END:
if (sub_count == -1)
sub_count = sub_num;
else if (sub_num != sub_count)
printf("Inconsistent POST count %d != %d\n",
sub_num, sub_count);
sub_num = -1;
printf("\tPOST %s\n", id ? "Success" : "Failed");
#ifdef FIPS_POST_TIME
clock_gettime(CLOCK_REALTIME, &tend);
@@ -959,21 +1249,22 @@ static int post_cb(int op, int id, int subid, void *ex)
case FIPS_POST_STARTED:
if (!post_quiet && !exp_fail)
printf("\t\t%s %s test started\n", idstr, exstr);
printf("%s started\n", teststr);
#ifdef FIPS_POST_TIME
clock_gettime(CLOCK_REALTIME, &start);
#endif
break;
case FIPS_POST_SUCCESS:
if (sub_num > 0)
sub_num++;
if (exp_fail)
{
printf("\t\t%s %s test OK but should've failed\n",
idstr, exstr);
printf("%s OK but should've failed\n", teststr);
st_err++;
}
else if (!post_quiet)
printf("\t\t%s %s test OK\n", idstr, exstr);
printf("%s OK\n", teststr);
#ifdef FIPS_POST_TIME
clock_gettime(CLOCK_REALTIME, &end);
printf("\t\t\tTook %f seconds\n",
@@ -983,15 +1274,13 @@ static int post_cb(int op, int id, int subid, void *ex)
break;
case FIPS_POST_FAIL:
if (sub_num > 0)
sub_num++;
if (exp_fail)
{
printf("\t\t%s %s test failed as expected\n",
idstr, exstr);
}
printf("%s failed as expected\n", teststr);
else
{
printf("\t\t%s %s test Failed Incorrectly!!\n",
idstr, exstr);
printf("%s Failed Incorrectly!!\n", teststr);
st_err++;
}
break;
@@ -999,7 +1288,7 @@ static int post_cb(int op, int id, int subid, void *ex)
case FIPS_POST_CORRUPT:
if (exp_fail)
{
printf("\t\t%s %s test failure induced\n", idstr, exstr);
printf("%s failure induced\n", teststr);
return 0;
}
break;
@@ -1008,63 +1297,48 @@ static int post_cb(int op, int id, int subid, void *ex)
return 1;
}
/* Test POST induced failures */
typedef struct
{
const char *name;
int id, subid, keyid;
} fail_list;
static fail_list flist[] =
{
{"Integrity", FIPS_TEST_INTEGRITY, -1, -1},
{"AES", FIPS_TEST_CIPHER, NID_aes_128_ecb, -1},
{"DES3", FIPS_TEST_CIPHER, NID_des_ede3_ecb, -1},
{"AES-GCM", FIPS_TEST_GCM, -1, -1},
{"AES-CCM", FIPS_TEST_CCM, -1, -1},
{"AES-XTS", FIPS_TEST_XTS, -1, -1},
{"Digest", FIPS_TEST_DIGEST, -1, -1},
{"HMAC", FIPS_TEST_HMAC, -1, -1},
{"CMAC", FIPS_TEST_CMAC, -1, -1},
{"DRBG", FIPS_TEST_DRBG, -1, -1},
{"X9.31 PRNG", FIPS_TEST_X931, -1, -1},
{"RSA", FIPS_TEST_SIGNATURE, -1, EVP_PKEY_RSA},
{"DSA", FIPS_TEST_SIGNATURE, -1, EVP_PKEY_DSA},
{"ECDSA", FIPS_TEST_SIGNATURE, -1, EVP_PKEY_EC},
{"ECDH", FIPS_TEST_ECDH, -1, -1},
{NULL, -1, -1, -1}
};
static int do_fail_all(int fullpost, int fullerr)
{
fail_list *ftmp;
int rv;
size_t i;
int sub_fail;
RSA *rsa = NULL;
DSA *dsa = NULL;
DRBG_CTX *dctx = NULL, *defctx = NULL;
EC_KEY *ec = NULL;
BIGNUM *bn = NULL;
unsigned char key[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
EVP_CIPHER_CTX ctx;
unsigned char out[10];
if (!fullpost)
post_quiet = 1;
if (!fullerr)
no_err = 1;
FIPS_module_mode_set(0, NULL);
for (ftmp = flist; ftmp->name; ftmp++)
fips_module_mode_set_verbose(0, NULL);
for (sub_fail = 1; sub_fail < sub_count; sub_fail++)
{
printf(" Testing induced failure of %s test\n", ftmp->name);
fail_id = ftmp->id;
fail_sub = ftmp->subid;
fail_key = ftmp->keyid;
rv = FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS);
sub_fail_num = sub_fail;
printf(" Testing induced failure of POST subtest %d\n",
sub_fail);
rv = fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS);
if (rv)
{
printf("\tFIPS mode incorrectly successful!!\n");
st_err++;
}
printf("\tAttempting crypto operation after failed POST... ");
FIPS_cipher_ctx_init(&ctx);
rv = FIPS_cipherinit(&ctx, EVP_aes_128_ecb(), key, NULL, 1);
if (rv > 0)
{
printf("succeeded incorrectly!!\n");
st_err++;
}
else
printf("failed as expected.\n");
FIPS_cipher_ctx_cleanup(&ctx);
}
sub_fail_num = -1;
printf(" Testing induced failure of RSA keygen test\n");
/* NB POST will succeed with a pairwise test failures as
* it is not used during POST.
@@ -1072,7 +1346,7 @@ static int do_fail_all(int fullpost, int fullerr)
fail_id = FIPS_TEST_PAIRWISE;
fail_key = EVP_PKEY_RSA;
/* Now enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1092,12 +1366,12 @@ static int do_fail_all(int fullpost, int fullerr)
printf("\tRSA key generation failed as expected.\n");
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
printf(" Testing induced failure of DSA keygen test\n");
fail_key = EVP_PKEY_DSA;
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1116,9 +1390,9 @@ static int do_fail_all(int fullpost, int fullerr)
printf("\tDSA key generation failed as expected.\n");
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1147,9 +1421,9 @@ static int do_fail_all(int fullpost, int fullerr)
fail_sub = -1;
fail_key = -1;
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1182,9 +1456,9 @@ static int do_fail_all(int fullpost, int fullerr)
FIPS_drbg_stick(0);
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1212,9 +1486,9 @@ static int do_fail_all(int fullpost, int fullerr)
else
printf("\tDRBG continuous PRNG entropy failed as expected\n");
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1222,9 +1496,9 @@ static int do_fail_all(int fullpost, int fullerr)
FIPS_drbg_free(dctx);
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1252,9 +1526,9 @@ static int do_fail_all(int fullpost, int fullerr)
FIPS_x931_stick(0);
/* Leave FIPS mode to clear error */
FIPS_module_mode_set(0, NULL);
fips_module_mode_set_verbose(0, NULL);
/* Enter FIPS mode successfully */
if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
if (!fips_module_mode_set_verbose(1, FIPS_AUTH_USER_PASS))
{
printf("\tError entering FIPS mode\n");
st_err++;
@@ -1337,6 +1611,12 @@ int main(int argc, char **argv)
FIPS_post_set_callback(post_cb);
#if (defined(__arm__) || defined(__aarch64__))
extern unsigned int OPENSSL_armcap_P;
if (0 == OPENSSL_armcap_P)
fprintf(stderr, "Optimizations disabled\n");
#endif
printf("\tFIPS-mode test application\n");
printf("\t%s\n\n", FIPS_module_version_text());
@@ -1426,6 +1706,9 @@ int main(int argc, char **argv)
} else if (!strcmp(*args, "fullerr")) {
fullerr = 1;
no_exit = 1;
} else if (!strcmp(*args, "verbose")) {
verbose = 1;
no_exit = 1;
} else {
printf("Bad argument \"%s\"\n", *args);
return 1;
@@ -1435,7 +1718,7 @@ int main(int argc, char **argv)
if ((argc != 1) && !no_exit) {
fips_algtest_init_nofips();
if (!FIPS_module_mode_set(1, pass)) {
if (!fips_module_mode_set_verbose(1, pass)) {
printf("Power-up self test failed\n");
return 1;
}
@@ -1456,7 +1739,7 @@ int main(int argc, char **argv)
/* Power-up self test
*/
ERR_clear_error();
test_msg("2. Automatic power-up self test", FIPS_module_mode_set(1, pass));
test_msg("2a. Automatic power-up self test", fips_module_mode_set_verbose(1, pass));
if (!FIPS_module_mode())
return 1;
if (do_drbg_stick)
@@ -1464,6 +1747,8 @@ int main(int argc, char **argv)
if (do_rng_stick)
FIPS_x931_stick(1);
test_msg("2b. On demand self test", FIPS_selftest());
/* AES encryption/decryption
*/
test_msg("3a. AES encryption/decryption", FIPS_aes_test());
@@ -1564,7 +1849,10 @@ int main(int argc, char **argv)
printf("\t%s\n", do_drbg_all() ? "successful as expected"
: Fail("failed INCORRECTLY!") );
printf("13. Induced test failure check...\n");
test_msg("13. ECDSA key generation and signature validation",
FIPS_ecdsa_test());
printf("14. Induced test failure check...\n");
printf("\t%s\n", do_fail_all(fullpost, fullerr) ? "successful as expected"
: Fail("failed INCORRECTLY!") );
printf("\nAll tests completed with %d errors\n", Error);

View File

@@ -668,6 +668,50 @@
#define bn_mul_mont_gather5 fips_bn_mul_mont_gather5
#define bn_scatter5 fips_bn_scatter5
#define bn_gather5 fips_bn_gather5
#define _armv8_aes_probe _fips_armv8_aes_probe
#define _armv8_pmull_probe _fips_armv8_pmull_probe
#define _armv8_sha1_probe _fips_armv8_sha1_probe
#define _armv8_sha256_probe _fips_armv8_sha256_probe
#define aes_v8_encrypt fips_aes_v8_encrypt
#define aes_v8_decrypt fips_aes_v8_decrypt
#define aes_v8_set_encrypt_key fips_aes_v8_set_encrypt_key
#define aes_v8_set_decrypt_key fips_aes_v8_set_decrypt_key
#define aes_v8_cbc_encrypt fips_aes_v8_cbc_encrypt
#define aes_v8_ctr32_encrypt_blocks fips_aes_v8_ctr32_encrypt_blocks
#define gcm_init_v8 fips_gcm_init_v8
#define gcm_gmult_v8 fips_gcm_gmult_v8
#define gcm_ghash_v8 fips_gcm_ghash_v8
#if defined(__APPLE__) && __ASSEMBLER__
#define _OPENSSL_armcap_P _fips_openssl_armcap_P
#define __armv7_neon_probe __fips_armv7_neon_probe
#define __armv7_tick __fips_armv7_tick
#define __armv8_aes_probe __fips_armv8_aes_probe
#define __armv8_pmull_probe __fips_armv8_pmull_probe
#define __armv8_sha1_probe __fips_armv8_sha1_probe
#define __armv8_sha256_probe __fips_armv8_sha256_probe
#define _aes_v8_encrypt _fips_aes_v8_encrypt
#define _aes_v8_decrypt _fips_aes_v8_decrypt
#define _aes_v8_set_encrypt_key _fips_aes_v8_set_encrypt_key
#define _aes_v8_set_decrypt_key _fips_aes_v8_set_decrypt_key
#define _aes_v8_cbc_encrypt _fips_aes_v8_cbc_encrypt
#define _aes_v8_ctr32_encrypt_blocks _fips_aes_v8_ctr32_encrypt_blocks
#define _gcm_init_v8 _fips_gcm_init_v8
#define _gcm_gmult_v8 _fips_gcm_gmult_v8
#define _gcm_ghash_v8 _fips_gcm_ghash_v8
#define _sha1_block_data_order _fips_sha1_block_data_order
#define _sha256_block_data_order _fips_sha256_block_data_order
#define _sha512_block_data_order _fips_sha512_block_data_order
#define _AES_decrypt _fips_aes_decrypt
#define _AES_encrypt _fips_aes_encrypt
#define _AES_set_decrypt_key _fips_aes_set_decrypt_key
#define _AES_set_encrypt_key _fips_aes_set_encrypt_key
#define _gcm_gmult_4bit _fips_gcm_gmult_4bit
#define _gcm_ghash_4bit _fips_gcm_ghash_4bit
#define _gcm_gmult_neon _fips_gcm_gmult_neon
#define _gcm_ghash_neon _fips_gcm_ghash_neon
#define _bn_GF2m_mul_2x2 _fips_bn_GF2m_mul_2x2
#define _OPENSSL_cleanse _FIPS_openssl_cleanse
#endif
#if defined(_MSC_VER)
# pragma const_seg("fipsro$b")

View File

@@ -288,8 +288,11 @@ int FIPS_rsa_sign_digest(RSA *rsa, const unsigned char *md, int md_len,
*siglen=j;
}
psserr:
if (sbuf)
{
OPENSSL_cleanse(sbuf, i);
OPENSSL_free(sbuf);
}
return ret;
}

View File

@@ -30,7 +30,8 @@ LIB=$(TOP)/libcrypto.a
LIBSRC=fips_sha1_selftest.c
LIBOBJ=fips_sha1_selftest.o
SRC= $(LIBSRC) fips_standalone_sha1.c
SRC= $(LIBSRC)
PROGS= fips_standalone_sha1.c
EXHEADER=
HEADER=

76
iOS/Makefile Normal file
View File

@@ -0,0 +1,76 @@
#
# OpenSSL/iOS/Makefile
#
DIR= iOS
TOP= ..
CC= cc
INCLUDES= -I$(TOP) -I$(TOP)/include
CFLAG= -g -static
MAKEFILE= Makefile
PERL= perl
RM= rm -f
EXE=incore_macho
CFLAGS= $(INCLUDES) $(CFLAG)
top:
@$(MAKE) -f $(TOP)/Makefile reflect THIS=exe
exe: fips_algvs.app/fips_algvs
incore_macho: incore_macho.c $(TOP)/crypto/sha/sha1dgst.c
$(HOSTCC) $(HOSTCFLAGS) -I$(TOP)/include -I$(TOP)/crypto -o $@ incore_macho.c $(TOP)/crypto/sha/sha1dgst.c
fips_algvs.app/fips_algvs: $(TOP)/test/fips_algvs.c $(TOP)/fips/fipscanister.o fopen.m incore_macho
FIPS_SIG=./incore_macho \
$(TOP)/fips/fipsld $(CFLAGS) -I$(TOP)/fips -o $@ \
$(TOP)/test/fips_algvs.c $(TOP)/fips/fipscanister.o \
fopen.m -framework Foundation || rm $@
codesign -f -s "iPhone Developer" --entitlements fips_algvs.app/Entitlements.plist fips_algvs.app || rm $@
install:
@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
@set -e; for i in $(EXE); \
do \
(echo installing $$i; \
cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
done;
@set -e; for i in $(SCRIPTS); \
do \
(echo installing $$i; \
cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
done
tags:
ctags $(SRC)
tests:
links:
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
depend:
@if [ -z "$(THIS)" ]; then \
$(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
else \
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(SRC); \
fi
dclean:
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
mv -f Makefile.new $(MAKEFILE)
clean:
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
rm -f fips_algvs.app/fips_algvs
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>get-task-allow</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>fips_algvs</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleExecutable</key>
<string>fips_algvs</string>
<key>CFBundleIdentifier</key>
<string>fips_algvs</string>
<key>CFBundleResourceSpecification</key>
<string>ResourceRules.plist</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>CFBundleDisplayName</key>
<string>fips_algvs</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>rules</key>
<dict>
<key>.*</key>
<true/>
<key>Info.plist</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>ResourceRules.plist</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>100</real>
</dict>
</dict>
</dict>
</plist>

93
iOS/fopen.m Normal file
View File

@@ -0,0 +1,93 @@
#include <stdio.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <Foundation/Foundation.h>
static FILE *(*libc_fopen)(const char *, const char *) = NULL;
__attribute__((constructor))
static void pre_main(void)
{
/*
* Pull reference to fopen(3) from libc.
*/
void *handle = dlopen("libSystem.B.dylib",RTLD_LAZY);
if (handle) {
libc_fopen = dlsym(handle,"fopen");
dlclose(handle);
}
/*
* Change to Documents directory.
*/
NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSFileManager *filemgr = [NSFileManager defaultManager];
[filemgr changeCurrentDirectoryPath: docs];
[filemgr release];
}
char *mkdirhier(char *path)
{
char *slash;
struct stat buf;
if (path[0]=='.' && path[1]=='/') path+=2;
if ((slash = strrchr(path,'/'))) {
*slash = '\0';
if (stat(path,&buf)==0) {
*slash = '/';
return NULL;
}
(void)mkdirhier(path);
mkdir (path,0777);
*slash = '/';
}
return slash;
}
/*
* Replacement fopen(3)
*/
FILE *fopen(const char *filename, const char *mode)
{
FILE *ret;
if ((ret = (*libc_fopen)(filename,mode)) == NULL) {
/*
* If file is not present in Documents directory, try from Bundle.
*/
NSString *nsspath = [NSString stringWithFormat:@"%@/%s",
[[NSBundle mainBundle] bundlePath],
filename];
if ((ret = (*libc_fopen)([nsspath cStringUsingEncoding:NSUTF8StringEncoding],mode)) == NULL &&
mode[0]=='w' &&
((filename[0]!='.' && filename[0]!='/') ||
(filename[0]=='.' && filename[1]=='/')) ) {
/*
* If not present in Bundle, create directory in Documents
*/
char *path = strdup(filename), *slash;
static int once = 1;
if ((slash = mkdirhier(path)) && once) {
/*
* For some reason iOS truncates first created file
* upon program exit, so we create one preemptively...
*/
once = 0;
strcpy(slash,"/.0");
creat(path,0444);
}
free(path);
ret = (*libc_fopen)(filename,mode);
}
}
return ret;
}

1016
iOS/incore_macho.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,7 @@ PERL= perl
# KRB5 stuff
KRB5_INCLUDES=
LIBKRB5=
TEST= fips_algvs.c
PEX_LIBS=
EX_LIBS= #-lnsl -lsocket

View File

@@ -70,6 +70,67 @@ int main(int argc, char **argv)
}
#else
#if defined(__vxworks)
#include <taskLibCommon.h>
#include <string.h>
int fips_algvs_main(int argc, char **argv);
#define main fips_algvs_main
static int fips_algvs_argv(char *a0)
{
char *argv[32] = { "fips_algvs" };
int argc = 1;
int main_ret;
if (a0) {
char *scan = a0, *arg = a0;
while (*scan) {
if (*scan++ == ' ') {
scan[-1] = '\0';
argv[argc++] = arg;
if (argc == (sizeof(argv)/sizeof(argv[0])-1))
break;
while (*scan == ' ') scan++;
arg = scan;
}
}
if (*scan == '\0') argv[argc++] = arg;
}
argv[argc] = NULL;
main_ret = fips_algvs_main(argc, argv);
if (a0) free(a0);
return main_ret;
}
int fips_algvs(int a0)
{
return taskSpawn("fips_algvs", 100, (VX_FP_TASK | VX_SPE_TASK), 100000,
(FUNCPTR)fips_algvs_argv,
a0 ? strdup(a0) : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
static FILE *fips_fopen(const char *path, const char *mode)
{
char fips_path [256];
if (path[0] != '/' && strlen(path) < (sizeof(fips_path)-8)) {
strcpy(fips_path,"/fips0/");
strcat(fips_path,path);
return fopen(fips_path,mode);
}
return fopen(path,mode);
}
#define fopen fips_fopen
#endif
#define FIPS_ALGVS
extern int fips_aesavs_main(int argc, char **argv);
@@ -265,6 +326,16 @@ int main(int argc, char **argv)
SysInit();
#endif
#if (defined(__arm__) || defined(__aarch64__))
if (*args && !strcmp(*args, "-noaccel"))
{
extern unsigned int OPENSSL_armcap_P;
OPENSSL_armcap_P=0;
args++;
argc--;
}
#endif
if (*args && *args[0] != '-')
{
rv = run_prg(argc - 1, args);

View File

@@ -27,33 +27,30 @@ if (exists $ENV{"PREMAIN_DSO_EXE"})
$fips_premain_dso = "";
}
my $fips_sig = $ENV{"FIPS_SIG"};
if (defined $fips_sig)
{
if ($fips_premain_dso ne "")
{
$fips_premain_dso = "$fips_sig -dso";
}
else
{
$fips_premain_dso = "$fips_sig -exe";
}
}
check_hash($sha1_exe, "fips_premain.c");
check_hash($sha1_exe, "fipscanister.lib");
print "Integrity check OK\n";
if (is_premain_linked(@ARGV)) {
print "$fips_cc $fips_cc_args $fips_libdir/fips_premain.c\n";
system "$fips_cc $fips_cc_args $fips_libdir/fips_premain.c";
die "First stage Compile failure" if $? != 0;
} elsif (!defined($ENV{FIPS_SIG})) {
die "no fips_premain.obj linked";
}
print "$fips_link @ARGV\n";
system "$fips_link @ARGV";
die "First stage Link failure" if $? != 0;
if (defined($ENV{FIPS_SIG})) {
print "$ENV{FIPS_SIG} $fips_target\n";
system "$ENV{FIPS_SIG} $fips_target";
die "$ENV{FIPS_SIG} $fips_target failed" if $? != 0;
exit;
}
print "$fips_premain_dso $fips_target\n";
system("$fips_premain_dso $fips_target >$fips_target.sha1");
@@ -74,6 +71,22 @@ print "$fips_link @ARGV\n";
system "$fips_link @ARGV";
die "Second stage Link failure" if $? != 0;
sub is_premain_linked
{
return 1 if (grep /fips_premain\.obj/,@_);
foreach (@_)
{
if (/^@(.*)/ && -f $1)
{
open FD,$1 or die "can't open $1";
my $ret = (grep /fips_premain\.obj/,<FD>)?1:0;
close FD;
return $ret;
}
}
return 0;
}
sub check_hash
{
my ($sha1_exe, $filename) = @_;

View File

@@ -382,7 +382,7 @@ if (!$legacy_mode) {
}
$FINGERPRINT_ascii_value
= $exe->Lookup("FINGERPRINT_ascii_value") or die;
= $exe->Lookup("FINGERPRINT_ascii_value");
}
if ($FIPS_text_startX && $FIPS_text_endX) {
@@ -439,9 +439,12 @@ $fingerprint = FIPS_incore_fingerprint();
if ($legacy_mode) {
print unpack("H*",$fingerprint);
} else {
} elsif (defined($FINGERPRINT_ascii_value)) {
seek(FD,$FINGERPRINT_ascii_value->{st_offset},0) or die "$!";
print FD unpack("H*",$fingerprint) or die "$!";
} else {
seek(FD,$FIPS_signature->{st_offset},0) or die "$!";
print FD $fingerprint or die "$!";
}
close (FD);

View File

@@ -864,13 +864,13 @@ if ($fips)
}
$rules.=&cc_compile_target("\$(OBJ_D)${o}fips_standalone_sha1$obj",
"fips${o}sha${o}fips_standalone_sha1.c",
"\$(SHLIB_CFLAGS)");
"\$(APP_CFLAGS)");
$rules.=&cc_compile_target("\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj",
"fips${o}fips_premain.c",
"-DFINGERPRINT_PREMAIN_DSO_LOAD \$(SHLIB_CFLAGS)");
"-DFINGERPRINT_PREMAIN_DSO_LOAD \$(APP_CFLAGS)");
$rules.=&cc_compile_target("\$(OBJ_D)${o}fips_algvs$obj",
"test${o}fips_algvs.c",
"\$(SHLIB_CFLAGS)");
"\$(APP_CFLAGS)");
}
foreach (values %lib_nam)

View File

@@ -49,8 +49,7 @@ if ($FLAVOR =~ /WIN64/)
# considered safe to ignore.
#
$base_cflags= " $mf_cflag";
my $f = $shlib?' /MD':' /MT';
$lib_cflag='/Zl' if (!$shlib); # remove /DEFAULTLIBs from static lib
my $f = ($shlib and !$fipscanisterbuild)?' /MD':' /MT';
$opt_cflags=$f.' /Ox';
$dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
$lflags="/nologo /subsystem:console /opt:ref";
@@ -127,19 +126,24 @@ elsif ($FLAVOR =~ /CE/)
$base_cflags.=" $wcecdefs";
$base_cflags.=' -I$(WCECOMPAT)/include' if (defined($ENV{'WCECOMPAT'}));
$base_cflags.=' -I$(PORTSDK_LIBPATH)/../../include' if (defined($ENV{'PORTSDK_LIBPATH'}));
$opt_cflags=' /MC /O1i'; # optimize for space, but with intrinsics...
$dbg_clfags=' /MC /Od -DDEBUG -D_DEBUG';
if (`cl 2>&1` =~ /Version 1[4-9]\./) {
$base_cflags.=($shlib and !$fipscanisterbuild)?' /MD':' /MT';
} else {
$base_cflags.=' /MC';
}
$opt_cflags=' /O1i'; # optimize for space, but with intrinsics...
$dbg_cflags=' /Od -DDEBUG -D_DEBUG';
$lflags="/nologo /opt:ref $wcelflag";
}
else # Win32
{
$base_cflags= " $mf_cflag";
my $f = $shlib?' /MD':' /MT';
$lib_cflag='/Zl' if (!$shlib); # remove /DEFAULTLIBs from static lib
my $f = ($shlib and !$fipscanisterbuild)?' /MD':' /MT';
$opt_cflags=$f.' /Ox /O2 /Ob2';
$dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
$lflags="/nologo /subsystem:console /opt:ref";
}
$lib_cflag='/Zl' if (!$shlib or $fipscanisterbuild); # remove /DEFAULTLIBs
$mlflags='';
$out_def ="out32"; $out_def.="dll" if ($shlib);
@@ -284,7 +288,8 @@ elsif ($shlib && $FLAVOR =~ /CE/)
{
$mlflags.=" $lflags /dll";
$lflags.=' /entry:mainCRTstartup' if(defined($ENV{'PORTSDK_LIBPATH'}));
$lib_cflag.=" -D_WINDLL -D_DLL";
$lib_cflag.=" -D_WINDLL";
$lib_cflag.=" -D_DLL" if (!$fipscanisterbuild);
}
sub do_lib_rule