Compare commits

...

55 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
Dr. Stephen Henson
3b4f1f302d update DRBG to handle new file format 2012-10-19 20:53:35 +00:00
Dr. Stephen Henson
986b927fb3 aix[64]-cc: get MT support right (gcc targets are not affected).
(backport from HEAD)
2012-10-16 22:47:44 +00:00
Dr. Stephen Henson
add13802cf Don't require tag before ciphertext in AESGCM mode 2012-10-16 22:47:00 +00:00
Dr. Stephen Henson
b6c1d4b7f0 e_aes.c: uninitialized variable in aes_ccm_init_key.
PR: 2874
Submitted by: Tomas Mraz
(backport from HEAD)
2012-10-15 11:28:59 +00:00
Dr. Stephen Henson
933c9d00da reset ctx->num for CTR mode for FIPS EVP 2012-10-14 12:38:58 +00:00
Dr. Stephen Henson
aaf8b56fc8 sha1-armv4-large.pl: comply with ABI.
(backport from HEAD)
2012-10-14 12:30:12 +00:00
Dr. Stephen Henson
799602e489 gcm128.c: fix AAD-only case with AAD length not divisible by 16.
PR: 2859
Submitted by: John Foley
(backport from HEAD)
2012-10-14 12:29:25 +00:00
Dr. Stephen Henson
82607b291f optimize make_kn (from HEAD, by Andy) 2012-10-14 12:26:02 +00:00
Dr. Stephen Henson
fd9d2eaf16 CMAC reset fix (from HEAD) 2012-10-14 12:24:24 +00:00
Dr. Stephen Henson
3e1beaf43e Add BSD-ppc85xx support and avoid copying overlapping buffers in fips_dssvs.c 2012-10-14 12:03:34 +00:00
Dr. Stephen Henson
ea11fc17cf Add support for Windows CE and C64+ to FIPS module. (from fips2-stable) 2012-10-04 14:27:39 +00:00
Dr. Stephen Henson
05b751c96b file TI_CGTOOLS.pl was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:39 +0000 2012-10-04 13:27:12 +00:00
Dr. Stephen Henson
9fe1f397aa file fips_standalone_sha1 was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:38 +0000 2012-10-04 13:27:10 +00:00
Dr. Stephen Henson
be739df6c5 file run6x was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:09 +00:00
Dr. Stephen Henson
d26196803e file incore6x was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:08 +00:00
Dr. Stephen Henson
1c540214e0 file hmac_sha1.pl was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:07 +00:00
Dr. Stephen Henson
79f0c30e7e file fipscanister.cmd was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:06 +00:00
Dr. Stephen Henson
3d75000cc3 file fips_standalone_sha1 was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:05 +00:00
Dr. Stephen Henson
b82ac9947e file env was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:04 +00:00
Dr. Stephen Henson
23c7979fcf file do_fips was added on branch OpenSSL-fips-2_0-dev on 2012-10-04 14:27:33 +0000 2012-10-04 13:27:03 +00:00
Dr. Stephen Henson
88e9264dd2 automatically make output directory is using minimal script 2012-06-07 17:14:31 +00:00
Dr. Stephen Henson
83db979256 Version of "incore" for Windows executables. Original by Andy. 2012-05-23 17:07:23 +00:00
Dr. Stephen Henson
4feb7ef394 Add --script-sfprefix option to insert a prefix before the request and
response filenames in output script.
2012-05-23 12:44:48 +00:00
Dr. Stephen Henson
4972d50da0 add comment 2012-05-23 11:47:01 +00:00
Dr. Stephen Henson
35b412322f fix typo 2012-05-23 11:45:21 +00:00
Dr. Stephen Henson
b75ff26d7b Don't install fips_standalone_sha1.exe if it isn't being built 2012-05-23 00:39:01 +00:00
Dr. Stephen Henson
b440c25d36 Changes needed to support WinCE compilation:
Don't try to raise SIGABRT if not defined.
Return from fips_dhvs.c main instead of calling exit.
Workaround for lack of GetSystemFileAsFileTime.
Disable optimisation for part of bn_nist.c to avoid compiler bug.
Remove /WX flag so we don't exist on warnings.
2012-05-22 23:57:22 +00:00
Dr. Stephen Henson
76f4af202e cross compile target support for do_fips script 2012-05-18 15:55:40 +00:00
Dr. Stephen Henson
fcb81a191d don't insert time in response files: it breaks some systems and we shouldn't be doing this anyway 2012-05-18 15:05:33 +00:00
Dr. Stephen Henson
05703abd9f Make Windows FIPS build work more like other builds. Add build_tests
target to build FIPS test utilities and build_algvs target to build the
multicall fips_algvs utility.
2012-05-17 11:09:46 +00:00
Dr. Stephen Henson
455ecb3a06 initial mk1mf cross compilation support 2012-05-16 18:56:33 +00:00
cvs2svn
d8e5830423 This commit was manufactured by cvs2svn to create branch 'OpenSSL-fips-
2_0-dev'.
2012-01-18 15:07:12 +00:00
90 changed files with 9727 additions and 311 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

24
CHANGES
View File

@@ -4,6 +4,30 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
*) Add perl scripts to calculate FIPS signatures for Windows
exectuables including WinCE.
[Andy Polyakov]
*) Don't attempt to insert current time into AES/3DES tests, we should
be just copying input line across and this breaks some systems lacking
ctime.
[Steve Henson]
*) Update Windows build system for FIPS. Don't compile algorithm test
utilties by default: the target build_tests is needed for that. Add
support for building fips_algvs with the build_algvs target.
[Steve Henson]
*) Add initial cross compilation support for Windows build. The following
environment variables should be set:
FIPS_SHA1_PATH: path to fips_standalone_sha1 exectutable which will
be used explicitly and not built.
FIPS_SIG: similar to other builds: path to a "get signature" script
which is used to obtain the signature of the target instead of
executing it on the host.
[Steve Henson]
*) Add flag to EC_KEY to use cofactor ECDH if set.
[Steve Henson]

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)",
@@ -409,6 +411,8 @@ my %table=(
"BSD-x86-elf", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-BSD-x86-elf", "gcc:-DL_ENDIAN -DTERMIOS -O3 -Wall -g::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"BSD-sparcv8", "gcc:-DB_ENDIAN -DTERMIOS -O3 -mv8 -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${sparcv8_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"BSD-ppc85xx","gcc:-DTERMIOS -O3 -fomit-frame-pointer -msoft-float -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-BSD-ppc85xx","gcc:-DTERMIOS -O0 -fomit-frame-pointer -msoft-float -Wall -g::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"BSD-generic64","gcc:-DTERMIOS -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
# -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
@@ -461,8 +465,8 @@ my %table=(
"aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64",
# Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE
# at build time. $OBJECT_MODE is respected at ./config stage!
"aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
"aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
"aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
#
# Cray T90 and similar (SDSC)
@@ -579,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:::",
@@ -596,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:::::",
@@ -610,12 +631,14 @@ my %table=(
"uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
"uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
"c64xplus","cl6x:-mv6400+ -o2 -ox -ms -pden -DNO_SYS_TYPES_H -DGETPID_IS_MEANINGLESS -DMD32_REG_T=int -DOPENSSL_SMALL_FOOTPRINT:<c6x.h>::DSPBIOS::BN_LLONG:c64xpluscpuid.o:bn-c64xplus.o c64xplus-gf2m.o::aes-c64xplus.o aes_cbc.o aes_ctr.o:::sha1-c64xplus.o sha256-c64xplus.o sha512-c64xplus.o:::::::ghash-c64xplus.o::void:",
);
my @MK1MF_Builds=qw(VC-WIN64I VC-WIN64A
debug-VC-WIN64I debug-VC-WIN64A
VC-NT VC-CE VC-WIN32 debug-VC-WIN32
BC-32
BC-32 c64xplus
netware-clib netware-clib-bsdsock
netware-libc netware-libc-bsdsock);
@@ -1556,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//);
@@ -1577,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";
}

View File

@@ -186,7 +186,7 @@ SHARED_LDFLAGS=
GENERAL= Makefile
BASENAME= openssl
NAME= $(BASENAME)-$(VERSION)
TARFILE= openssl-fips-2.0-test.tar
TARFILE= openssl-fips-2.0.tar
WTARFILE= $(NAME)-win.tar
EXHEADER= e_os2.h
HEADER= e_os.h

40
TABLE
View File

@@ -862,7 +862,7 @@ $multilib =
$cc = cc
$cflags = -q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst
$unistd =
$thread_cflag = -qthreaded
$thread_cflag = -qthreaded -D_THREAD_SAFE
$sys_id = AIX
$lflags =
$bn_ops = BN_LLONG RC4_CHAR
@@ -961,7 +961,7 @@ $multilib =
$cc = cc
$cflags = -q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst
$unistd =
$thread_cflag = -qthreaded
$thread_cflag = -qthreaded -D_THREAD_SAFE
$sys_id = AIX
$lflags =
$bn_ops = SIXTY_FOUR_BIT_LONG RC4_CHAR
@@ -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

7
c6x/do_fips Normal file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
perl Configure c64xplus fipscanisteronly no-engine
perl util/mkfiles.pl > MINFO
perl util/mk1mf.pl auto > c6x/fips.mak
make -f c6x/fips.mak
make -f c6x/fips_algvs.mak

7
c6x/env Normal file
View File

@@ -0,0 +1,7 @@
# MSYS-style PATH
export PATH=/c/CCStudio_v3.3/c6000/cgtools/bin:/c/Program\ Files/ActivePerl58/bin:$PATH
# Windows-style variables
export C6X_C_DIR='C:\CCStudio_v3.3\c6000\cgtools\include;C:\CCStudio_v3.3\c6000\cgtools\lib'
export PERL5LIB=C:/CCStudio_v3.3/bin/utilities/ccs_scripting

32
c6x/fips_standalone_sha1 Normal file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env perl
#
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
unshift(@INC,$dir);
require "hmac_sha1.pl";
(!@ARV[0] && -f @ARGV[$#ARGV]) || die "usage: $0 [-verify] file";
$verify=shift if (@ARGV[0] eq "-verify");
sysopen(FD,@ARGV[0],0) || die "$!";
binmode(FD);
my $ctx = HMAC->Init("etaonrishdlcupfm");
while (read(FD,$blob,4*1024)) { $ctx->Update($blob); }
close(FD);
my $signature = unpack("H*",$ctx->Final());
print "HMAC-SHA1(@ARGV[0])= $signature\n";
if ($verify) {
open(FD,"<@ARGV[0].sha1") || die "$!";
$line = <FD>;
close(FD);
exit(0) if ($line =~ /HMAC\-SHA1\([^\)]*\)=\s*([0-9a-f]+)/i &&
$1 eq $signature);
die "signature mismatch";
}

19
c6x/fipscanister.cmd Normal file
View File

@@ -0,0 +1,19 @@
SECTIONS
{
.text:
{
*(.fips_text:start)
*(.text)
*(.const:aes_asm)
*(.const:sha_asm)
*(.const:des_sptrans)
*(.switch)
*(.fips_text:end)
}
.const:
{
*(.fips_const:start)
*(.const)
*(.fips_const:end)
}
}

196
c6x/hmac_sha1.pl Normal file
View File

@@ -0,0 +1,196 @@
#!/usr/bin/env perl
#
# Copyright (c) 2011 The OpenSSL Project.
#
######################################################################
#
# SHA1 and HMAC in Perl by <appro@openssl.org>.
#
{ package SHA1;
use integer;
{
################################### SHA1 block code generator
my @V = ('$A','$B','$C','$D','$E');
my $i;
sub XUpdate {
my $ret;
$ret="(\$T=\$W[($i-16)%16]^\$W[($i-14)%16]^\$W[($i-8)%16]^\$W[($i-3)%16],\n\t";
if ((1<<31)<<1) {
$ret.=" \$W[$i%16]=((\$T<<1)|(\$T>>31))&0xffffffff)\n\t ";
} else {
$ret.=" \$W[$i%16]=(\$T<<1)|((\$T>>31)&1))\n\t ";
}
}
sub tail {
my ($a,$b,$c,$d,$e)=@V;
my $ret;
if ((1<<31)<<1) {
$ret.="(($a<<5)|($a>>27));\n\t";
$ret.="$b=($b<<30)|($b>>2); $e&=0xffffffff; #$b&=0xffffffff;\n\t";
} else {
$ret.="(($a<<5)|($a>>27)&0x1f);\n\t";
$ret.="$b=($b<<30)|($b>>2)&0x3fffffff;\n\t";
}
$ret;
}
sub BODY_00_15 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=\$W[$i]+0x5a827999+((($c^$d)&$b)^$d)+".tail();
}
sub BODY_16_19 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0x5a827999+((($c^$d)&$b)^$d)+".tail();
}
sub BODY_20_39 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0x6ed9eba1+($b^$c^$d)+".tail();
}
sub BODY_40_59 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0x8f1bbcdc+(($b&$c)|(($b|$c)&$d))+".tail();
}
sub BODY_60_79 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0xca62c1d6+($b^$c^$d)+".tail();
}
my $sha1_impl =
'sub block {
my $self = @_[0];
my @W = unpack("N16",@_[1]);
my ($A,$B,$C,$D,$E,$T) = @{$self->{H}};
';
$sha1_impl.='
$A &= 0xffffffff;
$B &= 0xffffffff;
' if ((1<<31)<<1);
for($i=0;$i<16;$i++){ $sha1_impl.=BODY_00_15(); unshift(@V,pop(@V)); }
for(;$i<20;$i++) { $sha1_impl.=BODY_16_19(); unshift(@V,pop(@V)); }
for(;$i<40;$i++) { $sha1_impl.=BODY_20_39(); unshift(@V,pop(@V)); }
for(;$i<60;$i++) { $sha1_impl.=BODY_40_59(); unshift(@V,pop(@V)); }
for(;$i<80;$i++) { $sha1_impl.=BODY_60_79(); unshift(@V,pop(@V)); }
$sha1_impl.='
$self->{H}[0]+=$A; $self->{H}[1]+=$B; $self->{H}[2]+=$C;
$self->{H}[3]+=$D; $self->{H}[4]+=$E; }';
#print $sha1_impl,"\n";
eval($sha1_impl); # generate code
}
sub Init {
my $class = shift; # multiple instances...
my $self = {};
bless $self,$class;
$self->{H} = [0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0];
$self->{N} = 0;
return $self;
}
sub Update {
my $self = shift;
my $msg;
foreach $msg (@_) {
my $len = length($msg);
my $num = length($self->{buf});
my $off = 0;
$self->{N} += $len;
if (($num+$len)<64)
{ $self->{buf} .= $msg; next; }
elsif ($num)
{ $self->{buf} .= substr($msg,0,($off=64-$num));
$self->block($self->{buf});
}
while(($off+64) <= $len)
{ $self->block(substr($msg,$off,64));
$off += 64;
}
$self->{buf} = substr($msg,$off);
}
return $self;
}
sub Final {
my $self = shift;
my $num = length($self->{buf});
$self->{buf} .= chr(0x80); $num++;
if ($num>56)
{ $self->{buf} .= chr(0)x(64-$num);
$self->block($self->{buf});
$self->{buf}=undef;
$num=0;
}
$self->{buf} .= chr(0)x(56-$num);
$self->{buf} .= pack("N2",($self->{N}>>29)&0x7,$self->{N}<<3);
$self->block($self->{buf});
return pack("N*",@{$self->{H}});
}
sub Selftest {
my $hash;
$hash=SHA1->Init()->Update('abc')->Final();
die "SHA1 test#1" if (unpack("H*",$hash) ne 'a9993e364706816aba3e25717850c26c9cd0d89d');
$hash=SHA1->Init()->Update('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')->Final();
die "SHA1 test#2" if (unpack("H*",$hash) ne '84983e441c3bd26ebaae4aa1f95129e5e54670f1');
#$hash=SHA1->Init()->Update('a'x1000000)->Final();
#die "SHA1 test#3" if (unpack("H*",$hash) ne '34aa973cd4c4daa4f61eeb2bdbad27316534016f');
}
}
{ package HMAC;
sub Init {
my $class = shift;
my $key = shift;
my $self = {};
bless $self,$class;
if (length($key)>64) {
$key = SHA1->Init()->Update($key)->Final();
}
$key .= chr(0x00)x(64-length($key));
my @ikey = map($_^=0x36,unpack("C*",$key));
($self->{hash} = SHA1->Init())->Update(pack("C*",@ikey));
$self->{okey} = pack("C*",map($_^=0x36^0x5c,@ikey));
return $self;
}
sub Update {
my $self = shift;
$self->{hash}->Update(@_);
return $self;
}
sub Final {
my $self = shift;
my $ihash = $self->{hash}->Final();
return SHA1->Init()->Update($self->{okey},$ihash)->Final();
}
sub Selftest {
my $hmac;
$hmac = HMAC->Init('0123456789:;<=>?@ABC')->Update('Sample #2')->Final();
die "HMAC test" if (unpack("H*",$hmac) ne '0922d3405faa3d194f82a45830737d5cc6c75d24');
}
}
1;

241
c6x/incore6x Normal file
View File

@@ -0,0 +1,241 @@
#!/usr/bin/env perl
#
# Copyright (c) 2011 The OpenSSL Project.
#
# The script embeds fingerprint into TI-COFF executable object.
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
unshift(@INC,$dir);
require "hmac_sha1.pl";
######################################################################
#
# COFF symbol table parser by <appro@openssl.org>. The table entries
# are extended with offset within executable file...
#
{ package COFF;
use FileHandle;
sub dup { my %copy=map {$_} @_; return \%copy; }
sub Load {
my $class = shift;
my $self = {};
my $FD = FileHandle->new(); # autoclose
bless $self,$class;
sysopen($FD,shift,0) or die "$!";
binmode($FD);
#################################################
# read and parse COFF header...
#
read($FD,my $coff,22) or die "$!";
my %coff_header;
@coff_header{version,nsects,date,syms_off,nsyms,opt,flags,magic}=
unpack("v2V3v3",$coff);
$!=42; # signal fipsld to revert to two-step link
die "not TI-COFF file" if ($coff_header{version} != 0xC2);
my $big_endian = ($coff_header{flags}>>9)&1; # 0 or 1
my $strings;
my $symsize;
#################################################
# load strings table
#
seek($FD,$coff_header{syms_off}+18*$coff_header{nsyms},0) or die "$!";
read($FD,$strings,4) or die "$!";
$symsize = unpack("V",$strings);
read($FD,$strings,$symsize,4) or die "$!";
#################################################
# read sections
#
my $i;
my @sections;
# seek to section headers
seek($FD,22+@coff_header{opt},0) or die "$!";
for ($i=0;$i<$coff_header{nsects};$i++) {
my %coff_shdr;
my $name;
read($FD,my $section,48) or die "$!";
@coff_shdr{sh_name,sh_phaddr,sh_vaddr,
sh_size,sh_offset,sh_relocs,sh_reserved,
sh_relocoff,sh_lines,sh_flags} =
unpack("a8V9",$section);
$name = $coff_shdr{sh_name};
# see if sh_name is a an offset in $strings
my ($hi,$lo) = unpack("V2",$name);
if ($hi==0 && $lo<$symsize) {
$name = substr($strings,$lo,64);
}
$coff_shdr{sh_name} = (split(chr(0),$name))[0];
push(@sections,dup(%coff_shdr));
}
#################################################
# load symbols table
#
seek($FD,$coff_header{syms_off},0) or die "$!";
for ($i=0;$i<$coff_header{nsyms};$i++) {
my %coff_sym;
my $name;
read($FD,my $blob,18) or die "$!";
@coff_sym{st_name,st_value,st_shndx,reserved,class,aux} =
unpack("a8Vv2C2",$blob);
# skip aux entries
if ($coff_sym{aux}) {
seek($FD,18*$coff_sym{aux},1) or die "$!";
$i+=$coff_sym{aux};
}
$name = $coff_sym{st_name};
# see if st_name is a an offset in $strings
my ($hi,$lo) = unpack("V2",$name);
if ($hi==0 && $lo<$symsize) {
$name = substr($strings,$lo,64);
}
$coff_sym{st_name} = $name = (split(chr(0),$name))[0];
my $st_secn = $coff_sym{st_shndx}-1;
if ($st_secn>=0 && $st_secn<=$#sections
&& @sections[$st_secn]->{sh_offset}
&& $name =~ m/^_[a-z]+/i) {
# synthesize st_offset, ...
$coff_sym{st_offset} = $coff_sym{st_value}
- @sections[$st_secn]->{sh_vaddr}
+ @sections[$st_secn]->{sh_offset};
$coff_sym{st_section} = @sections[$st_secn]->{sh_name};
# ... and add to lookup table
$self->{symbols}{$name} = dup(%coff_sym);
}
}
return $self;
}
sub Lookup {
my $self = shift;
my $name = shift;
return $self->{symbols}{"_$name"};
}
sub Traverse {
my $self = shift;
my $code = shift;
if (ref($code) eq 'CODE') {
for (keys(%{$self->{symbols}})) { &$code($self->{symbols}{$_}); }
}
}
}
######################################################################
#
# main()
#
my $legacy_mode;
if ($#ARGV<0 || ($#ARGV>0 && !($legacy_mode=(@ARGV[0] =~ /^\-(dso|exe)$/)))) {
print STDERR "usage: $0 [-dso|-exe] ti-coff-binary\n";
exit(1);
}
$exe = COFF->Load(@ARGV[$#ARGV]);
$FIPS_text_start = $exe->Lookup("FIPS_text_start") or die;
$FIPS_text_end = $exe->Lookup("FIPS_text_end") or die;
$FIPS_rodata_start = $exe->Lookup("FIPS_rodata_start") or die;
$FIPS_rodata_end = $exe->Lookup("FIPS_rodata_end") or die;
$FIPS_signature = $exe->Lookup("FIPS_signature") or die;
# new cross-compile support
$FIPS_text_startX = $exe->Lookup("FIPS_text_startX");
$FIPS_text_endX = $exe->Lookup("FIPS_text_endX");
if (!$legacy_mode) {
if (!$FIPS_text_startX || !$FIPS_text_endX) {
print STDERR "@ARGV[$#ARGV] is not cross-compiler aware.\n";
exit(42); # signal fipsld to revert to two-step link
}
$FINGERPRINT_ascii_value
= $exe->Lookup("FINGERPRINT_ascii_value");
}
if ($FIPS_text_startX && $FIPS_text_endX) {
$FIPS_text_start = $FIPS_text_startX;
$FIPS_text_end = $FIPS_text_endX;
}
sysopen(FD,@ARGV[$#ARGV],$legacy_mode?0:2) or die "$!"; # 2 is read/write
binmode(FD);
sub HMAC_Update {
my ($hmac,$off,$len) = @_;
my $blob;
seek(FD,$off,0) or die "$!";
read(FD,$blob,$len) or die "$!";
$$hmac->Update($blob);
}
# fips/fips.c:FIPS_incore_fingerprint's Perl twin
#
sub FIPS_incore_fingerprint {
my $p1 = $FIPS_text_start->{st_offset};
my $p2 = $FIPS_text_end->{st_offset};
my $p3 = $FIPS_rodata_start->{st_offset};
my $p4 = $FIPS_rodata_end->{st_offset};
my $sig = $FIPS_signature->{st_offset};
my $ctx = HMAC->Init("etaonrishdlcupfm");
# detect overlapping regions
if ($p1<=$p3 && $p2>=$p3) {
$p3 = $p1; $p4 = $p2>$p4?$p2:$p4; $p1 = 0; $p2 = 0;
} elsif ($p3<=$p1 && $p4>=$p1) {
$p3 = $p3; $p4 = $p2>$p4?$p2:$p4; $p1 = 0; $p2 = 0;
}
if ($p1) {
HMAC_Update (\$ctx,$p1,$p2-$p1);
}
if ($sig>=$p3 && $sig<$p4) {
# "punch" hole
HMAC_Update(\$ctx,$p3,$sig-$p3);
$p3 = $sig+20;
HMAC_Update(\$ctx,$p3,$p4-$p3);
} else {
HMAC_Update(\$ctx,$p3,$p4-$p3);
}
return $ctx->Final();
}
$fingerprint = FIPS_incore_fingerprint();
if ($legacy_mode) {
print unpack("H*",$fingerprint);
} elsif ($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);

43
c6x/run6x Normal file
View File

@@ -0,0 +1,43 @@
#!/usr/bin/env perl
$exe = @ARGV[0];
$exe .= ".out" if (! -f $exe);
die if (! -f $exe);
use CCS_SCRIPTING_PERL;
my $studio=new CCS_SCRIPTING_PERL::CCS_Scripting();
$studio->CCSOpenNamed("*","*",1); # connect to board
$studio->TargetReset();
print "loading $exe\n";
$studio->ProgramLoad($exe);
sub write_string {
my ($studio,$addr,$str) = @_;
my $len = length($str);
my $i;
for ($i=0; $i<$len; $i++) {
$studio->MemoryWrite($CCS_SCRIPTING_PERL::PAGE_DATA,$addr+$i,8,vec($str,$i,8));
}
$studio->MemoryWrite($CCS_SCRIPTING_PERL::PAGE_DATA,$addr+$i,8,0);
return $i+1;
}
$addr= $studio->SymbolGetAddress("__c_args");
printf "setting up __c_args at 0x%X\n",$addr;#\n";
$studio->MemoryWrite($CCS_SCRIPTING_PERL::PAGE_DATA,$addr,32,$#ARGV+1);
for ($i=0,$strings=$addr+($#ARGV+3)*4; $i<=$#ARGV; $i++) {
$off = write_string($studio,$strings,@ARGV[$i]);
$studio->MemoryWrite($CCS_SCRIPTING_PERL::PAGE_DATA,$addr+4*($i+1),32,$strings);
$strings += $off;
}
$studio->MemoryWrite($SCC_SCRIPTING_PERL::PAGE_DATA,$addr+4*($i+1),32,0);
print "running...\n";
$studio->TargetRun();

44
config
View File

@@ -219,7 +219,11 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in
;;
NetBSD:*:*:*386*)
echo "`(/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model) | sed 's,.*\(.\)86-class.*,i\186,'`-whatever-netbsd"; exit 0
if [ -z ${CROSS_COMPILE} ]; then
echo "`(/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model) | sed 's,.*\(.\)86-class.*,i\186,'`-whatever-netbsd"; exit 0
else
echo "${MACHINE}-whatever-netbsd"; exit 0
fi
;;
NetBSD:*)
@@ -371,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;
;;
@@ -572,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
@@ -597,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" ;;
@@ -734,17 +747,23 @@ case "$GUESSOS" in
sparc64-*-*bsd*) OUT="BSD-sparc64" ;;
ia64-*-*bsd*) OUT="BSD-ia64" ;;
amd64-*-*bsd*) OUT="BSD-x86_64" ;;
*86*-*-*bsd*) # mimic ld behaviour when it's looking for libc...
if [ -L /usr/lib/libc.so ]; then # [Free|Net]BSD
libc=/usr/lib/libc.so
else # OpenBSD
# ld searches for highest libc.so.* and so do we
libc=`(ls /usr/lib/libc.so.* | tail -1) 2>/dev/null`
fi
case "`(file -L $libc) 2>/dev/null`" in
*ELF*) OUT="BSD-x86-elf" ;;
*) OUT="BSD-x86"; options="$options no-sse2" ;;
esac ;;
*86*-*-*bsd*) if [ -z ${CROSS_COMPILE} ]; then
# mimic ld behaviour when it's looking for libc...
if [ -L /usr/lib/libc.so ]; then # [Free|Net]BSD
libc=/usr/lib/libc.so
else # OpenBSD
# ld searches for highest libc.so.* and so do we
libc=`(ls /usr/lib/libc.so.* | tail -1) 2>/dev/null`
fi
echo "libc = $libc"
case "`(file -L $libc) 2>/dev/null`" in
*ELF*) OUT="BSD-x86-elf" ;;
*) OUT="BSD-x86"; options="$options no-sse2" ;;
esac
else
OUT="BSD-x86-elf"
fi;;
ppc85xx-*-*bsd*) OUT="BSD-ppc85xx" ;; # MPC85XX has no hardware FP accelerator
*-*-*bsd*) OUT="BSD-generic32" ;;
*-*-osf) OUT="osf1-alpha-cc" ;;
@@ -842,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+$/)) {}
open STDOUT,">$output";
$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...

File diff suppressed because it is too large Load Diff

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+$/)) {}
open STDOUT,">$output";
$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+$/)) {}
open STDOUT,">$output";
$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

@@ -0,0 +1,333 @@
;;====================================================================
;; Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
;; project.
;;
;; Rights for redistribution and usage in source and binary forms are
;; granted according to the OpenSSL license. Warranty of any kind is
;; disclaimed.
;;====================================================================
;; Compiler-generated multiply-n-add SPLOOP runs at 12*n cycles, n
;; being the number of 32-bit words, addition - 8*n. Corresponding 4x
;; unrolled SPLOOP-free loops - at ~8*n and ~5*n. Below assembler
;; SPLOOPs spin at ... 2*n cycles [plus epilogue].
;;====================================================================
.text
.asg B3,RA
.asg A4,ARG0
.asg B4,ARG1
.asg A6,ARG2
.asg B6,ARG3
.asg A8,ARG4
.asg B8,ARG5
.asg A4,RET
.asg A15,FP
.asg B14,DP
.asg B15,SP
.global _bn_mul_add_words
_bn_mul_add_words:
.asmfunc
MV ARG2,B0
[!B0] BNOP RA
||[!B0] MVK 0,RET
[B0] MVC B0,ILC
[B0] ZERO A19 ; high part of accumulator
|| [B0] MV ARG0,A2
|| [B0] MV ARG3,A3
NOP 3
SPLOOP 2 ; 2*n+10
;;====================================================================
LDW *ARG1++,B7 ; ap[i]
NOP 3
LDW *ARG0++,A7 ; rp[i]
MPY32U B7,A3,A17:A16
NOP 3 ; [2,0] in epilogue
ADDU A16,A7,A21:A20
ADDU A19,A21:A20,A19:A18
|| MV.S A17,A23
SPKERNEL 2,1 ; leave slot for "return value"
|| STW A18,*A2++ ; rp[i]
|| ADD A19,A23,A19
;;====================================================================
BNOP RA,4
MV A19,RET ; return value
.endasmfunc
.global _bn_mul_words
_bn_mul_words:
.asmfunc
MV ARG2,B0
[!B0] BNOP RA
||[!B0] MVK 0,RET
[B0] MVC B0,ILC
[B0] ZERO A19 ; high part of accumulator
NOP 3
SPLOOP 2 ; 2*n+10
;;====================================================================
LDW *ARG1++,A7 ; ap[i]
NOP 4
MPY32U A7,ARG3,A17:A16
NOP 4 ; [2,0] in epiloque
ADDU A19,A16,A19:A18
|| MV.S A17,A21
SPKERNEL 2,1 ; leave slot for "return value"
|| STW A18,*ARG0++ ; rp[i]
|| ADD.L A19,A21,A19
;;====================================================================
BNOP RA,4
MV A19,RET ; return value
.endasmfunc
.global _bn_sqr_words
_bn_sqr_words:
.asmfunc
MV ARG2,B0
[!B0] BNOP RA
||[!B0] MVK 0,RET
[B0] MVC B0,ILC
[B0] MV ARG0,B2
|| [B0] ADD 4,ARG0,ARG0
NOP 3
SPLOOP 2 ; 2*n+10
;;====================================================================
LDW *ARG1++,B7 ; ap[i]
NOP 4
MPY32U B7,B7,B1:B0
NOP 3 ; [2,0] in epilogue
STW B0,*B2++(8) ; rp[2*i]
MV B1,A1
SPKERNEL 2,0 ; fully overlap BNOP RA,5
|| STW A1,*ARG0++(8) ; rp[2*i+1]
;;====================================================================
BNOP RA,5
.endasmfunc
.global _bn_add_words
_bn_add_words:
.asmfunc
MV ARG3,B0
[!B0] BNOP RA
||[!B0] MVK 0,RET
[B0] MVC B0,ILC
[B0] ZERO A1 ; carry flag
|| [B0] MV ARG0,A3
NOP 3
SPLOOP 2 ; 2*n+6
;;====================================================================
LDW *ARG2++,A7 ; bp[i]
|| LDW *ARG1++,B7 ; ap[i]
NOP 4
ADDU A7,B7,A9:A8
ADDU A1,A9:A8,A1:A0
SPKERNEL 0,0 ; fully overlap BNOP RA,5
|| STW A0,*A3++ ; write result
|| MV A1,RET ; keep carry flag in RET
;;====================================================================
BNOP RA,5
.endasmfunc
.global _bn_sub_words
_bn_sub_words:
.asmfunc
MV ARG3,B0
[!B0] BNOP RA
||[!B0] MVK 0,RET
[B0] MVC B0,ILC
[B0] ZERO A2 ; borrow flag
|| [B0] MV ARG0,A3
NOP 3
SPLOOP 2 ; 2*n+6
;;====================================================================
LDW *ARG2++,A7 ; bp[i]
|| LDW *ARG1++,B7 ; ap[i]
NOP 4
SUBU B7,A7,A1:A0
[A2] SUB A1:A0,1,A1:A0
SPKERNEL 0,1 ; leave slot for "return borrow flag"
|| STW A0,*A3++ ; write result
|| AND 1,A1,A2 ; pass on borrow flag
;;====================================================================
BNOP RA,4
AND 1,A1,RET ; return borrow flag
.endasmfunc
.global _bn_div_words
.global __divull
_bn_div_words:
.asmfunc
CALLP __divull,A3 ; jump to rts64plus.lib
|| MV ARG0,A5
|| MV ARG1,ARG0
|| MV ARG2,ARG1
|| ZERO B5
.endasmfunc
;;====================================================================
;; Not really Comba algorithm, just straightforward NxM... Dedicated
;; fully unrolled real Comba implementations are asymptotically 2x
;; faster, but naturally larger undertaking. Purpose of this exercise
;; was rather to learn to master nested SPLOOPs...
;;====================================================================
.global _bn_sqr_comba8
.global _bn_mul_comba8
_bn_sqr_comba8:
MV ARG1,ARG2
_bn_mul_comba8:
.asmfunc
MVK 8,B0 ; N, RILC
|| MVK 8,A0 ; M, outer loop counter
|| MV ARG1,A5 ; copy ap
|| MV ARG0,B4 ; copy rp
|| ZERO B19 ; high part of accumulator
MVC B0,RILC
|| SUB B0,2,B1 ; N-2, initial ILC
|| SUB B0,1,B2 ; const B2=N-1
|| LDW *A5++,B6 ; ap[0]
|| MV A0,A3 ; const A3=M
sploopNxM?: ; for best performance arrange M<=N
[A0] SPLOOPD 2 ; 2*n+10
|| MVC B1,ILC
|| ADDAW B4,B0,B5
|| ZERO B7
|| LDW *A5++,A9 ; pre-fetch ap[1]
|| ZERO A1
|| SUB A0,1,A0
;;====================================================================
;; SPLOOP from bn_mul_add_words, but with flipped A<>B register files.
;; This is because of Advisory 15 from TI publication SPRZ247I.
LDW *ARG2++,A7 ; bp[i]
NOP 3
[A1] LDW *B5++,B7 ; rp[i]
MPY32U A7,B6,B17:B16
NOP 3
ADDU B16,B7,B21:B20
ADDU B19,B21:B20,B19:B18
|| MV.S B17,B23
SPKERNEL
|| STW B18,*B4++ ; rp[i]
|| ADD.S B19,B23,B19
;;====================================================================
outer?: ; m*2*(n+1)+10
SUBAW ARG2,A3,ARG2 ; rewind bp to bp[0]
SPMASKR
|| CMPGT A0,1,A2 ; done pre-fetching ap[i+1]?
MVD A9,B6 ; move through .M unit(*)
[A2] LDW *A5++,A9 ; pre-fetch ap[i+1]
SUBAW B5,B2,B5 ; rewind rp to rp[1]
MVK 1,A1
[A0] BNOP.S1 outer?,4
|| [A0] SUB.L A0,1,A0
STW B19,*B4--[B2] ; rewind rp tp rp[1]
|| ZERO.S B19 ; high part of accumulator
;; end of outer?
BNOP RA,5 ; return
.endasmfunc
;; (*) It should be noted that B6 is used as input to MPY32U in
;; chronologically next cycle in *preceding* SPLOOP iteration.
;; Normally such arrangement would require DINT, but at this
;; point SPLOOP is draining and interrupts are disabled
;; implicitly.
.global _bn_sqr_comba4
.global _bn_mul_comba4
_bn_sqr_comba4:
MV ARG1,ARG2
_bn_mul_comba4:
.asmfunc
.if 0
BNOP sploopNxM?,3
;; Above mentioned m*2*(n+1)+10 does not apply in n=m=4 case,
;; because of read-after-write penalties, it's rather
;; n*2*(n+3)+10, or 66 cycles [plus various overheads]...
MVK 4,B0 ; N, RILC
|| MVK 4,A0 ; M, outer loop counter
|| MV ARG1,A5 ; copy ap
|| MV ARG0,B4 ; copy rp
|| ZERO B19 ; high part of accumulator
MVC B0,RILC
|| SUB B0,2,B1 ; first ILC
|| SUB B0,1,B2 ; const B2=N-1
|| LDW *A5++,B6 ; ap[0]
|| MV A0,A3 ; const A3=M
.else
;; This alternative is exercise in fully unrolled Comba
;; algorithm implementation that operates at n*(n+1)+12, or
;; as little as 32 cycles...
LDW *ARG1[0],B16 ; a[0]
|| LDW *ARG2[0],A16 ; b[0]
LDW *ARG1[1],B17 ; a[1]
|| LDW *ARG2[1],A17 ; b[1]
LDW *ARG1[2],B18 ; a[2]
|| LDW *ARG2[2],A18 ; b[2]
LDW *ARG1[3],B19 ; a[3]
|| LDW *ARG2[3],A19 ; b[3]
NOP
MPY32U A16,B16,A1:A0 ; a[0]*b[0]
MPY32U A17,B16,A23:A22 ; a[0]*b[1]
MPY32U A16,B17,A25:A24 ; a[1]*b[0]
MPY32U A16,B18,A27:A26 ; a[2]*b[0]
STW A0,*ARG0[0]
|| MPY32U A17,B17,A29:A28 ; a[1]*b[1]
MPY32U A18,B16,A31:A30 ; a[0]*b[2]
|| ADDU A22,A1,A1:A0
MV A23,B0
|| MPY32U A19,B16,A21:A20 ; a[3]*b[0]
|| ADDU A24,A1:A0,A1:A0
ADDU A25,B0,B1:B0
|| STW A0,*ARG0[1]
|| MPY32U A18,B17,A23:A22 ; a[2]*b[1]
|| ADDU A26,A1,A9:A8
ADDU A27,B1,B9:B8
|| MPY32U A17,B18,A25:A24 ; a[1]*b[2]
|| ADDU A28,A9:A8,A9:A8
ADDU A29,B9:B8,B9:B8
|| MPY32U A16,B19,A27:A26 ; a[0]*b[3]
|| ADDU A30,A9:A8,A9:A8
ADDU A31,B9:B8,B9:B8
|| ADDU B0,A9:A8,A9:A8
STW A8,*ARG0[2]
|| ADDU A20,A9,A1:A0
ADDU A21,B9,B1:B0
|| MPY32U A19,B17,A21:A20 ; a[3]*b[1]
|| ADDU A22,A1:A0,A1:A0
ADDU A23,B1:B0,B1:B0
|| MPY32U A18,B18,A23:A22 ; a[2]*b[2]
|| ADDU A24,A1:A0,A1:A0
ADDU A25,B1:B0,B1:B0
|| MPY32U A17,B19,A25:A24 ; a[1]*b[3]
|| ADDU A26,A1:A0,A1:A0
ADDU A27,B1:B0,B1:B0
|| ADDU B8,A1:A0,A1:A0
STW A0,*ARG0[3]
|| MPY32U A19,B18,A27:A26 ; a[3]*b[2]
|| ADDU A20,A1,A9:A8
ADDU A21,B1,B9:B8
|| MPY32U A18,B19,A29:A28 ; a[2]*b[3]
|| ADDU A22,A9:A8,A9:A8
ADDU A23,B9:B8,B9:B8
|| MPY32U A19,B19,A31:A30 ; a[3]*b[3]
|| ADDU A24,A9:A8,A9:A8
ADDU A25,B9:B8,B9:B8
|| ADDU B0,A9:A8,A9:A8
STW A8,*ARG0[4]
|| ADDU A26,A9,A1:A0
ADDU A27,B9,B1:B0
|| ADDU A28,A1:A0,A1:A0
ADDU A29,B1:B0,B1:B0
|| BNOP RA
|| ADDU B8,A1:A0,A1:A0
STW A0,*ARG0[5]
|| ADDU A30,A1,A9:A8
ADD A31,B1,B8
ADDU B0,A9:A8,A9:A8 ; removed || to avoid cross-path stall below
ADD B8,A9,A9
|| STW A8,*ARG0[6]
STW A9,*ARG0[7]
.endif
.endasmfunc

View File

@@ -0,0 +1,146 @@
#!/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/.
# ====================================================================
#
# February 2012
#
# The module implements bn_GF2m_mul_2x2 polynomial multiplication
# used in bn_gf2m.c. It's kind of low-hanging mechanical port from
# C for the time being... The subroutine runs in 37 cycles, which is
# 4.5x faster than compiler-generated code. Though comparison is
# totally unfair, because this module utilizes Galois Field Multiply
# instruction.
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
($rp,$a1,$a0,$b1,$b0)=("A4","B4","A6","B6","A8"); # argument vector
($Alo,$Alox0,$Alox1,$Alox2,$Alox3)=map("A$_",(16..20));
($Ahi,$Ahix0,$Ahix1,$Ahix2,$Ahix3)=map("B$_",(16..20));
($B_0,$B_1,$B_2,$B_3)=("B5","A5","A7","B7");
($A,$B)=($Alo,$B_1);
$xFF="B1";
sub mul_1x1_upper {
my ($A,$B)=@_;
$code.=<<___;
EXTU $B,8,24,$B_2 ; smash $B to 4 bytes
|| AND $B,$xFF,$B_0
|| SHRU $B,24,$B_3
SHRU $A,16, $Ahi ; smash $A to two halfwords
|| EXTU $A,16,16,$Alo
XORMPY $Alo,$B_2,$Alox2 ; 16x8 bits muliplication
|| XORMPY $Ahi,$B_2,$Ahix2
|| EXTU $B,16,24,$B_1
XORMPY $Alo,$B_0,$Alox0
|| XORMPY $Ahi,$B_0,$Ahix0
XORMPY $Alo,$B_3,$Alox3
|| XORMPY $Ahi,$B_3,$Ahix3
XORMPY $Alo,$B_1,$Alox1
|| XORMPY $Ahi,$B_1,$Ahix1
___
}
sub mul_1x1_merged {
my ($OUTlo,$OUThi,$A,$B)=@_;
$code.=<<___;
EXTU $B,8,24,$B_2 ; smash $B to 4 bytes
|| AND $B,$xFF,$B_0
|| SHRU $B,24,$B_3
SHRU $A,16, $Ahi ; smash $A to two halfwords
|| EXTU $A,16,16,$Alo
XOR $Ahix0,$Alox2,$Ahix0
|| MV $Ahix2,$OUThi
|| XORMPY $Alo,$B_2,$Alox2
XORMPY $Ahi,$B_2,$Ahix2
|| EXTU $B,16,24,$B_1
|| XORMPY $Alo,$B_0,A1 ; $Alox0
XOR $Ahix1,$Alox3,$Ahix1
|| SHL $Ahix0,16,$OUTlo
|| SHRU $Ahix0,16,$Ahix0
XOR $Alox0,$OUTlo,$OUTlo
|| XOR $Ahix0,$OUThi,$OUThi
|| XORMPY $Ahi,$B_0,$Ahix0
|| XORMPY $Alo,$B_3,$Alox3
|| SHL $Alox1,8,$Alox1
|| SHL $Ahix3,8,$Ahix3
XOR $Alox1,$OUTlo,$OUTlo
|| XOR $Ahix3,$OUThi,$OUThi
|| XORMPY $Ahi,$B_3,$Ahix3
|| SHL $Ahix1,24,$Alox1
|| SHRU $Ahix1,8, $Ahix1
XOR $Alox1,$OUTlo,$OUTlo
|| XOR $Ahix1,$OUThi,$OUThi
|| XORMPY $Alo,$B_1,$Alox1
|| XORMPY $Ahi,$B_1,$Ahix1
|| MV A1,$Alox0
___
}
sub mul_1x1_lower {
my ($OUTlo,$OUThi)=@_;
$code.=<<___;
;NOP
XOR $Ahix0,$Alox2,$Ahix0
|| MV $Ahix2,$OUThi
NOP
XOR $Ahix1,$Alox3,$Ahix1
|| SHL $Ahix0,16,$OUTlo
|| SHRU $Ahix0,16,$Ahix0
XOR $Alox0,$OUTlo,$OUTlo
|| XOR $Ahix0,$OUThi,$OUThi
|| SHL $Alox1,8,$Alox1
|| SHL $Ahix3,8,$Ahix3
XOR $Alox1,$OUTlo,$OUTlo
|| XOR $Ahix3,$OUThi,$OUThi
|| SHL $Ahix1,24,$Alox1
|| SHRU $Ahix1,8, $Ahix1
XOR $Alox1,$OUTlo,$OUTlo
|| XOR $Ahix1,$OUThi,$OUThi
___
}
$code.=<<___;
.text
.global _bn_GF2m_mul_2x2
_bn_GF2m_mul_2x2:
.asmfunc
MVK 0xFF,$xFF
___
&mul_1x1_upper($a0,$b0); # a0<61>b0
$code.=<<___;
|| MV $b1,$B
MV $a1,$A
___
&mul_1x1_merged("A28","B28",$A,$B); # a0<61>b0/a1<61>b1
$code.=<<___;
|| XOR $b0,$b1,$B
XOR $a0,$a1,$A
___
&mul_1x1_merged("A31","B31",$A,$B); # a1<61>b1/(a0+a1)<29>(b0+b1)
$code.=<<___;
XOR A28,A31,A29
|| XOR B28,B31,B29 ; a0<61>b0+a1<61>b1
___
&mul_1x1_lower("A30","B30"); # (a0+a1)<29>(b0+b1)
$code.=<<___;
|| BNOP B3
XOR A29,A30,A30
|| XOR B29,B30,B30 ; (a0+a1)<29>(b0+b1)-a0<61>b0-a1<61>b1
XOR B28,A30,A30
|| STW A28,*${rp}[0]
XOR B30,A31,A31
|| STW A30,*${rp}[1]
STW A31,*${rp}[2]
STW B31,*${rp}[3]
.endasmfunc
___
print $code;
close STDOUT;

View File

@@ -366,6 +366,10 @@ static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
# endif
#endif /* BN_BITS2 != 64 */
#if defined(_TMS320C6X) && defined(NIST_INT64)
# undef NIST_INT64 /* compiler bug */
# pragma diag_suppress 177
#endif
#define nist_set_192(to, from, a1, a2, a3) \
{ \
@@ -1047,6 +1051,11 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
return 1;
}
#ifdef _WIN32_WCE
/* Workaround for compiler bug under CE */
#pragma optimize( "", off )
#endif
#define BN_NIST_521_RSHIFT (521%BN_BITS2)
#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT)
#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
@@ -1113,6 +1122,10 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
return 1;
}
#ifdef _WIN32_WCE
#pragma optimize( "", on )
#endif
int (*BN_nist_mod_func(const BIGNUM *p))(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
{
if (BN_ucmp(&_bignum_nist_p_192, p) == 0)

246
crypto/c64xpluscpuid.pl Normal file
View File

@@ -0,0 +1,246 @@
#!/usr/bin/env perl
#
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
$code.=<<___;
.text
.asg B3,RA
.global _OPENSSL_rdtsc
_OPENSSL_rdtsc:
.asmfunc
B RA
MVC TSCL,B0
MVC TSCH,B1
[!B0] MVC B0,TSCL ; start TSC
MV B0,A4
MV B1,A5
.endasmfunc
.global _OPENSSL_cleanse
_OPENSSL_cleanse:
.asmfunc
ZERO A3:A2
|| ZERO B2
|| SHRU B4,3,B0 ; is length >= 8
|| ADD 1,A4,B6
[!B0] BNOP RA
|| ZERO A1
|| ZERO B1
[B0] MVC B0,ILC
||[!B0] CMPLT 0,B4,A1
||[!B0] CMPLT 1,B4,B1
[A1] STB A2,*A4++[2]
|| [B1] STB B2,*B6++[2]
||[!B0] CMPLT 2,B4,A1
||[!B0] CMPLT 3,B4,B1
[A1] STB A2,*A4++[2]
|| [B1] STB B2,*B6++[2]
||[!B0] CMPLT 4,B4,A1
||[!B0] CMPLT 5,B4,B1
[A1] STB A2,*A4++[2]
|| [B1] STB B2,*B6++[2]
||[!B0] CMPLT 6,B4,A1
[A1] STB A2,*A4++[2]
SPLOOP 1
STNDW A3:A2,*A4++
|| SUB B4,8,B4
SPKERNEL
MV B4,B0 ; remaining bytes
|| ADD 1,A4,B6
|| BNOP RA
[B0] CMPLT 0,B0,A1
|| [B0] CMPLT 1,B0,B1
[A1] STB A2,*A4++[2]
|| [B1] STB B2,*B6++[2]
|| [B0] CMPLT 2,B0,A1
|| [B0] CMPLT 3,B0,B1
[A1] STB A2,*A4++[2]
|| [B1] STB B2,*B6++[2]
|| [B0] CMPLT 4,B0,A1
|| [B0] CMPLT 5,B0,B1
[A1] STB A2,*A4++[2]
|| [B1] STB B2,*B6++[2]
|| [B0] CMPLT 6,B0,A1
[A1] STB A2,*A4++[2]
.endasmfunc
.global _OPENSSL_atomic_add
_OPENSSL_atomic_add:
.asmfunc
MV A4,B0
atomic_add?:
LL *B0,B5
NOP 4
ADD B4,B5,B5
SL B5,*B0
CMTL *B0,B1
NOP 4
[!B1] B atomic_add?
[B1] BNOP RA,4
MV B5,A4
.endasmfunc
.global _OPENSSL_wipe_cpu
_OPENSSL_wipe_cpu:
.asmfunc
ZERO A0
|| ZERO B0
|| ZERO A1
|| ZERO B1
ZERO A3:A2
|| MVD B0,B2
|| ZERO A4
|| ZERO B4
|| ZERO A5
|| ZERO B5
|| BNOP RA
ZERO A7:A6
|| ZERO B7:B6
|| ZERO A8
|| ZERO B8
|| ZERO A9
|| ZERO B9
ZERO A17:A16
|| ZERO B17:B16
|| ZERO A18
|| ZERO B18
|| ZERO A19
|| ZERO B19
ZERO A21:A20
|| ZERO B21:B20
|| ZERO A22
|| ZERO B22
|| ZERO A23
|| ZERO B23
ZERO A25:A24
|| ZERO B25:B24
|| ZERO A26
|| ZERO B26
|| ZERO A27
|| ZERO B27
ZERO A29:A28
|| ZERO B29:B28
|| ZERO A30
|| ZERO B30
|| ZERO A31
|| ZERO B31
.endasmfunc
CLFLUSH .macro CONTROL,ADDR,LEN
B passthrough?
|| STW ADDR,*CONTROL[0]
STW LEN,*CONTROL[1]
spinlock?:
LDW *CONTROL[1],A0
NOP 3
passthrough?:
NOP
[A0] BNOP spinlock?,5
.endm
.global _OPENSSL_instrument_bus
_OPENSSL_instrument_bus:
.asmfunc
MV B4,B0 ; reassign sizeof(output)
|| MV A4,B4 ; reassign output
|| MVK 0x00004030,A3
MV B0,A4 ; return value
|| MVK 1,A1
|| MVKH 0x01840000,A3 ; L1DWIBAR
MVC TSCL,B8 ; collect 1st tick
|| MVK 0x00004010,A5
MV B8,B9 ; lasttick = tick
|| MVK 0,B7 ; lastdiff = 0
|| MVKH 0x01840000,A5 ; L2WIBAR
CLFLUSH A3,B4,A1 ; write-back and invalidate L1D line
CLFLUSH A5,B4,A1 ; write-back and invalidate L2 line
LL *B4,B5
NOP 4
ADD B7,B5,B5
SL B5,*B4
CMTL *B4,B1
NOP 4
STW B5,*B4
bus_loop1?:
MVC TSCL,B8
|| [B0] SUB B0,1,B0
SUB B8,B9,B7 ; lastdiff = tick - lasttick
|| MV B8,B9 ; lasttick = tick
CLFLUSH A3,B4,A1 ; write-back and invalidate L1D line
CLFLUSH A5,B4,A1 ; write-back and invalidate L2 line
LL *B4,B5
NOP 4
ADD B7,B5,B5
SL B5,*B4
CMTL *B4,B1
STW B5,*B4 ; [!B1] is removed to flatten samples
|| ADDK 4,B4
|| [B0] BNOP bus_loop1?,5
BNOP RA,5
.endasmfunc
.global _OPENSSL_instrument_bus2
_OPENSSL_instrument_bus2:
.asmfunc
MV A6,B0 ; reassign max
|| MV B4,A6 ; reassing sizeof(output)
|| MVK 0x00004030,A3
MV A4,B4 ; reassign output
|| MVK 0,A4 ; return value
|| MVK 1,A1
|| MVKH 0x01840000,A3 ; L1DWIBAR
MVC TSCL,B8 ; collect 1st tick
|| MVK 0x00004010,A5
MV B8,B9 ; lasttick = tick
|| MVK 0,B7 ; lastdiff = 0
|| MVKH 0x01840000,A5 ; L2WIBAR
CLFLUSH A3,B4,A1 ; write-back and invalidate L1D line
CLFLUSH A5,B4,A1 ; write-back and invalidate L2 line
LL *B4,B5
NOP 4
ADD B7,B5,B5
SL B5,*B4
CMTL *B4,B1
NOP 4
STW B5,*B4
MVC TSCL,B8 ; collect 1st diff
SUB B8,B9,B7 ; lastdiff = tick - lasttick
|| MV B8,B9 ; lasttick = tick
|| SUB B0,1,B0
bus_loop2?:
CLFLUSH A3,B4,A1 ; write-back and invalidate L1D line
CLFLUSH A5,B4,A1 ; write-back and invalidate L2 line
LL *B4,B5
NOP 4
ADD B7,B5,B5
SL B5,*B4
CMTL *B4,B1
STW B5,*B4 ; [!B1] is removed to flatten samples
||[!B0] BNOP bus_loop2_done?,2
|| SUB B0,1,B0
MVC TSCL,B8
SUB B8,B9,B8
|| MV B8,B9
CMPEQ B8,B7,B2
|| MV B8,B7
[!B2] ADDAW B4,1,B4
||[!B2] ADDK 1,A4
CMPEQ A4,A6,A2
[!A2] BNOP bus_loop2?,5
bus_loop2_done?:
BNOP RA,5
.endasmfunc
___
print $code;
close STDOUT;

View File

@@ -77,19 +77,17 @@ struct CMAC_CTX_st
/* Make temporary keys K1 and K2 */
static void make_kn(unsigned char *k1, unsigned char *l, int bl)
static void make_kn(unsigned char *k1, const unsigned char *l, int bl)
{
int i;
unsigned char c = l[0], carry = c>>7, cnext;
/* Shift block to left, including carry */
for (i = 0; i < bl; i++)
{
k1[i] = l[i] << 1;
if (i < bl - 1 && l[i + 1] & 0x80)
k1[i] |= 1;
}
for (i = 0; i < bl-1; i++, c = cnext)
k1[i] = (c << 1) | ((cnext=l[i+1]) >> 7);
/* If MSB set fixup with R */
if (l[0] & 0x80)
k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
k1[i] = (c << 1) ^ ((0-carry)&(bl==16?0x87:0x1b));
}
CMAC_CTX *CMAC_CTX_new(void)
@@ -143,7 +141,8 @@ int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
const EVP_CIPHER *cipher, ENGINE *impl)
{
static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
__fips_constseg
static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = {0};
/* All zeros means restart */
if (!key && !cipher && !impl && keylen == 0)
{
@@ -152,6 +151,8 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
return 0;
if (!M_EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
return 0;
memset(ctx->tbl, 0, M_EVP_CIPHER_CTX_block_size(&ctx->cctx));
ctx->nlast_block = 0;
return 1;
}
/* Initialiase context */

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;
@@ -382,7 +382,9 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
abort();
#else
/* Win32 abort() customarily shows a dialog, but we just did that... */
#ifdef SIGABRT
raise(SIGABRT);
#endif
_exit(3);
#endif
}

View File

@@ -56,6 +56,9 @@
* [including the GNU Public Licence.]
*/
#ifdef _TMS320C6X
# pragma DATA_SECTION(DES_SPtrans,".const:des_sptrans")
#endif
__fips_constseg
OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64]={
{

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)
{
@@ -956,8 +1055,6 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (!gctx->iv_set)
return -1;
if (!ctx->encrypt && gctx->taglen < 0)
return -1;
if (in)
{
if (out == NULL)
@@ -999,6 +1096,8 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
{
if (!ctx->encrypt)
{
if (gctx->taglen < 0)
return -1;
if (CRYPTO_gcm128_finish(&gctx->gcm,
ctx->buf, gctx->taglen) != 0)
return -1;
@@ -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,12 +1344,26 @@ 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)
{
vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
&cctx->ks, (block128_f)vpaes_encrypt);
cctx->str = NULL;
cctx->key_set = 1;
break;
}

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+$/)) {}
open STDOUT,">$output";
$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,231 @@
#!/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/.
# ====================================================================
#
# December 2011
#
# The module implements GCM GHASH function and underlying single
# multiplication operation in GF(2^128). Even though subroutines
# have _4bit suffix, they are not using any tables, but rely on
# hardware Galois Field Multiply support. Streamed GHASH processes
# byte in ~7 cycles, which is >6x faster than "4-bit" table-driven
# code compiled with TI's cl6x 6.0 with -mv6400+ -o2 flags. We are
# comparing apples vs. oranges, but compiler surely could have done
# better, because theoretical [though not necessarily achievable]
# estimate for "4-bit" table-driven implementation is ~12 cycles.
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
($Xip,$Htable,$inp,$len)=("A4","B4","A6","B6"); # arguments
($Z0,$Z1,$Z2,$Z3, $H0, $H1, $H2, $H3,
$H0x,$H1x,$H2x,$H3x)=map("A$_",(16..27));
($H01u,$H01y,$H2u,$H3u, $H0y,$H1y,$H2y,$H3y,
$H0z,$H1z,$H2z,$H3z)=map("B$_",(16..27));
($FF000000,$E10000)=("B30","B31");
($xip,$x0,$x1,$xib)=map("B$_",(6..9)); # $xip zaps $len
$xia="A9";
($rem,$res)=("B4","B5"); # $rem zaps $Htable
$code.=<<___;
.text
.asg B3,RA
.if 0
.global _gcm_gmult_1bit
_gcm_gmult_1bit:
ADDAD $Htable,2,$Htable
.endif
.global _gcm_gmult_4bit
_gcm_gmult_4bit:
.asmfunc
LDDW *${Htable}[-1],$H1:$H0 ; H.lo
LDDW *${Htable}[-2],$H3:$H2 ; H.hi
|| MV $Xip,${xip} ; reassign Xi
|| MVK 15,B1 ; SPLOOPD constant
MVK 0xE1,$E10000
|| LDBU *++${xip}[15],$x1 ; Xi[15]
MVK 0xFF,$FF000000
|| LDBU *--${xip},$x0 ; Xi[14]
SHL $E10000,16,$E10000 ; [pre-shifted] reduction polynomial
SHL $FF000000,24,$FF000000 ; upper byte mask
|| BNOP ghash_loop?
|| MVK 1,B0 ; take a single spin
PACKH2 $H0,$H1,$xia ; pack H0' and H1's upper bytes
AND $H2,$FF000000,$H2u ; H2's upper byte
AND $H3,$FF000000,$H3u ; H3's upper byte
|| SHRU $H2u,8,$H2u
SHRU $H3u,8,$H3u
|| ZERO $Z1:$Z0
SHRU2 $xia,8,$H01u
|| ZERO $Z3:$Z2
.endasmfunc
.global _gcm_ghash_4bit
_gcm_ghash_4bit:
.asmfunc
LDDW *${Htable}[-1],$H1:$H0 ; H.lo
|| SHRU $len,4,B0 ; reassign len
LDDW *${Htable}[-2],$H3:$H2 ; H.hi
|| MV $Xip,${xip} ; reassign Xi
|| MVK 15,B1 ; SPLOOPD constant
MVK 0xE1,$E10000
|| [B0] LDNDW *${inp}[1],$H1x:$H0x
MVK 0xFF,$FF000000
|| [B0] LDNDW *${inp}++[2],$H3x:$H2x
SHL $E10000,16,$E10000 ; [pre-shifted] reduction polynomial
|| LDDW *${xip}[1],$Z1:$Z0
SHL $FF000000,24,$FF000000 ; upper byte mask
|| LDDW *${xip}[0],$Z3:$Z2
PACKH2 $H0,$H1,$xia ; pack H0' and H1's upper bytes
AND $H2,$FF000000,$H2u ; H2's upper byte
AND $H3,$FF000000,$H3u ; H3's upper byte
|| SHRU $H2u,8,$H2u
SHRU $H3u,8,$H3u
SHRU2 $xia,8,$H01u
|| [B0] XOR $H0x,$Z0,$Z0 ; Xi^=inp
|| [B0] XOR $H1x,$Z1,$Z1
.if .LITTLE_ENDIAN
[B0] XOR $H2x,$Z2,$Z2
|| [B0] XOR $H3x,$Z3,$Z3
|| [B0] SHRU $Z1,24,$xia ; Xi[15], avoid cross-path stall
STDW $Z1:$Z0,*${xip}[1]
|| [B0] SHRU $Z1,16,$x0 ; Xi[14]
|| [B0] ZERO $Z1:$Z0
.else
[B0] XOR $H2x,$Z2,$Z2
|| [B0] XOR $H3x,$Z3,$Z3
|| [B0] MV $Z0,$xia ; Xi[15], avoid cross-path stall
STDW $Z1:$Z0,*${xip}[1]
|| [B0] SHRU $Z0,8,$x0 ; Xi[14]
|| [B0] ZERO $Z1:$Z0
.endif
STDW $Z3:$Z2,*${xip}[0]
|| [B0] ZERO $Z3:$Z2
|| [B0] MV $xia,$x1
[B0] ADDK 14,${xip}
ghash_loop?:
SPLOOPD 6 ; 6*16+7
|| MVC B1,ILC
|| [B0] SUB B0,1,B0
|| ZERO A0
|| ADD $x1,$x1,$xib ; SHL $x1,1,$xib
|| SHL $x1,1,$xia
___
########____________________________
# 0 D2. M1 M2 |
# 1 M1 |
# 2 M1 M2 |
# 3 D1. M1 M2 |
# 4 S1. L1 |
# 5 S2 S1x L1 D2 L2 |____________________________
# 6/0 L1 S1 L2 S2x |D2. M1 M2 |
# 7/1 L1 S1 D1x S2 M2 | M1 |
# 8/2 S1 L1x S2 | M1 M2 |
# 9/3 S1 L1x | D1. M1 M2 |
# 10/4 D1x | S1. L1 |
# 11/5 |S2 S1x L1 D2 L2 |____________
# 12/6/0 D1x __| L1 S1 L2 S2x |D2. ....
# 7/1 L1 S1 D1x S2 M2 | ....
# 8/2 S1 L1x S2 | ....
#####... ................|............
$code.=<<___;
XORMPY $H0,$xia,$H0x ; 0 ; H<>Xi[i]
|| XORMPY $H01u,$xib,$H01y
|| [A0] LDBU *--${xip},$x0
XORMPY $H1,$xia,$H1x ; 1
XORMPY $H2,$xia,$H2x ; 2
|| XORMPY $H2u,$xib,$H2y
XORMPY $H3,$xia,$H3x ; 3
|| XORMPY $H3u,$xib,$H3y
||[!A0] MVK.D 15,A0 ; *--${xip} counter
XOR.L $H0x,$Z0,$Z0 ; 4 ; Z^=H<>Xi[i]
|| [A0] SUB.S A0,1,A0
XOR.L $H1x,$Z1,$Z1 ; 5
|| AND.D $H01y,$FF000000,$H0z
|| SWAP2.L $H01y,$H1y ; ; SHL $H01y,16,$H1y
|| SHL $x0,1,$xib
|| SHL $x0,1,$xia
XOR.L $H2x,$Z2,$Z2 ; 6/0 ; [0,0] in epilogue
|| SHL $Z0,1,$rem ; ; rem=Z<<1
|| SHRMB.S $Z1,$Z0,$Z0 ; ; Z>>=8
|| AND.L $H1y,$FF000000,$H1z
XOR.L $H3x,$Z3,$Z3 ; 7/1
|| SHRMB.S $Z2,$Z1,$Z1
|| XOR.D $H0z,$Z0,$Z0 ; merge upper byte products
|| AND.S $H2y,$FF000000,$H2z
|| XORMPY $E10000,$rem,$res ; ; implicit rem&0x1FE
XOR.L $H1z,$Z1,$Z1 ; 8/2
|| SHRMB.S $Z3,$Z2,$Z2
|| AND.S $H3y,$FF000000,$H3z
XOR.L $H2z,$Z2,$Z2 ; 9/3
|| SHRU $Z3,8,$Z3
XOR.D $H3z,$Z3,$Z3 ; 10/4
NOP ; 11/5
SPKERNEL 0,2
|| XOR.D $res,$Z3,$Z3 ; 12/6/0; Z^=res
; input pre-fetch is possible where D1 slot is available...
[B0] LDNDW *${inp}[1],$H1x:$H0x ; 8/-
[B0] LDNDW *${inp}++[2],$H3x:$H2x ; 9/-
NOP ; 10/-
.if .LITTLE_ENDIAN
SWAP2 $Z0,$Z1 ; 11/-
|| SWAP4 $Z1,$Z0
SWAP4 $Z1,$Z1 ; 12/-
|| SWAP2 $Z0,$Z0
SWAP2 $Z2,$Z3
|| SWAP4 $Z3,$Z2
||[!B0] BNOP RA
SWAP4 $Z3,$Z3
|| SWAP2 $Z2,$Z2
|| [B0] BNOP ghash_loop?
[B0] XOR $H0x,$Z0,$Z0 ; Xi^=inp
|| [B0] XOR $H1x,$Z1,$Z1
[B0] XOR $H2x,$Z2,$Z2
|| [B0] XOR $H3x,$Z3,$Z3
|| [B0] SHRU $Z1,24,$xia ; Xi[15], avoid cross-path stall
STDW $Z1:$Z0,*${xip}[1]
|| [B0] SHRU $Z1,16,$x0 ; Xi[14]
|| [B0] ZERO $Z1:$Z0
.else
[!B0] BNOP RA ; 11/-
[B0] BNOP ghash_loop? ; 12/-
[B0] XOR $H0x,$Z0,$Z0 ; Xi^=inp
|| [B0] XOR $H1x,$Z1,$Z1
[B0] XOR $H2x,$Z2,$Z2
|| [B0] XOR $H3x,$Z3,$Z3
|| [B0] MV $Z0,$xia ; Xi[15], avoid cross-path stall
STDW $Z1:$Z0,*${xip}[1]
|| [B0] SHRU $Z0,8,$x0 ; Xi[14]
|| [B0] ZERO $Z1:$Z0
.endif
STDW $Z3:$Z2,*${xip}[0]
|| [B0] ZERO $Z3:$Z2
|| [B0] MV $xia,$x1
[B0] ADDK 14,${xip}
.endasmfunc
.sect .const
.cstring "GHASH for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
.align 4
___
print $code;
close STDOUT;

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,14 +666,25 @@ 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
# endif
#endif
@@ -738,14 +749,28 @@ 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;
}
# elif defined(GHASH_ASM_C64Xplus)
/* C64x+ assembler doesn't use tables, skip gcm_init_4bit.
* This is likely to trigger "function never referenced"
* warning and code being eliminated. */
# else
gcm_init_4bit(ctx->Htable,ctx->H.u);
# endif
@@ -1397,7 +1422,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16]) = ctx->gmult;
#endif
if (ctx->mres)
if (ctx->mres || ctx->ares)
GCM_MUL(ctx,Xi);
if (is_endian.little) {

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+$/)) {}
open STDOUT,">$output";
$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";
@@ -177,6 +189,7 @@ for($i=0;$i<5;$i++) {
$code.=<<___;
teq $Xi,sp
bne .L_00_15 @ [((11+4)*5+2)*3]
sub sp,sp,#25*4
___
&BODY_00_15(@V); unshift(@V,pop(@V));
&BODY_16_19(@V); unshift(@V,pop(@V));
@@ -186,7 +199,6 @@ ___
$code.=<<___;
ldr $K,.LK_20_39 @ [+15+16*4]
sub sp,sp,#25*4
cmn sp,#0 @ [+3], clear carry to denote 20_39
.L_20_39_or_60_79:
___

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

@@ -0,0 +1,323 @@
#!/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 C64x+.
#
# November 2011
#
# If compared to compiler-generated code with similar characteristics,
# i.e. compiled with OPENSSL_SMALL_FOOTPRINT and utilizing SPLOOPs,
# this implementation is 25% smaller and >2x faster. In absolute terms
# performance is (quite impressive) ~6.5 cycles per processed byte.
# Fully unrolled assembler would be ~5x larger and is likely to be
# ~15% faster. It would be free from references to intermediate ring
# buffer, but put more pressure on L1P [both because the code would be
# larger and won't be using SPLOOP buffer]. There are no plans to
# realize fully unrolled variant though...
#
# !!! Note that this module uses AMR, which means that all interrupt
# service routines are expected to preserve it and for own well-being
# zero it upon entry.
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
($CTX,$INP,$NUM) = ("A4","B4","A6"); # arguments
($A,$B,$C,$D,$E, $Arot,$F,$F0,$T,$K) = map("A$_",(16..20, 21..25));
($X0,$X2,$X8,$X13) = ("A26","B26","A27","B27");
($TX0,$TX1,$TX2,$TX3) = map("B$_",(28..31));
($XPA,$XPB) = ("A5","B5"); # X circular buffer
($Actx,$Bctx,$Cctx,$Dctx,$Ectx) = map("A$_",(3,6..9)); # zaps $NUM
$code=<<___;
.text
.asg B3,RA
.asg A15,FP
.asg B15,SP
.if .BIG_ENDIAN
.asg MV,SWAP2
.asg MV,SWAP4
.endif
.global _sha1_block_data_order
_sha1_block_data_order:
.asmfunc stack_usage(64)
MV $NUM,A0 ; reassign $NUM
|| MVK -64,B0
[!A0] BNOP RA ; if ($NUM==0) return;
|| [A0] STW FP,*SP--[16] ; save frame pointer and alloca(64)
|| [A0] MV SP,FP
[A0] LDW *${CTX}[0],$A ; load A-E...
|| [A0] AND B0,SP,SP ; align stack at 64 bytes
[A0] LDW *${CTX}[1],$B
|| [A0] SUBAW SP,2,SP ; reserve two words above buffer
[A0] LDW *${CTX}[2],$C
|| [A0] MVK 0x00404,B0
[A0] LDW *${CTX}[3],$D
|| [A0] MVKH 0x50000,B0 ; 0x050404, 64 bytes for $XP[AB]
[A0] LDW *${CTX}[4],$E
|| [A0] MVC B0,AMR ; setup circular addressing
LDNW *${INP}++,$TX1 ; pre-fetch input
NOP 1
loop?:
MVK 0x00007999,$K
|| ADDAW SP,2,$XPA
|| SUB A0,1,A0
|| MVK 13,B0
MVKH 0x5a820000,$K ; K_00_19
|| ADDAW SP,2,$XPB
|| MV $A,$Actx
|| MV $B,$Bctx
;;==================================================
SPLOOPD 5 ; BODY_00_13
|| MV $C,$Cctx
|| MV $D,$Dctx
|| MV $E,$Ectx
|| MVC B0,ILC
ROTL $A,5,$Arot
|| AND $C,$B,$F
|| ANDN $D,$B,$F0
|| ADD $K,$E,$T ; T=E+K
XOR $F0,$F,$F ; F_00_19(B,C,D)
|| MV $D,$E ; E=D
|| MV $C,$D ; D=C
|| SWAP2 $TX1,$TX2
|| LDNW *${INP}++,$TX1
ADD $F,$T,$T ; T+=F_00_19(B,C,D)
|| ROTL $B,30,$C ; C=ROL(B,30)
|| SWAP4 $TX2,$TX3 ; byte swap
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| MV $A,$B ; B=A
ADD $TX3,$T,$A ; A=T+Xi
|| STW $TX3,*${XPB}++
SPKERNEL
;;==================================================
ROTL $A,5,$Arot ; BODY_14
|| AND $C,$B,$F
|| ANDN $D,$B,$F0
|| ADD $K,$E,$T ; T=E+K
XOR $F0,$F,$F ; F_00_19(B,C,D)
|| MV $D,$E ; E=D
|| MV $C,$D ; D=C
|| SWAP2 $TX1,$TX2
|| LDNW *${INP}++,$TX1
ADD $F,$T,$T ; T+=F_00_19(B,C,D)
|| ROTL $B,30,$C ; C=ROL(B,30)
|| SWAP4 $TX2,$TX2 ; byte swap
|| LDW *${XPA}++,$X0 ; fetches from X ring buffer are
|| LDW *${XPB}[4],$X2 ; 2 iterations ahead
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| MV $A,$B ; B=A
|| LDW *${XPA}[7],$X8
|| MV $TX3,$X13 ; || LDW *${XPB}[15],$X13
|| MV $TX2,$TX3
ADD $TX2,$T,$A ; A=T+Xi
|| STW $TX2,*${XPB}++
;;==================================================
ROTL $A,5,$Arot ; BODY_15
|| AND $C,$B,$F
|| ANDN $D,$B,$F0
|| ADD $K,$E,$T ; T=E+K
XOR $F0,$F,$F ; F_00_19(B,C,D)
|| MV $D,$E ; E=D
|| MV $C,$D ; D=C
|| SWAP2 $TX1,$TX2
ADD $F,$T,$T ; T+=F_00_19(B,C,D)
|| ROTL $B,30,$C ; C=ROL(B,30)
|| SWAP4 $TX2,$TX2 ; byte swap
|| XOR $X0,$X2,$TX0 ; Xupdate XORs are 1 iteration ahead
|| LDW *${XPA}++,$X0
|| LDW *${XPB}[4],$X2
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| MV $A,$B ; B=A
|| XOR $X8,$X13,$TX1
|| LDW *${XPA}[7],$X8
|| MV $TX3,$X13 ; || LDW *${XPB}[15],$X13
|| MV $TX2,$TX3
ADD $TX2,$T,$A ; A=T+Xi
|| STW $TX2,*${XPB}++
|| XOR $TX0,$TX1,$TX1
|| MVK 3,B0
;;==================================================
SPLOOPD 5 ; BODY_16_19
|| MVC B0,ILC
ROTL $A,5,$Arot
|| AND $C,$B,$F
|| ANDN $D,$B,$F0
|| ADD $K,$E,$T ; T=E+K
|| ROTL $TX1,1,$TX2 ; Xupdate output
XOR $F0,$F,$F ; F_00_19(B,C,D)
|| MV $D,$E ; E=D
|| MV $C,$D ; D=C
ADD $F,$T,$T ; T+=F_00_19(B,C,D)
|| ROTL $B,30,$C ; C=ROL(B,30)
|| XOR $X0,$X2,$TX0
|| LDW *${XPA}++,$X0
|| LDW *${XPB}[4],$X2
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| MV $A,$B ; B=A
|| XOR $X8,$X13,$TX1
|| LDW *${XPA}[7],$X8
|| MV $TX3,$X13 ; || LDW *${XPB}[15],$X13
|| MV $TX2,$TX3
ADD $TX2,$T,$A ; A=T+Xi
|| STW $TX2,*${XPB}++
|| XOR $TX0,$TX1,$TX1
SPKERNEL
MVK 0xffffeba1,$K
|| MVK 19,B0
MVKH 0x6ed90000,$K ; K_20_39
___
sub BODY_20_39 {
$code.=<<___;
;;==================================================
SPLOOPD 5 ; BODY_20_39
|| MVC B0,ILC
ROTL $A,5,$Arot
|| XOR $B,$C,$F
|| ADD $K,$E,$T ; T=E+K
|| ROTL $TX1,1,$TX2 ; Xupdate output
XOR $D,$F,$F ; F_20_39(B,C,D)
|| MV $D,$E ; E=D
|| MV $C,$D ; D=C
ADD $F,$T,$T ; T+=F_20_39(B,C,D)
|| ROTL $B,30,$C ; C=ROL(B,30)
|| XOR $X0,$X2,$TX0
|| LDW *${XPA}++,$X0
|| LDW *${XPB}[4],$X2
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| MV $A,$B ; B=A
|| XOR $X8,$X13,$TX1
|| LDW *${XPA}[7],$X8
|| MV $TX3,$X13 ; || LDW *${XPB}[15],$X13
|| MV $TX2,$TX3
ADD $TX2,$T,$A ; A=T+Xi
|| STW $TX2,*${XPB}++ ; last one is redundant
|| XOR $TX0,$TX1,$TX1
SPKERNEL
___
$code.=<<___ if (!shift);
MVK 0xffffbcdc,$K
MVKH 0x8f1b0000,$K ; K_40_59
___
} &BODY_20_39();
$code.=<<___;
;;==================================================
SPLOOPD 5 ; BODY_40_59
|| MVC B0,ILC
|| AND $B,$C,$F
|| AND $B,$D,$F0
ROTL $A,5,$Arot
|| XOR $F0,$F,$F
|| AND $C,$D,$F0
|| ADD $K,$E,$T ; T=E+K
|| ROTL $TX1,1,$TX2 ; Xupdate output
XOR $F0,$F,$F ; F_40_59(B,C,D)
|| MV $D,$E ; E=D
|| MV $C,$D ; D=C
ADD $F,$T,$T ; T+=F_40_59(B,C,D)
|| ROTL $B,30,$C ; C=ROL(B,30)
|| XOR $X0,$X2,$TX0
|| LDW *${XPA}++,$X0
|| LDW *${XPB}[4],$X2
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| MV $A,$B ; B=A
|| XOR $X8,$X13,$TX1
|| LDW *${XPA}[7],$X8
|| MV $TX3,$X13 ; || LDW *${XPB}[15],$X13
|| MV $TX2,$TX3
ADD $TX2,$T,$A ; A=T+Xi
|| STW $TX2,*${XPB}++
|| XOR $TX0,$TX1,$TX1
|| AND $B,$C,$F
|| AND $B,$D,$F0
SPKERNEL
MVK 0xffffc1d6,$K
|| MVK 18,B0
MVKH 0xca620000,$K ; K_60_79
___
&BODY_20_39(-1); # BODY_60_78
$code.=<<___;
;;==================================================
[A0] B loop?
|| ROTL $A,5,$Arot ; BODY_79
|| XOR $B,$C,$F
|| ROTL $TX1,1,$TX2 ; Xupdate output
[A0] LDNW *${INP}++,$TX1 ; pre-fetch input
|| ADD $K,$E,$T ; T=E+K
|| XOR $D,$F,$F ; F_20_39(B,C,D)
ADD $F,$T,$T ; T+=F_20_39(B,C,D)
|| ADD $Ectx,$D,$E ; E=D,E+=Ectx
|| ADD $Dctx,$C,$D ; D=C,D+=Dctx
|| ROTL $B,30,$C ; C=ROL(B,30)
ADD $Arot,$T,$T ; T+=ROL(A,5)
|| ADD $Bctx,$A,$B ; B=A,B+=Bctx
ADD $TX2,$T,$A ; A=T+Xi
ADD $Actx,$A,$A ; A+=Actx
|| ADD $Cctx,$C,$C ; C+=Cctx
;; end of loop?
BNOP RA ; return
|| MV FP,SP ; restore stack pointer
|| LDW *FP[0],FP ; restore frame pointer
STW $A,*${CTX}[0] ; emit A-E...
|| MVK 0,B0
STW $B,*${CTX}[1]
|| MVC B0,AMR ; clear AMR
STW $C,*${CTX}[2]
STW $D,*${CTX}[3]
STW $E,*${CTX}[4]
.endasmfunc
.sect .const
.cstring "SHA1 block transform for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
.align 4
___
print $code;
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+$/)) {}
open STDOUT,">$output";
$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

@@ -0,0 +1,292 @@
#!/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 for C64x+.
#
# January 2012
#
# Performance is just below 10 cycles per processed byte, which is
# almost 40% faster than compiler-generated code. Unroll is unlikely
# to give more than ~8% improvement...
#
# !!! Note that this module uses AMR, which means that all interrupt
# service routines are expected to preserve it and for own well-being
# zero it upon entry.
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
($CTXA,$INP,$NUM) = ("A4","B4","A6"); # arguments
$K256="A3";
($A,$Actx,$B,$Bctx,$C,$Cctx,$D,$Dctx,$T2,$S0,$s1,$t0a,$t1a,$t2a,$X9,$X14)
=map("A$_",(16..31));
($E,$Ectx,$F,$Fctx,$G,$Gctx,$H,$Hctx,$T1,$S1,$s0,$t0e,$t1e,$t2e,$X1,$X15)
=map("B$_",(16..31));
($Xia,$Xib)=("A5","B5"); # circular/ring buffer
$CTXB=$t2e;
($Xn,$X0,$K)=("B7","B8","B9");
($Maj,$Ch)=($T2,"B6");
$code.=<<___;
.text
.asg B3,RA
.asg A15,FP
.asg B15,SP
.if .BIG_ENDIAN
.asg SWAP2,MV
.asg SWAP4,MV
.endif
.global _sha256_block_data_order
_sha256_block_data_order:
.asmfunc stack_usage(64)
MV $NUM,A0 ; reassign $NUM
|| MVK -64,B0
[!A0] BNOP RA ; if ($NUM==0) return;
|| [A0] STW FP,*SP--[16] ; save frame pointer and alloca(64)
|| [A0] MV SP,FP
[A0] ADDKPC _sha256_block_data_order,B2
|| [A0] AND B0,SP,SP ; align stack at 64 bytes
[A0] MVK 0x00404,B1
|| [A0] MVKL (K256-_sha256_block_data_order),$K256
[A0] MVKH 0x50000,B1
|| [A0] MVKH (K256-_sha256_block_data_order),$K256
[A0] MVC B1,AMR ; setup circular addressing
|| [A0] MV SP,$Xia
[A0] MV SP,$Xib
|| [A0] ADD B2,$K256,$K256
|| [A0] MV $CTXA,$CTXB
|| [A0] SUBAW SP,2,SP ; reserve two words above buffer
LDW *${CTXA}[0],$A ; load ctx
|| LDW *${CTXB}[4],$E
LDW *${CTXA}[1],$B
|| LDW *${CTXB}[5],$F
LDW *${CTXA}[2],$C
|| LDW *${CTXB}[6],$G
LDW *${CTXA}[3],$D
|| LDW *${CTXB}[7],$H
LDNW *$INP++,$Xn ; pre-fetch input
LDW *$K256++,$K ; pre-fetch K256[0]
MVK 14,B0 ; loop counters
MVK 47,B1
|| ADDAW $Xia,9,$Xia
outerloop?:
SUB A0,1,A0
|| MV $A,$Actx
|| MV $E,$Ectx
|| MVD $B,$Bctx
|| MVD $F,$Fctx
MV $C,$Cctx
|| MV $G,$Gctx
|| MVD $D,$Dctx
|| MVD $H,$Hctx
|| SWAP4 $Xn,$X0
SPLOOPD 8 ; BODY_00_14
|| MVC B0,ILC
|| SWAP2 $X0,$X0
LDNW *$INP++,$Xn
|| ROTL $A,30,$S0
|| OR $A,$B,$Maj
|| AND $A,$B,$t2a
|| ROTL $E,26,$S1
|| AND $F,$E,$Ch
|| ANDN $G,$E,$t2e
ROTL $A,19,$t0a
|| AND $C,$Maj,$Maj
|| ROTL $E,21,$t0e
|| XOR $t2e,$Ch,$Ch ; Ch(e,f,g) = (e&f)^(~e&g)
ROTL $A,10,$t1a
|| OR $t2a,$Maj,$Maj ; Maj(a,b,c) = ((a|b)&c)|(a&b)
|| ROTL $E,7,$t1e
|| ADD $K,$H,$T1 ; T1 = h + K256[i]
ADD $X0,$T1,$T1 ; T1 += X[i];
|| STW $X0,*$Xib++
|| XOR $t0a,$S0,$S0
|| XOR $t0e,$S1,$S1
XOR $t1a,$S0,$S0 ; Sigma0(a)
|| XOR $t1e,$S1,$S1 ; Sigma1(e)
|| LDW *$K256++,$K ; pre-fetch K256[i+1]
|| ADD $Ch,$T1,$T1 ; T1 += Ch(e,f,g)
ADD $S1,$T1,$T1 ; T1 += Sigma1(e)
|| ADD $S0,$Maj,$T2 ; T2 = Sigma0(a) + Maj(a,b,c)
|| ROTL $G,0,$H ; h = g
|| MV $F,$G ; g = f
|| MV $X0,$X14
|| SWAP4 $Xn,$X0
SWAP2 $X0,$X0
|| MV $E,$F ; f = e
|| ADD $D,$T1,$E ; e = d + T1
|| MV $C,$D ; d = c
MV $B,$C ; c = b
|| MV $A,$B ; b = a
|| ADD $T1,$T2,$A ; a = T1 + T2
SPKERNEL
ROTL $A,30,$S0 ; BODY_15
|| OR $A,$B,$Maj
|| AND $A,$B,$t2a
|| ROTL $E,26,$S1
|| AND $F,$E,$Ch
|| ANDN $G,$E,$t2e
|| LDW *${Xib}[1],$Xn ; modulo-scheduled
ROTL $A,19,$t0a
|| AND $C,$Maj,$Maj
|| ROTL $E,21,$t0e
|| XOR $t2e,$Ch,$Ch ; Ch(e,f,g) = (e&f)^(~e&g)
|| LDW *${Xib}[2],$X1 ; modulo-scheduled
ROTL $A,10,$t1a
|| OR $t2a,$Maj,$Maj ; Maj(a,b,c) = ((a|b)&c)|(a&b)
|| ROTL $E,7,$t1e
|| ADD $K,$H,$T1 ; T1 = h + K256[i]
ADD $X0,$T1,$T1 ; T1 += X[i];
|| STW $X0,*$Xib++
|| XOR $t0a,$S0,$S0
|| XOR $t0e,$S1,$S1
XOR $t1a,$S0,$S0 ; Sigma0(a)
|| XOR $t1e,$S1,$S1 ; Sigma1(e)
|| LDW *$K256++,$K ; pre-fetch K256[i+1]
|| ADD $Ch,$T1,$T1 ; T1 += Ch(e,f,g)
ADD $S1,$T1,$T1 ; T1 += Sigma1(e)
|| ADD $S0,$Maj,$T2 ; T2 = Sigma0(a) + Maj(a,b,c)
|| ROTL $G,0,$H ; h = g
|| MV $F,$G ; g = f
|| MV $X0,$X15
MV $E,$F ; f = e
|| ADD $D,$T1,$E ; e = d + T1
|| MV $C,$D ; d = c
|| MV $Xn,$X0 ; modulo-scheduled
|| LDW *$Xia,$X9 ; modulo-scheduled
|| ROTL $X1,25,$t0e ; modulo-scheduled
|| ROTL $X14,15,$t0a ; modulo-scheduled
SHRU $X1,3,$s0 ; modulo-scheduled
|| SHRU $X14,10,$s1 ; modulo-scheduled
|| ROTL $B,0,$C ; c = b
|| MV $A,$B ; b = a
|| ADD $T1,$T2,$A ; a = T1 + T2
SPLOOPD 10 ; BODY_16_63
|| MVC B1,ILC
|| ROTL $X1,14,$t1e ; modulo-scheduled
|| ROTL $X14,13,$t1a ; modulo-scheduled
XOR $t0e,$s0,$s0
|| XOR $t0a,$s1,$s1
|| MV $X15,$X14
|| MV $X1,$Xn
XOR $t1e,$s0,$s0 ; sigma0(X[i+1])
|| XOR $t1a,$s1,$s1 ; sigma1(X[i+14])
|| LDW *${Xib}[2],$X1 ; module-scheduled
ROTL $A,30,$S0
|| OR $A,$B,$Maj
|| AND $A,$B,$t2a
|| ROTL $E,26,$S1
|| AND $F,$E,$Ch
|| ANDN $G,$E,$t2e
|| ADD $X9,$X0,$X0 ; X[i] += X[i+9]
ROTL $A,19,$t0a
|| AND $C,$Maj,$Maj
|| ROTL $E,21,$t0e
|| XOR $t2e,$Ch,$Ch ; Ch(e,f,g) = (e&f)^(~e&g)
|| ADD $s0,$X0,$X0 ; X[i] += sigma1(X[i+1])
ROTL $A,10,$t1a
|| OR $t2a,$Maj,$Maj ; Maj(a,b,c) = ((a|b)&c)|(a&b)
|| ROTL $E,7,$t1e
|| ADD $H,$K,$T1 ; T1 = h + K256[i]
|| ADD $s1,$X0,$X0 ; X[i] += sigma1(X[i+14])
XOR $t0a,$S0,$S0
|| XOR $t0e,$S1,$S1
|| ADD $X0,$T1,$T1 ; T1 += X[i]
|| STW $X0,*$Xib++
XOR $t1a,$S0,$S0 ; Sigma0(a)
|| XOR $t1e,$S1,$S1 ; Sigma1(e)
|| ADD $Ch,$T1,$T1 ; T1 += Ch(e,f,g)
|| MV $X0,$X15
|| ROTL $G,0,$H ; h = g
|| LDW *$K256++,$K ; pre-fetch K256[i+1]
ADD $S1,$T1,$T1 ; T1 += Sigma1(e)
|| ADD $S0,$Maj,$T2 ; T2 = Sigma0(a) + Maj(a,b,c)
|| MV $F,$G ; g = f
|| MV $Xn,$X0 ; modulo-scheduled
|| LDW *++$Xia,$X9 ; modulo-scheduled
|| ROTL $X1,25,$t0e ; module-scheduled
|| ROTL $X14,15,$t0a ; modulo-scheduled
ROTL $X1,14,$t1e ; modulo-scheduled
|| ROTL $X14,13,$t1a ; modulo-scheduled
|| MV $E,$F ; f = e
|| ADD $D,$T1,$E ; e = d + T1
|| MV $C,$D ; d = c
|| MV $B,$C ; c = b
MV $A,$B ; b = a
|| ADD $T1,$T2,$A ; a = T1 + T2
|| SHRU $X1,3,$s0 ; modulo-scheduled
|| SHRU $X14,10,$s1 ; modulo-scheduled
SPKERNEL
[A0] B outerloop?
|| [A0] LDNW *$INP++,$Xn ; pre-fetch input
|| [A0] ADDK -260,$K256 ; rewind K256
|| ADD $Actx,$A,$A ; accumulate ctx
|| ADD $Ectx,$E,$E
|| ADD $Bctx,$B,$B
ADD $Fctx,$F,$F
|| ADD $Cctx,$C,$C
|| ADD $Gctx,$G,$G
|| ADD $Dctx,$D,$D
|| ADD $Hctx,$H,$H
|| [A0] LDW *$K256++,$K ; pre-fetch K256[0]
[!A0] BNOP RA
||[!A0] MV $CTXA,$CTXB
[!A0] MV FP,SP ; restore stack pointer
||[!A0] LDW *FP[0],FP ; restore frame pointer
[!A0] STW $A,*${CTXA}[0] ; save ctx
||[!A0] STW $E,*${CTXB}[4]
||[!A0] MVK 0,B0
[!A0] STW $B,*${CTXA}[1]
||[!A0] STW $F,*${CTXB}[5]
||[!A0] MVC B0,AMR ; clear AMR
STW $C,*${CTXA}[2]
|| STW $G,*${CTXB}[6]
STW $D,*${CTXA}[3]
|| STW $H,*${CTXB}[7]
.endasmfunc
.sect ".const:sha_asm"
.align 128
K256:
.uword 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
.uword 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
.uword 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
.uword 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
.uword 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
.uword 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
.uword 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
.uword 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
.uword 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
.uword 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
.uword 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
.uword 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
.uword 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
.uword 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
.uword 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
.uword 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
.cstring "SHA256 block transform for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
.align 4
___
print $code;

View File

@@ -38,8 +38,20 @@ $hi="HI";
$lo="LO";
# ====================================================================
while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
$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;

View File

@@ -0,0 +1,410 @@
#!/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/.
# ====================================================================
#
# SHA512 for C64x+.
#
# January 2012
#
# Performance is 19 cycles per processed byte. Compared to block
# transform function from sha512.c compiled with cl6x with -mv6400+
# -o2 -DOPENSSL_SMALL_FOOTPRINT it's almost 7x faster and 2x smaller.
# Loop unroll won't make it, this implementation, any faster, because
# it's effectively dominated by SHRU||SHL pairs and you can't schedule
# more of them.
#
# !!! Note that this module uses AMR, which means that all interrupt
# service routines are expected to preserve it and for own well-being
# zero it upon entry.
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
open STDOUT,">$output";
($CTXA,$INP,$NUM) = ("A4","B4","A6"); # arguments
$K512="A3";
($Ahi,$Actxhi,$Bhi,$Bctxhi,$Chi,$Cctxhi,$Dhi,$Dctxhi,
$Ehi,$Ectxhi,$Fhi,$Fctxhi,$Ghi,$Gctxhi,$Hhi,$Hctxhi)=map("A$_",(16..31));
($Alo,$Actxlo,$Blo,$Bctxlo,$Clo,$Cctxlo,$Dlo,$Dctxlo,
$Elo,$Ectxlo,$Flo,$Fctxlo,$Glo,$Gctxlo,$Hlo,$Hctxlo)=map("B$_",(16..31));
($S1hi,$CHhi,$S0hi,$t0hi)=map("A$_",(10..13));
($S1lo,$CHlo,$S0lo,$t0lo)=map("B$_",(10..13));
($T1hi, $T2hi)= ("A6","A7");
($T1lo,$T1carry,$T2lo,$T2carry)=("B6","B7","B8","B9");
($Khi,$Klo)=("A9","A8");
($MAJhi,$MAJlo)=($T2hi,$T2lo);
($t1hi,$t1lo)=($Khi,"B2");
$CTXB=$t1lo;
($Xihi,$Xilo)=("A5","B5"); # circular/ring buffer
$code.=<<___;
.text
.asg B3,RA
.asg A15,FP
.asg B15,SP
.if .BIG_ENDIAN
.asg $Khi,KHI
.asg $Klo,KLO
.else
.asg $Khi,KLO
.asg $Klo,KHI
.endif
.global _sha512_block_data_order
_sha512_block_data_order:
.asmfunc stack_usage(40+128)
MV $NUM,A0 ; reassign $NUM
|| MVK -128,B0
[!A0] BNOP RA ; if ($NUM==0) return;
|| [A0] STW FP,*SP--(40) ; save frame pointer
|| [A0] MV SP,FP
[A0] STDW B13:B12,*SP[4]
|| [A0] MVK 0x00404,B1
[A0] STDW B11:B10,*SP[3]
|| [A0] STDW A13:A12,*FP[-3]
|| [A0] MVKH 0x60000,B1
[A0] STDW A11:A10,*SP[1]
|| [A0] MVC B1,AMR ; setup circular addressing
|| [A0] ADD B0,SP,SP ; alloca(128)
[A0] AND B0,SP,SP ; align stack at 128 bytes
|| [A0] ADDKPC _sha512_block_data_order,B1
|| [A0] MVKL (K512-_sha512_block_data_order),$K512
[A0] MVKH (K512-_sha512_block_data_order),$K512
|| [A0] SUBAW SP,2,SP ; reserve two words above buffer
ADDAW SP,3,$Xilo
ADDAW SP,2,$Xihi
|| MV $CTXA,$CTXB
LDW *${CTXA}[0^.LITTLE_ENDIAN],$Ahi ; load ctx
|| LDW *${CTXB}[1^.LITTLE_ENDIAN],$Alo
|| ADD B1,$K512,$K512
LDW *${CTXA}[2^.LITTLE_ENDIAN],$Bhi
|| LDW *${CTXB}[3^.LITTLE_ENDIAN],$Blo
LDW *${CTXA}[4^.LITTLE_ENDIAN],$Chi
|| LDW *${CTXB}[5^.LITTLE_ENDIAN],$Clo
LDW *${CTXA}[6^.LITTLE_ENDIAN],$Dhi
|| LDW *${CTXB}[7^.LITTLE_ENDIAN],$Dlo
LDW *${CTXA}[8^.LITTLE_ENDIAN],$Ehi
|| LDW *${CTXB}[9^.LITTLE_ENDIAN],$Elo
LDW *${CTXA}[10^.LITTLE_ENDIAN],$Fhi
|| LDW *${CTXB}[11^.LITTLE_ENDIAN],$Flo
LDW *${CTXA}[12^.LITTLE_ENDIAN],$Ghi
|| LDW *${CTXB}[13^.LITTLE_ENDIAN],$Glo
LDW *${CTXA}[14^.LITTLE_ENDIAN],$Hhi
|| LDW *${CTXB}[15^.LITTLE_ENDIAN],$Hlo
LDNDW *$INP++,B11:B10 ; pre-fetch input
LDDW *$K512++,$Khi:$Klo ; pre-fetch K512[0]
outerloop?:
MVK 15,B0 ; loop counters
|| MVK 64,B1
|| SUB A0,1,A0
MV $Ahi,$Actxhi
|| MV $Alo,$Actxlo
|| MV $Bhi,$Bctxhi
|| MV $Blo,$Bctxlo
|| MV $Chi,$Cctxhi
|| MV $Clo,$Cctxlo
|| MVD $Dhi,$Dctxhi
|| MVD $Dlo,$Dctxlo
MV $Ehi,$Ectxhi
|| MV $Elo,$Ectxlo
|| MV $Fhi,$Fctxhi
|| MV $Flo,$Fctxlo
|| MV $Ghi,$Gctxhi
|| MV $Glo,$Gctxlo
|| MVD $Hhi,$Hctxhi
|| MVD $Hlo,$Hctxlo
loop0_15?:
.if .BIG_ENDIAN
MV B11,$T1hi
|| MV B10,$T1lo
.else
SWAP4 B10,$T1hi
|| SWAP4 B11,$T1lo
SWAP2 $T1hi,$T1hi
|| SWAP2 $T1lo,$T1lo
.endif
loop16_79?:
STW $T1hi,*$Xihi++[2]
|| STW $T1lo,*$Xilo++[2] ; X[i] = T1
|| ADD $Hhi,$T1hi,$T1hi
|| ADDU $Hlo,$T1lo,$T1carry:$T1lo ; T1 += h
|| SHRU $Ehi,14,$S1hi
|| SHL $Ehi,32-14,$S1lo
XOR $Fhi,$Ghi,$CHhi
|| XOR $Flo,$Glo,$CHlo
|| ADD KHI,$T1hi,$T1hi
|| ADDU KLO,$T1carry:$T1lo,$T1carry:$T1lo ; T1 += K512[i]
|| SHRU $Elo,14,$t0lo
|| SHL $Elo,32-14,$t0hi
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| AND $Ehi,$CHhi,$CHhi
|| AND $Elo,$CHlo,$CHlo
|| ROTL $Ghi,0,$Hhi
|| ROTL $Glo,0,$Hlo ; h = g
|| SHRU $Ehi,18,$t0hi
|| SHL $Ehi,32-18,$t0lo
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| XOR $Ghi,$CHhi,$CHhi
|| XOR $Glo,$CHlo,$CHlo ; Ch(e,f,g) = ((f^g)&e)^g
|| ROTL $Fhi,0,$Ghi
|| ROTL $Flo,0,$Glo ; g = f
|| SHRU $Elo,18,$t0lo
|| SHL $Elo,32-18,$t0hi
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| OR $Ahi,$Bhi,$MAJhi
|| OR $Alo,$Blo,$MAJlo
|| ROTL $Ehi,0,$Fhi
|| ROTL $Elo,0,$Flo ; f = e
|| SHRU $Ehi,41-32,$t0lo
|| SHL $Ehi,64-41,$t0hi
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| AND $Chi,$MAJhi,$MAJhi
|| AND $Clo,$MAJlo,$MAJlo
|| ROTL $Dhi,0,$Ehi
|| ROTL $Dlo,0,$Elo ; e = d
|| SHRU $Elo,41-32,$t0hi
|| SHL $Elo,64-41,$t0lo
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo ; Sigma1(e)
|| AND $Ahi,$Bhi,$t1hi
|| AND $Alo,$Blo,$t1lo
|| ROTL $Chi,0,$Dhi
|| ROTL $Clo,0,$Dlo ; d = c
|| SHRU $Ahi,28,$S0hi
|| SHL $Ahi,32-28,$S0lo
OR $t1hi,$MAJhi,$MAJhi
|| OR $t1lo,$MAJlo,$MAJlo ; Maj(a,b,c) = ((a|b)&c)|(a&b)
|| ADD $CHhi,$T1hi,$T1hi
|| ADDU $CHlo,$T1carry:$T1lo,$T1carry:$T1lo ; T1 += Ch(e,f,g)
|| ROTL $Bhi,0,$Chi
|| ROTL $Blo,0,$Clo ; c = b
|| SHRU $Alo,28,$t0lo
|| SHL $Alo,32-28,$t0hi
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| ADD $S1hi,$T1hi,$T1hi
|| ADDU $S1lo,$T1carry:$T1lo,$T1carry:$T1lo ; T1 += Sigma1(e)
|| ROTL $Ahi,0,$Bhi
|| ROTL $Alo,0,$Blo ; b = a
|| SHRU $Ahi,34-32,$t0lo
|| SHL $Ahi,64-34,$t0hi
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| ADD $MAJhi,$T1hi,$T2hi
|| ADDU $MAJlo,$T1carry:$T1lo,$T2carry:$T2lo ; T2 = T1+Maj(a,b,c)
|| SHRU $Alo,34-32,$t0hi
|| SHL $Alo,64-34,$t0lo
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| ADD $Ehi,$T1hi,$T1hi
|| ADDU $Elo,$T1carry:$T1lo,$T1carry:$T1lo ; T1 += e
|| [B0] BNOP loop0_15?
|| SHRU $Ahi,39-32,$t0lo
|| SHL $Ahi,64-39,$t0hi
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| [B0] LDNDW *$INP++,B11:B10 ; pre-fetch input
||[!B1] BNOP break?
|| SHRU $Alo,39-32,$t0hi
|| SHL $Alo,64-39,$t0lo
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo ; Sigma0(a)
|| ADD $T1carry,$T1hi,$Ehi
|| MV $T1lo,$Elo ; e = T1
||[!B0] LDW *${Xihi}[28],$T1hi
||[!B0] LDW *${Xilo}[28],$T1lo ; X[i+14]
ADD $S0hi,$T2hi,$T2hi
|| ADDU $S0lo,$T2carry:$T2lo,$T2carry:$T2lo ; T2 += Sigma0(a)
|| [B1] LDDW *$K512++,$Khi:$Klo ; pre-fetch K512[i]
NOP ; avoid cross-path stall
ADD $T2carry,$T2hi,$Ahi
|| MV $T2lo,$Alo ; a = T2
|| [B0] SUB B0,1,B0
;;===== branch to loop00_15? is taken here
NOP
;;===== branch to break? is taken here
LDW *${Xihi}[2],$T2hi
|| LDW *${Xilo}[2],$T2lo ; X[i+1]
|| SHRU $T1hi,19,$S1hi
|| SHL $T1hi,32-19,$S1lo
SHRU $T1lo,19,$t0lo
|| SHL $T1lo,32-19,$t0hi
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| SHRU $T1hi,61-32,$t0lo
|| SHL $T1hi,64-61,$t0hi
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| SHRU $T1lo,61-32,$t0hi
|| SHL $T1lo,64-61,$t0lo
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| SHRU $T1hi,6,$t0hi
|| SHL $T1hi,32-6,$t0lo
XOR $t0hi,$S1hi,$S1hi
|| XOR $t0lo,$S1lo,$S1lo
|| SHRU $T1lo,6,$t0lo
|| LDW *${Xihi}[18],$T1hi
|| LDW *${Xilo}[18],$T1lo ; X[i+9]
XOR $t0lo,$S1lo,$S1lo ; sigma1(Xi[i+14])
|| LDW *${Xihi}[0],$CHhi
|| LDW *${Xilo}[0],$CHlo ; X[i]
|| SHRU $T2hi,1,$S0hi
|| SHL $T2hi,32-1,$S0lo
SHRU $T2lo,1,$t0lo
|| SHL $T2lo,32-1,$t0hi
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| SHRU $T2hi,8,$t0hi
|| SHL $T2hi,32-8,$t0lo
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| SHRU $T2lo,8,$t0lo
|| SHL $T2lo,32-8,$t0hi
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| ADD $S1hi,$T1hi,$T1hi
|| ADDU $S1lo,$T1lo,$T1carry:$T1lo ; T1 = X[i+9]+sigma1()
|| [B1] BNOP loop16_79?
|| SHRU $T2hi,7,$t0hi
|| SHL $T2hi,32-7,$t0lo
XOR $t0hi,$S0hi,$S0hi
|| XOR $t0lo,$S0lo,$S0lo
|| ADD $CHhi,$T1hi,$T1hi
|| ADDU $CHlo,$T1carry:$T1lo,$T1carry:$T1lo ; T1 += X[i]
|| SHRU $T2lo,7,$t0lo
XOR $t0lo,$S0lo,$S0lo ; sigma0(Xi[i+1]
ADD $S0hi,$T1hi,$T1hi
|| ADDU $S0lo,$T1carry:$T1lo,$T1carry:$T1lo ; T1 += sigma0()
|| [B1] SUB B1,1,B1
NOP ; avoid cross-path stall
ADD $T1carry,$T1hi,$T1hi
;;===== branch to loop16_79? is taken here
break?:
ADD $Ahi,$Actxhi,$Ahi ; accumulate ctx
|| ADDU $Alo,$Actxlo,$Actxlo:$Alo
|| [A0] LDNDW *$INP++,B11:B10 ; pre-fetch input
|| [A0] ADDK -640,$K512 ; rewind pointer to K512
ADD $Bhi,$Bctxhi,$Bhi
|| ADDU $Blo,$Bctxlo,$Bctxlo:$Blo
|| [A0] LDDW *$K512++,$Khi:$Klo ; pre-fetch K512[0]
ADD $Chi,$Cctxhi,$Chi
|| ADDU $Clo,$Cctxlo,$Cctxlo:$Clo
|| ADD $Actxlo,$Ahi,$Ahi
||[!A0] MV $CTXA,$CTXB
ADD $Dhi,$Dctxhi,$Dhi
|| ADDU $Dlo,$Dctxlo,$Dctxlo:$Dlo
|| ADD $Bctxlo,$Bhi,$Bhi
||[!A0] STW $Ahi,*${CTXA}[0^.LITTLE_ENDIAN] ; save ctx
||[!A0] STW $Alo,*${CTXB}[1^.LITTLE_ENDIAN]
ADD $Ehi,$Ectxhi,$Ehi
|| ADDU $Elo,$Ectxlo,$Ectxlo:$Elo
|| ADD $Cctxlo,$Chi,$Chi
|| [A0] BNOP outerloop?
||[!A0] STW $Bhi,*${CTXA}[2^.LITTLE_ENDIAN]
||[!A0] STW $Blo,*${CTXB}[3^.LITTLE_ENDIAN]
ADD $Fhi,$Fctxhi,$Fhi
|| ADDU $Flo,$Fctxlo,$Fctxlo:$Flo
|| ADD $Dctxlo,$Dhi,$Dhi
||[!A0] STW $Chi,*${CTXA}[4^.LITTLE_ENDIAN]
||[!A0] STW $Clo,*${CTXB}[5^.LITTLE_ENDIAN]
ADD $Ghi,$Gctxhi,$Ghi
|| ADDU $Glo,$Gctxlo,$Gctxlo:$Glo
|| ADD $Ectxlo,$Ehi,$Ehi
||[!A0] STW $Dhi,*${CTXA}[6^.LITTLE_ENDIAN]
||[!A0] STW $Dlo,*${CTXB}[7^.LITTLE_ENDIAN]
ADD $Hhi,$Hctxhi,$Hhi
|| ADDU $Hlo,$Hctxlo,$Hctxlo:$Hlo
|| ADD $Fctxlo,$Fhi,$Fhi
||[!A0] STW $Ehi,*${CTXA}[8^.LITTLE_ENDIAN]
||[!A0] STW $Elo,*${CTXB}[9^.LITTLE_ENDIAN]
ADD $Gctxlo,$Ghi,$Ghi
||[!A0] STW $Fhi,*${CTXA}[10^.LITTLE_ENDIAN]
||[!A0] STW $Flo,*${CTXB}[11^.LITTLE_ENDIAN]
ADD $Hctxlo,$Hhi,$Hhi
||[!A0] STW $Ghi,*${CTXA}[12^.LITTLE_ENDIAN]
||[!A0] STW $Glo,*${CTXB}[13^.LITTLE_ENDIAN]
;;===== branch to outerloop? is taken here
STW $Hhi,*${CTXA}[14^.LITTLE_ENDIAN]
|| STW $Hlo,*${CTXB}[15^.LITTLE_ENDIAN]
|| MVK -40,B0
ADD FP,B0,SP ; destroy circular buffer
|| LDDW *FP[-4],A11:A10
LDDW *SP[2],A13:A12
|| LDDW *FP[-2],B11:B10
LDDW *SP[4],B13:B12
|| BNOP RA
LDW *++SP(40),FP ; restore frame pointer
MVK 0,B0
MVC B0,AMR ; clear AMR
NOP 2 ; wait till FP is committed
.endasmfunc
.sect ".const:sha_asm"
.align 128
K512:
.uword 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
.uword 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
.uword 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
.uword 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
.uword 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
.uword 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
.uword 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
.uword 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
.uword 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
.uword 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
.uword 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
.uword 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
.uword 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
.uword 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
.uword 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
.uword 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
.uword 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
.uword 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
.uword 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
.uword 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
.uword 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
.uword 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
.uword 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
.uword 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
.uword 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
.uword 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
.uword 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
.uword 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
.uword 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
.uword 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
.uword 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
.uword 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
.uword 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
.uword 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
.uword 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
.uword 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
.uword 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
.uword 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
.uword 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
.uword 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
.cstring "SHA512 block transform for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
.align 4
___
print $code;
close STDOUT;

View File

@@ -65,7 +65,7 @@ int OPENSSL_issetugid(void)
return issetugid();
}
#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(_TMS320C6X)
int OPENSSL_issetugid(void)
{

10
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
# include <io.h>
# include <fcntl.h>
# if !defined(OPENSSL_FIPSCANISTER)
# include <io.h>
# include <fcntl.h>
# endif
# ifdef OPENSSL_SYS_WINCE
# define OPENSSL_NO_POSIX_IO
@@ -668,7 +670,7 @@ extern char *sys_errlist[]; extern int sys_nerr;
#if defined(OPENSSL_SYS_WINDOWS)
# define strcasecmp _stricmp
# define strncasecmp _strnicmp
#elif defined(OPENSSL_SYS_VMS)
#elif defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_DSPBIOS)
/* VMS below version 7.0 doesn't have strcasecmp() */
# include "o_str.h"
# define strcasecmp OPENSSL_strcasecmp

View File

@@ -99,7 +99,7 @@ static int AESTest(EVP_CIPHER_CTX *ctx,
{
const EVP_CIPHER *cipher = NULL;
if (strcasecmp(amode, "CBC") == 0)
if (fips_strcasecmp(amode, "CBC") == 0)
{
switch (akeysz)
{
@@ -117,7 +117,7 @@ static int AESTest(EVP_CIPHER_CTX *ctx,
}
}
else if (strcasecmp(amode, "ECB") == 0)
else if (fips_strcasecmp(amode, "ECB") == 0)
{
switch (akeysz)
{
@@ -134,7 +134,7 @@ static int AESTest(EVP_CIPHER_CTX *ctx,
break;
}
}
else if (strcasecmp(amode, "CFB128") == 0)
else if (fips_strcasecmp(amode, "CFB128") == 0)
{
switch (akeysz)
{
@@ -169,7 +169,7 @@ static int AESTest(EVP_CIPHER_CTX *ctx,
break;
}
}
else if(!strcasecmp(amode,"CFB1"))
else if(!fips_strcasecmp(amode,"CFB1"))
{
switch (akeysz)
{
@@ -186,7 +186,7 @@ static int AESTest(EVP_CIPHER_CTX *ctx,
break;
}
}
else if(!strcasecmp(amode,"CFB8"))
else if(!fips_strcasecmp(amode,"CFB8"))
{
switch (akeysz)
{
@@ -215,7 +215,7 @@ static int AESTest(EVP_CIPHER_CTX *ctx,
}
if (FIPS_cipherinit(ctx, cipher, aKey, iVec, dir) <= 0)
return 0;
if(!strcasecmp(amode,"CFB1"))
if(!fips_strcasecmp(amode,"CFB1"))
M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
if (dir)
FIPS_cipher(ctx, ciphertext, plaintext, len);
@@ -635,10 +635,8 @@ static int proc_file(char *rqfile, char *rspfile)
char *xp, *pp = ibuf+2;
int n;
if (akeysz)
{ /* insert current time & date */
time_t rtim = time(0);
fputs("# ", rfp);
copy_line(ctime(&rtim), rfp);
{
copy_line(ibuf, rfp);
}
else
{
@@ -876,11 +874,11 @@ int main(int argc, char **argv)
if (argc > 1)
{
if (strcasecmp(argv[1], "-d") == 0)
if (fips_strcasecmp(argv[1], "-d") == 0)
{
d_opt = 1;
}
else if (strcasecmp(argv[1], "-f") == 0)
else if (fips_strcasecmp(argv[1], "-f") == 0)
{
d_opt = 0;
}

View File

@@ -75,10 +75,11 @@ int main(int argc, char **argv)
#include "fips_utl.h"
static char buf[204800];
static char lbuf[204800];
static void gcmtest(FILE *in, FILE *out, int encrypt)
{
char buf[2048];
char lbuf[2048];
char *keyword, *value;
int keylen = -1, ivlen = -1, aadlen = -1, taglen = -1, ptlen = -1;
int rv;
@@ -266,8 +267,6 @@ static void gcmtest(FILE *in, FILE *out, int encrypt)
static void xtstest(FILE *in, FILE *out)
{
char buf[204800];
char lbuf[204800];
char *keyword, *value;
int inlen = 0;
int encrypt = 0;
@@ -340,8 +339,6 @@ static void xtstest(FILE *in, FILE *out)
static void ccmtest(FILE *in, FILE *out)
{
char buf[200048];
char lbuf[200048];
char *keyword, *value;
long l;
unsigned char *Key = NULL, *Nonce = NULL;

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

@@ -356,10 +356,8 @@ static int tproc_file(char *rqfile, char *rspfile)
char *xp, *pp = ibuf+2;
int n;
if(*amode)
{ /* insert current time & date */
time_t rtim = time(0);
fputs("# ", rfp);
copy_line(ctime(&rtim), rfp);
{
copy_line(ibuf, rfp);
}
else
{

View File

@@ -286,7 +286,7 @@ int main(int argc, char **argv)
return 0;
parse_error:
fprintf(stderr, "Error Parsing request file\n");
exit(1);
return 1;
}
#endif

View File

@@ -62,8 +62,10 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef NO_SYS_TYPES_H
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "e_os.h"

View File

@@ -46,7 +46,8 @@ static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
if (strcmp(keyword, "L"))
return 0;
*pL = atoi(value);
strcpy(line, p + 1);
strcpy(lbuf, p + 1);
strcpy(line, lbuf);
if (pmd)
p = strchr(line, ',');
else
@@ -552,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))
{
@@ -578,8 +584,7 @@ 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);
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,12 +173,12 @@ 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;
}
rv = 1;
if (test_err == 0)
rv = 1;
err:

View File

@@ -81,7 +81,7 @@ static int fips_started = 0;
static int fips_is_owning_thread(void);
static int fips_set_owning_thread(void);
static int fips_clear_owning_thread(void);
static unsigned char *fips_signature_witness(void);
static const unsigned char *fips_signature_witness(void);
#define fips_w_lock() CRYPTO_w_lock(CRYPTO_LOCK_FIPS)
#define fips_w_unlock() CRYPTO_w_unlock(CRYPTO_LOCK_FIPS)
@@ -148,7 +148,10 @@ void fips_set_selftest_fail(void)
extern const void *FIPS_text_start(), *FIPS_text_end();
extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
unsigned char FIPS_signature [20] = { 0 };
#ifdef _TMS320C6X
const
#endif
unsigned char FIPS_signature [20] = { 0, 0xff };
__fips_constseg
static const char FIPS_hmac_key[]="etaonrishdlcupfm";
@@ -413,9 +416,8 @@ int fips_clear_owning_thread(void)
return ret;
}
unsigned char *fips_signature_witness(void)
const unsigned char *fips_signature_witness(void)
{
extern unsigned char FIPS_signature[];
return FIPS_signature;
}

View File

@@ -29,12 +29,15 @@ 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))) || \
(defined(__NetBSD__) && (defined(__powerpc__) || defined(__i386))) || \
(defined(__linux) && ((defined(__PPC__) && !defined(__PPC64__)) || \
defined(__arm__) || defined(__arm))) || \
(defined(__APPLE__) /* verified on all MacOS X & iOS flavors */)|| \
(defined(_TMS320C6X)) || \
(defined(_WIN32) && defined(_MSC_VER))
# define FIPS_REF_POINT_IS_CROSS_COMPILER_AWARE
# endif
@@ -70,6 +73,10 @@ const unsigned int FIPS_text_startX[]=
# pragma const_seg("fipsro$a")
# pragma const_seg()
__declspec(allocate("fipsro$a"))
# elif defined(_TMS320C6X)
# pragma CODE_SECTION(instruction_pointer,".fips_text:start")
# pragma CODE_SECTION(FIPS_ref_point,".fips_text:start")
# pragma DATA_SECTION(FIPS_rodata_start,".fips_const:start")
# endif
const unsigned int FIPS_rodata_start[]=
{ 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
@@ -87,6 +94,10 @@ const unsigned int FIPS_text_endX[]=
# pragma const_seg("fipsro$z")
# pragma const_seg()
__declspec(allocate("fipsro$z"))
# elif defined(_TMS320C6X)
# pragma CODE_SECTION(instruction_pointer,".fips_text:end")
# pragma CODE_SECTION(FIPS_ref_point,".fips_text:end")
# pragma DATA_SECTION(FIPS_rodata_end,".fips_const:end")
# endif
const unsigned int FIPS_rodata_end[]=
{ 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b };

View File

@@ -53,6 +53,12 @@
int lib$initialize();
globaldef int (*lib_init_ref)() = lib$initialize;
# pragma __standard
#elif defined(_TMS320C6X)
# if defined(__TI_EABI__)
asm("\t.sect \".init_array\"\n\t.align 4\n\t.field FINGERPRINT_premain,32");
# else
asm("\t.sect \".pinit\"\n\t.align 4\n\t.field _FINGERPRINT_premain,32");
# endif
#elif 0
The rest has to be taken care of through command line:

View File

@@ -1 +1 @@
HMAC-SHA1(fips_premain.c)= 1eaf66f76187877ff403708a2948d240f92736a0
HMAC-SHA1(fips_premain.c)= 65b20c3cec235cec85af848e1cd2dfdfa101804a

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

@@ -495,6 +495,7 @@ my $onedir = 0;
my $filter = "";
my $tvdir;
my $tprefix;
my $sfprefix = "";
my $debug = 0;
my $quiet = 0;
my $notest = 0;
@@ -615,6 +616,9 @@ foreach (@ARGV) {
elsif (/--script-tprefix=(.*)$/) {
$stprefix = $1;
}
elsif (/--script-fprefix=(.*)$/) {
$sfprefix = $1;
}
elsif (/--mkdir=(.*)$/) {
$mkcmd = $1;
}
@@ -1017,6 +1021,10 @@ END
$out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|;
my $outdir = $out;
$outdir =~ s|/[^/]*$||;
if ( !-d $outdir && ($outfile eq "" || $minimal_script)) {
print STDERR "DEBUG: Creating directory $outdir\n" if $debug;
mkdir($outdir) || die "Can't create directory $outdir";
}
if ($outfile ne "") {
if ($win32) {
$outdir =~ tr|/|\\|;
@@ -1039,12 +1047,9 @@ END
}
$lastdir = $outdir;
}
} elsif ( !-d $outdir ) {
print STDERR "DEBUG: Creating directory $outdir\n" if $debug;
mkdir($outdir) || die "Can't create directory $outdir";
}
}
my $cmd = "$tcmd \"$req\" \"$out\"";
my $cmd = "$tcmd \"$sfprefix$req\" \"$sfprefix$out\"";
print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify );
if ($outfile ne "") {
if ($minimal_script) {

View File

@@ -589,6 +589,7 @@
#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 AES_ctr32_encrypt fips_aes_ctr32_encrypt
#define BN_from_montgomery fips_bn_from_montgomery
#define BN_num_bits_word FIPS_bn_num_bits_word
#define DES_SPtrans fips_des_sptrans
@@ -667,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

@@ -182,7 +182,7 @@ int main(int argc,char **argv)
int r, nid = 0;
int pr = 0;
char buf[2048], lbuf[2048];
unsigned char randout[2048];
unsigned char *randout = NULL;
char *keyword = NULL, *value = NULL;
unsigned char *ent = NULL, *nonce = NULL, *pers = NULL, *adin = NULL;
@@ -298,6 +298,8 @@ int main(int argc,char **argv)
else
exit(1);
}
if (!strcmp(keyword, "[ReturnedBitsLen"))
randoutlen = atoi(value) / 8;
if (!strcmp(keyword, "EntropyInput"))
{
@@ -327,7 +329,11 @@ int main(int argc,char **argv)
FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0,
test_nonce, 0);
FIPS_drbg_set_app_data(dctx, &t);
randoutlen = (int)FIPS_drbg_get_blocklength(dctx);
if (randoutlen == 0)
randoutlen = (int)FIPS_drbg_get_blocklength(dctx);
if (randout)
OPENSSL_free(randout);
randout = OPENSSL_malloc(randoutlen);
r = FIPS_drbg_instantiate(dctx, pers, perslen);
if (!r)
{
@@ -406,6 +412,8 @@ int main(int argc,char **argv)
}
}
if (randout)
OPENSSL_free(randout);
if (in && in != stdin)
fclose(in);
if (out && out != stdout)

View File

@@ -66,7 +66,7 @@
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/fips_rand.h>
#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS))
#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYSNAME_DSPBIOS))
# include <sys/time.h>
#endif
#if defined(OPENSSL_SYS_VXWORKS)
@@ -232,8 +232,13 @@ void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr)
{
#ifdef OPENSSL_SYS_WIN32
FILETIME ft;
#ifdef _WIN32_WCE
SYSTEMTIME t;
#endif
#elif defined(OPENSSL_SYS_VXWORKS)
struct timespec ts;
#elif defined(OPENSSL_SYSNAME_DSPBIOS)
unsigned long long TSC, OPENSSL_rdtsc();
#else
struct timeval tv;
#endif
@@ -243,7 +248,12 @@ void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr)
#endif
#ifdef OPENSSL_SYS_WIN32
#ifdef _WIN32_WCE
GetSystemTime(&t);
SystemTimeToFileTime(&t, &ft);
#else
GetSystemTimeAsFileTime(&ft);
#endif
buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff);
buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff);
buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff);
@@ -262,6 +272,16 @@ void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr)
buf[5] = (unsigned char) ((ts.tv_nsec >> 8) & 0xff);
buf[6] = (unsigned char) ((ts.tv_nsec >> 16) & 0xff);
buf[7] = (unsigned char) ((ts.tv_nsec >> 24) & 0xff);
#elif defined(OPENSSL_SYSNAME_DSPBIOS)
TSC = OPENSSL_rdtsc();
buf[0] = (unsigned char) (TSC & 0xff);
buf[1] = (unsigned char) ((TSC >> 8) & 0xff);
buf[2] = (unsigned char) ((TSC >> 16) & 0xff);
buf[3] = (unsigned char) ((TSC >> 24) & 0xff);
buf[4] = (unsigned char) ((TSC >> 32) & 0xff);
buf[5] = (unsigned char) ((TSC >> 40) & 0xff);
buf[6] = (unsigned char) ((TSC >> 48) & 0xff);
buf[7] = (unsigned char) ((TSC >> 56) & 0xff);
#else
gettimeofday(&tv,NULL);
buf[0] = (unsigned char) (tv.tv_sec & 0xff);

View File

@@ -288,8 +288,11 @@ int FIPS_rsa_sign_digest(RSA *rsa, const unsigned char *md, int md_len,
*siglen=j;
}
psserr:
OPENSSL_cleanse(sbuf, i);
OPENSSL_free(sbuf);
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=

View File

@@ -208,6 +208,7 @@ int FIPS_cipherinit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
break;
case EVP_CIPH_CTR_MODE:
ctx->num = 0;
/* Don't reuse IV for CTR mode */
if(iv)
memcpy(ctx->iv, iv, M_EVP_CIPHER_CTX_iv_length(ctx));

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

@@ -1,7 +1,10 @@
@echo off
rem @echo off
SET ASM=%1
SET EXARG=
SET MFILE=ntdll.mak
if NOT X%OSVERSION% == X goto wince
if NOT X%PROCESSOR_ARCHITECTURE% == X goto defined
@@ -42,6 +45,14 @@ SET TARGET=VC-WIN64A
if x%ASM% == xno-asm goto compile
SET ASM=nasm
goto compile
:wince
echo Auto Configuring for WinCE
SET TARGET=VC-CE
SET MFILE=cedll.mak
:compile
if x%ASM% == xno-asm SET EXARG=no-asm
@@ -52,13 +63,13 @@ echo on
perl util\mkfiles.pl >MINFO
@if ERRORLEVEL 1 goto error
perl util\mk1mf.pl dll %ASM% %TARGET% >ms\ntdll.mak
perl util\mk1mf.pl dll %ASM% %TARGET% >ms\%MFILE%
@if ERRORLEVEL 1 goto error
nmake -f ms\ntdll.mak clean
nmake -f ms\ntdll.mak
nmake -f ms\%MFILE% clean
nmake -f ms\%MFILE%
@if ERRORLEVEL 1 goto error
nmake -f ms\ntdll.mak install
nmake -f ms\%MFILE% install
@if ERRORLEVEL 1 goto error
@echo.

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);
@@ -89,6 +150,7 @@ extern int fips_rsavtest_main(int argc, char **argv);
extern int fips_shatest_main(int argc, char **argv);
extern int fips_test_suite_main(int argc, char **argv);
#if !defined(_TMS320C6400_PLUS)
#include "fips_aesavs.c"
#include "fips_cmactest.c"
#include "fips_desmovs.c"
@@ -106,6 +168,28 @@ extern int fips_test_suite_main(int argc, char **argv);
#include "fips_shatest.c"
#include "fips_test_suite.c"
#else
#include "aes/fips_aesavs.c"
#include "cmac/fips_cmactest.c"
#include "des/fips_desmovs.c"
#include "dh/fips_dhvs.c"
#include "rand/fips_drbgvs.c"
#include "dsa/fips_dssvs.c"
#include "ecdh/fips_ecdhvs.c"
#include "ecdsa/fips_ecdsavs.c"
#include "aes/fips_gcmtest.c"
#include "hmac/fips_hmactest.c"
#include "rand/fips_rngvs.c"
#include "rsa/fips_rsagtest.c"
#include "rsa/fips_rsastest.c"
#include "rsa/fips_rsavtest.c"
#include "sha/fips_shatest.c"
#include "fips_test_suite.c"
#pragma DATA_SECTION(aucCmBootDspLoad, "BootDspSection");
volatile unsigned char aucCmBootDspLoad[8*1024];
#endif
typedef struct
{
const char *name;
@@ -221,7 +305,7 @@ static int run_prg(int argc, char **argv)
int main(int argc, char **argv)
{
char buf[1024];
static char buf[1024];
char **args = argv + 1;
const char *sname = "fipstests.sh";
ARGS arg;
@@ -238,6 +322,20 @@ int main(int argc, char **argv)
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
#endif
#if defined(_TMS320C6400_PLUS)
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);

32
util/fips_standalone_sha1 Normal file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env perl
#
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
unshift(@INC,$dir);
require "hmac_sha1.pl";
(!@ARV[0] && -f @ARGV[$#ARGV]) || die "usage: $0 [-verify] file";
$verify=shift if (@ARGV[0] eq "-verify");
sysopen(FD,@ARGV[0],0) || die "$!";
binmode(FD);
my $ctx = HMAC->Init("etaonrishdlcupfm");
while (read(FD,$blob,4*1024)) { $ctx->Update($blob); }
close(FD);
my $signature = unpack("H*",$ctx->Final());
print "HMAC-SHA1(@ARGV[0])= $signature\n";
if ($verify) {
open(FD,"<@ARGV[0].sha1") || die "$!";
$line = <FD>;
close(FD);
exit(0) if ($line =~ /HMAC\-SHA1\([^\)]*\)=\s*([0-9a-f]+)/i &&
$1 eq $signature);
die "signature mismatch";
}

View File

@@ -8,9 +8,6 @@ my @ARGS = @ARGV;
my $top = shift @ARGS;
my $target = shift @ARGS;
my $tmptarg = $target;
$tmptarg =~ s/\.[^\\\/\.]+$/.tmp/;
my $runasm = 1;
@@ -40,43 +37,31 @@ while (<IN>)
last if (/assembler/)
}
# Store all renames.
# Store all renames [noting minimal length].
my $minlen=0x10000;
while (<IN>)
{
if (/^#define\s+(\w+)\s+(\w+)\b/)
if (/^#define\s+_?(\w+)\s+_?(\w+)\b/)
{
$edits{$1} = $2;
my $len = length($1);
$minlen = $len if ($len<$minlen);
}
}
my ($from, $to);
open(IN,"$target") || die "Can't open $target for reading";
#delete any temp file lying around
@code = <IN>; # suck in whole file
unlink $tmptarg;
close IN;
#rename target temporarily
my $rencnt = 0;
# On windows the previous file doesn't always close straight away
# so retry the rename operation a few times if it fails.
while (!rename($target, $tmptarg))
{
sleep 2;
die "Can't rename $target" if ($rencnt++ > 10);
}
open(OUT,">$target") || die "Can't open $target for writing";
#edit target
open(IN,$tmptarg) || die "Can't open temporary file";
open(OUT, ">$target") || die "Can't open output file $target";
while (<IN>)
{
while (($from, $to) = each %edits)
{
s/(\b_*)$from(\b)/$1$to$2/g;
}
print OUT $_;
}
foreach $line (@code)
{
$line =~ s/\b(_?)(\w{$minlen,})\b/$1.($edits{$2} or $2)/geo;
print OUT $line;
}
close OUT;
@@ -87,14 +72,5 @@ if ($runasm)
my $rv = $?;
# restore target
unlink $target;
rename $tmptarg, $target;
die "Error executing assembler!" if $rv != 0;
}
else
{
# Don't care about target
unlink $tmptarg;
}

View File

@@ -58,7 +58,7 @@ while (<STDIN>)
}
else
{
next unless (/^(fips\/|crypto|util|test|include|ms)/);
next unless (/^(fips\/|crypto|util|test|include|ms|c6x)/);
}
if (/^crypto\/([^\/]+)/)
{

View File

@@ -33,14 +33,24 @@ check_hash($sha1_exe, "fipscanister.lib");
print "Integrity check OK\n";
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;
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");
@@ -61,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) = @_;

196
util/hmac_sha1.pl Executable file
View File

@@ -0,0 +1,196 @@
#!/usr/bin/env perl
#
# Copyright (c) 2011 The OpenSSL Project.
#
######################################################################
#
# SHA1 and HMAC in Perl by <appro@openssl.org>.
#
{ package SHA1;
use integer;
{
################################### SHA1 block code generator
my @V = ('$A','$B','$C','$D','$E');
my $i;
sub XUpdate {
my $ret;
$ret="(\$T=\$W[($i-16)%16]^\$W[($i-14)%16]^\$W[($i-8)%16]^\$W[($i-3)%16],\n\t";
if ((1<<31)<<1) {
$ret.=" \$W[$i%16]=((\$T<<1)|(\$T>>31))&0xffffffff)\n\t ";
} else {
$ret.=" \$W[$i%16]=(\$T<<1)|((\$T>>31)&1))\n\t ";
}
}
sub tail {
my ($a,$b,$c,$d,$e)=@V;
my $ret;
if ((1<<31)<<1) {
$ret.="(($a<<5)|($a>>27));\n\t";
$ret.="$b=($b<<30)|($b>>2); $e&=0xffffffff; #$b&=0xffffffff;\n\t";
} else {
$ret.="(($a<<5)|($a>>27)&0x1f);\n\t";
$ret.="$b=($b<<30)|($b>>2)&0x3fffffff;\n\t";
}
$ret;
}
sub BODY_00_15 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=\$W[$i]+0x5a827999+((($c^$d)&$b)^$d)+".tail();
}
sub BODY_16_19 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0x5a827999+((($c^$d)&$b)^$d)+".tail();
}
sub BODY_20_39 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0x6ed9eba1+($b^$c^$d)+".tail();
}
sub BODY_40_59 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0x8f1bbcdc+(($b&$c)|(($b|$c)&$d))+".tail();
}
sub BODY_60_79 {
my ($a,$b,$c,$d,$e)=@V;
"$e+=".XUpdate()."+0xca62c1d6+($b^$c^$d)+".tail();
}
my $sha1_impl =
'sub block {
my $self = @_[0];
my @W = unpack("N16",@_[1]);
my ($A,$B,$C,$D,$E,$T) = @{$self->{H}};
';
$sha1_impl.='
$A &= 0xffffffff;
$B &= 0xffffffff;
' if ((1<<31)<<1);
for($i=0;$i<16;$i++){ $sha1_impl.=BODY_00_15(); unshift(@V,pop(@V)); }
for(;$i<20;$i++) { $sha1_impl.=BODY_16_19(); unshift(@V,pop(@V)); }
for(;$i<40;$i++) { $sha1_impl.=BODY_20_39(); unshift(@V,pop(@V)); }
for(;$i<60;$i++) { $sha1_impl.=BODY_40_59(); unshift(@V,pop(@V)); }
for(;$i<80;$i++) { $sha1_impl.=BODY_60_79(); unshift(@V,pop(@V)); }
$sha1_impl.='
$self->{H}[0]+=$A; $self->{H}[1]+=$B; $self->{H}[2]+=$C;
$self->{H}[3]+=$D; $self->{H}[4]+=$E; }';
#print $sha1_impl,"\n";
eval($sha1_impl); # generate code
}
sub Init {
my $class = shift; # multiple instances...
my $self = {};
bless $self,$class;
$self->{H} = [0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0];
$self->{N} = 0;
return $self;
}
sub Update {
my $self = shift;
my $msg;
foreach $msg (@_) {
my $len = length($msg);
my $num = length($self->{buf});
my $off = 0;
$self->{N} += $len;
if (($num+$len)<64)
{ $self->{buf} .= $msg; next; }
elsif ($num)
{ $self->{buf} .= substr($msg,0,($off=64-$num));
$self->block($self->{buf});
}
while(($off+64) <= $len)
{ $self->block(substr($msg,$off,64));
$off += 64;
}
$self->{buf} = substr($msg,$off);
}
return $self;
}
sub Final {
my $self = shift;
my $num = length($self->{buf});
$self->{buf} .= chr(0x80); $num++;
if ($num>56)
{ $self->{buf} .= chr(0)x(64-$num);
$self->block($self->{buf});
$self->{buf}=undef;
$num=0;
}
$self->{buf} .= chr(0)x(56-$num);
$self->{buf} .= pack("N2",($self->{N}>>29)&0x7,$self->{N}<<3);
$self->block($self->{buf});
return pack("N*",@{$self->{H}});
}
sub Selftest {
my $hash;
$hash=SHA1->Init()->Update('abc')->Final();
die "SHA1 test#1" if (unpack("H*",$hash) ne 'a9993e364706816aba3e25717850c26c9cd0d89d');
$hash=SHA1->Init()->Update('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')->Final();
die "SHA1 test#2" if (unpack("H*",$hash) ne '84983e441c3bd26ebaae4aa1f95129e5e54670f1');
#$hash=SHA1->Init()->Update('a'x1000000)->Final();
#die "SHA1 test#3" if (unpack("H*",$hash) ne '34aa973cd4c4daa4f61eeb2bdbad27316534016f');
}
}
{ package HMAC;
sub Init {
my $class = shift;
my $key = shift;
my $self = {};
bless $self,$class;
if (length($key)>64) {
$key = SHA1->Init()->Update($key)->Final();
}
$key .= chr(0x00)x(64-length($key));
my @ikey = map($_^=0x36,unpack("C*",$key));
($self->{hash} = SHA1->Init())->Update(pack("C*",@ikey));
$self->{okey} = pack("C*",map($_^=0x36^0x5c,@ikey));
return $self;
}
sub Update {
my $self = shift;
$self->{hash}->Update(@_);
return $self;
}
sub Final {
my $self = shift;
my $ihash = $self->{hash}->Final();
return SHA1->Init()->Update($self->{okey},$ihash)->Final();
}
sub Selftest {
my $hmac;
$hmac = HMAC->Init('0123456789:;<=>?@ABC')->Update('Sample #2')->Final();
die "HMAC test" if (unpack("H*",$hmac) ne '0922d3405faa3d194f82a45830737d5cc6c75d24');
}
}
1;

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

@@ -23,6 +23,7 @@ local $fips_canister_path = "";
my $fips_premain_dso_exe_path = "";
my $fips_premain_c_path = "";
my $fips_sha1_exe_path = "";
my $fips_sha1_exe_build = 1;
local $fipscanisterbuild = 0;
@@ -248,6 +249,10 @@ elsif (($platform eq "netware-clib") || ($platform eq "netware-libc") ||
$BSDSOCK=1 if ($platform eq "netware-libc-bsdsock") || ($platform eq "netware-clib-bsdsock");
require 'netware.pl';
}
elsif ($platform eq "c64xplus")
{
require "TI_CGTOOLS.pl";
}
else
{
require "unix.pl";
@@ -500,8 +505,16 @@ if ($fips)
{
if ($fips_sha1_exe_path eq "")
{
$fips_sha1_exe_path =
"\$(BIN_D)${o}fips_standalone_sha1$exep";
$fips_sha1_exe_path = $ENV{"FIPS_SHA1_PATH"};
if (defined $fips_sha1_exe_path)
{
$fips_sha1_exe_build = 0;
}
else
{
$fips_sha1_exe_path =
"\$(BIN_D)${o}fips_standalone_sha1$exep";
}
}
}
else
@@ -545,7 +558,7 @@ if ($fips)
if ($fipscanisteronly)
{
$build_targets = "\$(O_FIPSCANISTER) \$(T_EXE)";
$build_targets = "\$(O_FIPSCANISTER)";
$libs_dep = "";
}
@@ -567,9 +580,14 @@ if ($fipscanisteronly)
\$(CP) \"fips${o}fips_premain.c.sha1\" \"\$(INSTALLTOP)${o}lib\"
\$(CP) \"\$(INCO_D)${o}fips.h\" \"\$(INSTALLTOP)${o}include${o}openssl\"
\$(CP) \"\$(INCO_D)${o}fips_rand.h\" \"\$(INSTALLTOP)${o}include${o}openssl\"
\$(CP) "\$(BIN_D)${o}fips_standalone_sha1$exep" \"\$(INSTALLTOP)${o}bin\"
\$(CP) \"util${o}fipslink.pl\" \"\$(INSTALLTOP)${o}bin\"
EOF
if ($fips_sha1_exe_build)
{
$extra_install .= <<"EOF";
\$(CP) "\$(BIN_D)${o}fips_standalone_sha1$exep" \"\$(INSTALLTOP)${o}bin\"
EOF
}
}
elsif ($shlib)
{
@@ -716,7 +734,7 @@ LIBS_DEP=$libs_dep
EOF
$rules=<<"EOF";
all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers \$(FIPS_SHA1_EXE) $build_targets
all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers $build_targets
banner:
$banner
@@ -744,7 +762,11 @@ headers: \$(HEADER) \$(EXHEADER)
lib: \$(LIBS_DEP) \$(E_SHLIB)
exe: \$(T_EXE) \$(BIN_D)$o\$(E_EXE)$exep
exe: \$(BIN_D)$o\$(E_EXE)$exep
build_tests: \$(T_EXE)
build_algvs: \$(T_SRC) \$(BIN_D)${o}fips_algvs$exep
install: all
\$(MKDIR) \"\$(INSTALLTOP)\"
@@ -842,10 +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",
"\$(APP_CFLAGS)");
}
foreach (values %lib_nam)
@@ -878,6 +903,7 @@ EOF
}
$defs.=&do_defs("T_EXE",$test,"\$(TEST_D)",$exep);
$defs.=&do_defs("T_SRC",$test,"\$(TMP_D)",".c");
foreach (split(/\s+/,$test))
{
my $t_libs;
@@ -899,8 +925,11 @@ foreach (split(/\s+/,$test))
$tt="\$(OBJ_D)${o}$t${obj}";
$rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","$t_libs \$(EX_LIBS)", $ltype);
$rules.=&do_copy_rule("\$(TMP_D)",$_,".c");
}
$rules.=&do_link_rule("\$(TEST_D)${o}fips_algvs$exep","\$(OBJ_D)${o}fips_algvs$obj","\$(LIBS_DEP)","\$(O_FIPSCANISTER) \$(EX_LIBS)", 2) if $fips;
$defs.=&do_defs("E_SHLIB",$engines . $otherlibs,"\$(ENG_D)",$shlibp);
foreach (split(/\s+/,$engines))
@@ -955,20 +984,20 @@ if ($fips)
"\$(OBJ_D)${o}fips_start$obj",
"\$(FIPSOBJ)",
"\$(OBJ_D)${o}fips_end$obj",
"\$(FIPS_SHA1_EXE)", "");
"");
# FIXME
$rules.=&do_link_rule("\$(FIPS_SHA1_EXE)",
"\$(OBJ_D)${o}fips_standalone_sha1$obj \$(OBJ_D)${o}sha1dgst$obj $sha1_asm_obj",
"","\$(EX_LIBS)", 1);
"","\$(EX_LIBS)", 1) if $fips_sha1_exe_build;
}
else
{
$rules.=&do_link_rule("\$(FIPS_SHA1_EXE)",
"\$(OBJ_D)${o}fips_standalone_sha1$obj \$(O_FIPSCANISTER)",
"","", 1);
"","", 1) if $fips_sha1_exe_build;
}
$rules.=&do_link_rule("\$(PREMAIN_DSO_EXE)","\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj \$(CRYPTOOBJ) \$(O_FIPSCANISTER)","","\$(EX_LIBS)", 1);
$rules.=&do_link_rule("\$(PREMAIN_DSO_EXE)","\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj \$(CRYPTOOBJ) \$(O_FIPSCANISTER)","","\$(EX_LIBS)", 1) unless defined $ENV{"FIPS_SIG"};
}
@@ -1192,6 +1221,10 @@ sub do_compile_rule
{
$ret.=&Sasm_compile_target("$to${o}$n$obj",$s,$n);
}
elsif (-f ($s="${d}${o}asm${o}${n}.asm"))
{
$ret.=&cc_compile_target("$to${o}$n$obj","$s",$ex);
}
else { die "no rule for $_"; }
}
return($ret);

169
util/msincore Executable file
View File

@@ -0,0 +1,169 @@
#!/usr/bin/env perl
#
# Copyright (c) 2012 The OpenSSL Project.
#
# The script embeds fingerprint into Microsoft PE-COFF executable object.
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
unshift(@INC,$dir);
require "hmac_sha1.pl";
######################################################################
#
# PE-COFF segment table parser by <appro@openssl.org>.
#
{ package PECOFF;
use FileHandle;
sub dup { my %copy=map {$_} @_; return \%copy; }
sub Load {
my $class = shift;
my $self = {};
my $FD = FileHandle->new(); # autoclose
my $file = shift;
bless $self,$class;
sysopen($FD,$file,0) or die "$!";
binmode($FD);
#################################################
# read IMAGE_DOS_HEADER
#
read($FD,my $mz,64) or die "$!";
my @dos_header=unpack("a2C58V",$mz);
$!=42; # signal fipsld to revert to two-step link
die "$file is not PE-COFF image" if (@dos_header[0] ne "MZ");
my $e_lfanew=pop(@dos_header);
seek($FD,$e_lfanew,0) or die "$!";
read($FD,my $magic,4) or die "$!";
$!=42; # signal fipsld to revert to two-step link
die "$file is not PE-COFF image" if (unpack("V",$magic)!=0x4550);
#################################################
# read and parse COFF header...
#
read($FD,my $coff,20) or die "$!";
my %coff_header;
@coff_header{machine,nsects,date,syms_off,nsyms,opt,flags}=
unpack("v2V3v2",$coff);
my $strings;
my $symsize;
#################################################
# load strings table
#
if ($coff_header{syms_off}) {
seek($FD,$coff_header{syms_off}+18*$coff_header{nsyms},0) or die "$!";
read($FD,$strings,4) or die "$!";
$symsize = unpack("V",$strings);
read($FD,$strings,$symsize,4) or die "$!";
}
#################################################
# read sections
#
my $i;
# seek to section headers
seek($FD,$e_lfanew+24+@coff_header{opt},0) or die "$!";
for ($i=0;$i<$coff_header{nsects};$i++) {
my %coff_shdr;
my $name;
read($FD,my $section,40) or die "$!";
@coff_shdr{sh_name,sh_vsize,sh_vaddr,
sh_rawsize,sh_offset,sh_relocs,sh_lines,
sh_nrelocls,sh_nlines,sh_flags} =
unpack("a8V6v2V",$section);
$name = $coff_shdr{sh_name};
# see if sh_name is an offset in $strings
my ($hi,$lo) = unpack("V2",$name);
if ($hi==0 && $lo<$symsize) {
$name = substr($strings,$lo,64);
}
$name = (split(chr(0),$name))[0];
$coff_shdr{sh_name} = $name;
$self->{sections}{$name} = dup(%coff_shdr);
}
return $self;
}
sub Lookup {
my $self = shift;
my $name = shift;
return $self->{sections}{$name};
}
}
######################################################################
#
# main()
#
my $legacy_mode;
if ($#ARGV<0 || ($#ARGV>0 && !($legacy_mode=(@ARGV[0] =~ /^\-(dso|exe)$/)))) {
print STDERR "usage: $0 [-dso|-exe] pe-coff-binary\n";
exit(1);
}
$exe = PECOFF->Load(@ARGV[$#ARGV]);
sysopen(FD,@ARGV[$#ARGV],$legacy_mode?0:2) or die "$!"; # 2 is read/write
binmode(FD);
sub FIPS_incore_fingerprint {
my $ctx = HMAC->Init("etaonrishdlcupfm");
my ($beg,$end);
my $sect;
$sect = $exe->Lookup("fipstx") or die "no fipstx section";
seek(FD,$sect->{sh_offset},0) or die "$!";
read(FD,$blob,$sect->{sh_vsize}) or die "$!";
($beg = index($blob,"SPIFxet_ts_tXtra")) >= 0
or die "no FIPS_text_startX";
($end = rindex($blob,"SPIFxet_ne_t][Xd")) >= 0
or die "no FIPS_text_endX";
$ctx->Update(substr($blob,$beg,$end-$beg));
$sect = $exe->Lookup("fipsro") or die "no fipsro section";
seek(FD,$sect->{sh_offset},0) or die "$!";
read(FD,$blob,$sect->{sh_vsize}) or die "$!";
($beg = index($blob,"SPIFdor__atarats",40)) >= 0
or die "no FIPS_rodata_start";
($end = rindex($blob,"SPIFdor__ata[dne")) >= 0
or die "no FIPS_rodata_end";
$ctx->Update(substr($blob,$beg,$end-$beg));
return $ctx->Final();
}
$fingerprint = FIPS_incore_fingerprint();
if ($legacy_mode) {
print unpack("H*",$fingerprint);
} else {
my $sect = $exe->Lookup("fipsro");
seek(FD,$sect->{sh_offset},0) or die "$!";
print FD unpack("H*",$fingerprint) or die "$!";
}
close (FD);

274
util/pl/TI_CGTOOLS.pl Normal file
View File

@@ -0,0 +1,274 @@
#!/usr/local/bin/perl
#
# TI_CGTOOLS.pl, Texas Instruments CGTOOLS under Unix or MSYS.
#
$ssl= "ssl";
$crypto="crypto";
if ($fips && !$shlib)
{
$crypto="fips";
$crypto_compat = "cryptocompat.lib";
}
else
{
$crypto="crypto";
}
if ($fipscanisterbuild)
{
$fips_canister_path = "\$(LIB_D)/fipscanister.obj";
}
$o='/';
$cp='cp';
$cp2='$(PERL) util/copy.pl -stripcr';
$mkdir='$(PERL) util/mkdir-p.pl';
$rm='rm -f';
$zlib_lib="zlib1.lib";
# Santize -L options for ms link
$l_flags =~ s/-L("\[^"]+")/\/libpath:$1/g;
$l_flags =~ s/-L(\S+)/\/libpath:$1/g;
# C compiler stuff
$cc='cl6x';
$base_cflags= " $mf_cflag";
my $f;
$opt_cflags='';
$dbg_cflags=$f.' -g -DDEBUG -D_DEBUG';
$lflags='';
*::cc_compile_target = sub {
my ($target,$source,$ex_flags)=@_;
my $ret;
$ex_flags.=" -DMK1MF_BUILD" if ($source =~/cversion/);
$ret ="$target: \$(SRC_D)$o$source\n\t";
if ($fipscanisterbuild && $source=~/\.asm$/) {
$ret.="\$(PERL) util${o}fipsas.pl . \$< norunasm \$(CFLAG)\n\t";
}
$ret.="\$(CC) --obj_directory=\$(OBJ_D) $ex_flags -c \$(SRC_D)$o$source\n";
$target =~ s/.*${o}([^${o}]+)/$1/;
$source =~ s/.*${o}([^${o}\.]+)\..*/$1${obj}/;
$ret.="\tmv \$(OBJ_D)${o}$source \$(OBJ_D)${o}$target\n" if ($target ne $source);
$ret.="\n";
return($ret);
};
*::perlasm_compile_target = sub {
my ($target,$source,$bname)=@_;
my $ret;
$bname =~ s/(.*)\.[^\.]$/$1/;
$ret=<<___;
\$(TMP_D)$o$bname.asm: $source
\$(PERL) $source \$\@
___
$ret .= "\t\$(PERL) util${o}fipsas.pl . \$@ norunasm \$(CFLAG)\n" if $fipscanisterbuild;
$ret.=<<___;
$target: \$(TMP_D)$o$bname.asm
\$(ASM) --obj_directory=\$(OBJ_D) \$(TMP_D)$o$bname.asm
___
};
$mlflags='';
$out_def ="c6x";
$tmp_def ="$out_def/tmp";
$inc_def="$out_def/inc";
if ($debug)
{
$cflags=$dbg_cflags.$base_cflags;
}
else
{
$cflags=$opt_cflags.$base_cflags;
}
$obj='.obj';
$asm_suffix='.asm';
$ofile="";
# EXE linking stuff
$link='$(CC) -z';
$efile="-o ";
$exep='.out';
$ex_libs='';
# static library stuff
$mklib='ar6x';
$ranlib='';
$plib="";
$libp=".lib";
$shlibp=($shlib)?".dll":".lib";
$lfile='-o ';
$shlib_ex_obj="";
$asm='$(CC) $(CFLAG) -c';
$bn_asm_obj='';
$bn_asm_src='';
$des_enc_obj='';
$des_enc_src='';
$bf_enc_obj='';
$bf_enc_src='';
if (!$no_asm)
{
import_asm($mf_bn_asm, "bn", \$bn_asm_obj, \$bn_asm_src);
import_asm($mf_aes_asm, "aes", \$aes_asm_obj, \$aes_asm_src);
import_asm($mf_des_asm, "des", \$des_enc_obj, \$des_enc_src);
import_asm($mf_bf_asm, "bf", \$bf_enc_obj, \$bf_enc_src);
import_asm($mf_cast_asm, "cast", \$cast_enc_obj, \$cast_enc_src);
import_asm($mf_rc4_asm, "rc4", \$rc4_enc_obj, \$rc4_enc_src);
import_asm($mf_rc5_asm, "rc5", \$rc5_enc_obj, \$rc5_enc_src);
import_asm($mf_md5_asm, "md5", \$md5_asm_obj, \$md5_asm_src);
import_asm($mf_sha_asm, "sha", \$sha1_asm_obj, \$sha1_asm_src);
import_asm($mf_rmd_asm, "ripemd", \$rmd160_asm_obj, \$rmd160_asm_src);
import_asm($mf_wp_asm, "whrlpool", \$whirlpool_asm_obj, \$whirlpool_asm_src);
import_asm($mf_modes_asm, "modes", \$modes_asm_obj, \$modes_asm_src);
import_asm($mf_cpuid_asm, "", \$cpuid_asm_obj, \$cpuid_asm_src);
$perl_asm = 1;
}
sub do_lib_rule
{
my($objs,$target,$name,$shlib,$ign,$base_addr) = @_;
local($ret);
$taget =~ s/\//$o/g if $o ne '/';
my $base_arg;
if ($base_addr ne "")
{
$base_arg= " /base:$base_addr";
}
else
{
$base_arg = "";
}
if ($name ne "")
{
$name =~ tr/a-z/A-Z/;
$name = "/def:ms/${name}.def";
}
# $target="\$(LIB_D)$o$target";
# $ret.="$target: $objs\n";
if (!$shlib)
{
# $ret.="\t\$(RM) \$(O_$Name)\n";
$ret.="$target: $objs\n";
$ret.="\t\$(MKLIB) $lfile$target $objs\n";
}
else
{
local($ex)=($target =~ /O_CRYPTO/)?'':' $(L_CRYPTO)';
$ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
if ($fips && $target =~ /O_CRYPTO/)
{
$ret.="$target: $objs \$(PREMAIN_DSO_EXE)";
$ret.="\n\tFIPS_LINK=\"\$(LINK)\" \\\n";
$ret.="\tFIPS_CC=\$(CC)\\\n";
$ret.="\tFIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\\\n";
$ret.="\tPREMAIN_DSO_EXE=\$(PREMAIN_DSO_EXE)\\\n";
$ret.="\tFIPS_SHA1_EXE=\$(FIPS_SHA1_EXE)\\\n";
$ret.="\tFIPS_TARGET=$target\\\n";
$ret.="\tFIPSLIB_D=\$(FIPSLIB_D)\\\n";
$ret.="\t\$(FIPSLINK) \$(MLFLAGS) /map $base_arg $efile$target ";
$ret.="$name \$(SHLIB_EX_OBJ) $objs \$(EX_LIBS) ";
$ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n";
}
else
{
$ret.="$target: $objs";
$ret.="\n\t\$(LINK) \$(MLFLAGS) $efile$target $name \$(SHLIB_EX_OBJ) $objs $ex \$(EX_LIBS)\n";
}
$ret.="\tIF EXIST \$@.manifest mt -nologo -manifest \$@.manifest -outputresource:\$@;2\n\n";
}
$ret.="\n";
return($ret);
}
sub do_link_rule
{
my($target,$files,$dep_libs,$libs,$standalone)=@_;
local($ret,$_);
$file =~ s/\//$o/g if $o ne '/';
$n=&bname($targer);
$ret.="$target: $files $dep_libs\n";
if ($standalone == 1)
{
$ret.=" \$(LINK) \$(LFLAGS) $efile$target ";
$ret.= "\$(EX_LIBS) " if ($files =~ /O_FIPSCANISTER/ && !$fipscanisterbuild);
$ret.="$files $libs\n";
}
elsif ($standalone == 2)
{
$ret.="\t\$(LINK) \$(LFLAGS) $efile$target $files \$(O_FIPSCANISTER) $out_def/application.cmd\n";
$ret.="\t$out_def/incore6x $target\n\n";
}
else
{
$ret.="\t\$(LINK) \$(LFLAGS) $efile$target ";
$ret.="\t\$(APP_EX_OBJ) $files $libs\n";
}
return($ret);
}
sub do_rlink_rule
{
local($target,$rl_start, $rl_mid, $rl_end,$dep_libs,$libs)=@_;
local($ret,$_);
my $files = "$rl_start $rl_mid $rl_end";
$file =~ s/\//$o/g if $o ne '/';
$n=&bname($target);
$ret.="$target: $files $dep_libs\n";
$ret.="\t\$(LINK) -r $lfile$target $files $out_def/fipscanister.cmd\n";
$ret.="\t\$(PERL) $out_def${o}fips_standalone_sha1 $target > ${target}.sha1\n";
$ret.="\t\$(PERL) util${o}copy.pl -stripcr fips${o}fips_premain.c \$(LIB_D)${o}fips_premain.c\n";
$ret.="\t\$(CP) fips${o}fips_premain.c.sha1 \$(LIB_D)${o}fips_premain.c.sha1\n";
$ret.="\n";
return($ret);
}
sub import_asm
{
my ($mf_var, $asm_name, $oref, $sref) = @_;
my $asm_dir;
if ($asm_name eq "")
{
$asm_dir = "crypto$o";
}
else
{
$asm_dir = "crypto$o$asm_name$oasm$o";
}
$$oref = "";
$$sref = "";
$mf_var =~ s/\.o//g;
foreach (split(/ /, $mf_var))
{
$$sref .= $asm_dir . $_ . ".asm ";
}
foreach (split(/ /, $mf_var))
{
$$oref .= "\$(TMP_D)\\" . $_ . ".obj ";
}
$$oref =~ s/ $//;
$$sref =~ s/ $//;
}
1;

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";
@@ -123,23 +122,28 @@ elsif ($FLAVOR =~ /CE/)
}
$cc='$(CC)';
$base_cflags=' /W3 /WX /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT';
$base_cflags=' /W3 /GF /Gy /nologo -DUNICODE -D_UNICODE -DOPENSSL_SYSNAME_WINCE -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32 -DNO_CHMOD -DOPENSSL_SMALL_FOOTPRINT';
$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);
@@ -174,12 +178,12 @@ $rsc="rc";
$efile="/out:";
$exep='.exe';
if ($no_sock) { $ex_libs=''; }
elsif ($FLAVOR =~ /CE/) { $ex_libs='winsock.lib'; }
elsif ($FLAVOR =~ /CE/) { $ex_libs='ws2.lib'; }
else { $ex_libs='ws2_32.lib'; }
if ($FLAVOR =~ /CE/)
{
$ex_libs.=' $(WCECOMPAT)/lib/wcecompatex.lib' if (defined($ENV{'WCECOMPAT'}));
$ex_libs.=' $(WCECOMPAT)/lib/wcecompatex.lib crypt32.lib coredll.lib corelibc.lib' if (defined($ENV{'WCECOMPAT'}));
$ex_libs.=' $(PORTSDK_LIBPATH)/portlib.lib' if (defined($ENV{'PORTSDK_LIBPATH'}));
$ex_libs.=' /nodefaultlib:oldnames.lib coredll.lib corelibc.lib' if ($ENV{'TARGETCPU'} eq "X86");
}
@@ -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
@@ -389,8 +394,9 @@ sub do_rlink_rule
$file =~ s/\//$o/g if $o ne '/';
$n=&bname($targer);
$ret.="$target: $files $dep_libs \$(FIPS_SHA1_EXE)\n";
$ret.="\t\$(PERL) ms\\segrenam.pl \$\$a $rl_start\n";
$ret.="$target: $files $dep_libs";
$ret.=" \$(FIPS_SHA1_EXE)" unless defined $ENV{"FIPS_SHA1_PATH"};
$ret.="\n\t\$(PERL) ms\\segrenam.pl \$\$a $rl_start\n";
$ret.="\t\$(PERL) ms\\segrenam.pl \$\$b $rl_mid\n";
$ret.="\t\$(PERL) ms\\segrenam.pl \$\$c $rl_end\n";
$ret.="\t\$(MKLIB) $lfile$target @<<\n\t$files\n<<\n";