diff options
Diffstat (limited to 'openssl/crypto/sha')
23 files changed, 5156 insertions, 0 deletions
diff --git a/openssl/crypto/sha/Makefile b/openssl/crypto/sha/Makefile new file mode 100644 index 000000000..f4741b9ee --- /dev/null +++ b/openssl/crypto/sha/Makefile @@ -0,0 +1,146 @@ +# +# OpenSSL/crypto/sha/Makefile +# + +DIR= sha +TOP= ../.. +CC= cc +CPP= $(CC) -E +INCLUDES= +CFLAG=-g +MAKEFILE= Makefile +AR= ar r + +SHA1_ASM_OBJ= + +CFLAGS= $(INCLUDES) $(CFLAG) +ASFLAGS= $(INCLUDES) $(ASFLAG) +AFLAGS= $(ASFLAGS) + +GENERAL=Makefile +TEST=shatest.c sha1test.c sha256t.c sha512t.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=sha_dgst.c sha1dgst.c sha_one.c sha1_one.c sha256.c sha512.c +LIBOBJ=sha_dgst.o sha1dgst.o sha_one.o sha1_one.o sha256.o sha512.o $(SHA1_ASM_OBJ) + +SRC= $(LIBSRC) + +EXHEADER= sha.h +HEADER= sha_locl.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(ARX) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +# ELF +sx86-elf.s: asm/sha1-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha1-586.pl elf $(CFLAGS) $(PROCESSOR) > ../$@) +s512sse2-elf.s: asm/sha512-sse2.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha512-sse2.pl elf $(CFLAGS) $(PROCESSOR) > ../$@) +# COFF +sx86-cof.s: asm/sha1-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha1-586.pl coff $(CFLAGS) $(PROCESSOR) > ../$@) +s512sse2-cof.s: asm/sha512-sse2.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha512-sse2.pl coff $(CFLAGS) $(PROCESSOR) > ../$@) +# a.out +sx86-out.s: asm/sha1-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha1-586.pl a.out $(CFLAGS) $(PROCESSOR) > ../$@) +s512sse2-out.s: asm/sha512-sse2.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha512-sse2.pl a.out $(CFLAGS) $(PROCESSOR) > ../$@) + +sha1-ia64.s: asm/sha1-ia64.pl + (cd asm; $(PERL) sha1-ia64.pl ../$@ $(CFLAGS)) +sha256-ia64.s: asm/sha512-ia64.pl + (cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS)) +sha512-ia64.s: asm/sha512-ia64.pl + (cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS)) + +# Solaris make has to be explicitly told +sha1-x86_64.s: asm/sha1-x86_64.pl; $(PERL) asm/sha1-x86_64.pl $@ +sha256-x86_64.s:asm/sha512-x86_64.pl; $(PERL) asm/sha512-x86_64.pl $@ +sha512-x86_64.s:asm/sha512-x86_64.pl; $(PERL) asm/sha512-x86_64.pl $@ + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +sha1_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +sha1_one.o: ../../include/openssl/opensslconf.h +sha1_one.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +sha1_one.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +sha1_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +sha1_one.o: sha1_one.c +sha1dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h +sha1dgst.o: ../../include/openssl/opensslconf.h +sha1dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h +sha1dgst.o: ../md32_common.h sha1dgst.c sha_locl.h +sha256.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +sha256.o: ../../include/openssl/fips.h ../../include/openssl/opensslconf.h +sha256.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +sha256.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +sha256.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +sha256.o: ../md32_common.h sha256.c +sha512.o: ../../e_os.h ../../include/openssl/bio.h +sha512.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +sha512.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +sha512.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +sha512.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +sha512.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h +sha512.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +sha512.o: ../../include/openssl/symhacks.h ../cryptlib.h sha512.c +sha_dgst.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +sha_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +sha_dgst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +sha_dgst.o: ../../include/openssl/opensslconf.h +sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +sha_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +sha_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +sha_dgst.o: ../md32_common.h sha_dgst.c sha_locl.h +sha_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +sha_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +sha_one.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h +sha_one.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +sha_one.o: ../../include/openssl/symhacks.h sha_one.c diff --git a/openssl/crypto/sha/asm/README b/openssl/crypto/sha/asm/README new file mode 100644 index 000000000..b7e755765 --- /dev/null +++ b/openssl/crypto/sha/asm/README @@ -0,0 +1 @@ +C2.pl works diff --git a/openssl/crypto/sha/asm/sha1-586.pl b/openssl/crypto/sha/asm/sha1-586.pl new file mode 100644 index 000000000..a787dd37d --- /dev/null +++ b/openssl/crypto/sha/asm/sha1-586.pl @@ -0,0 +1,219 @@ +#!/usr/bin/env perl + +# ==================================================================== +# [Re]written by Andy Polyakov <appro@fy.chalmers.se> 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/. +# ==================================================================== + +# "[Re]written" was achieved in two major overhauls. In 2004 BODY_* +# functions were re-implemented to address P4 performance issue [see +# commentary below], and in 2006 the rest was rewritten in order to +# gain freedom to liberate licensing terms. + +# It was noted that Intel IA-32 C compiler generates code which +# performs ~30% *faster* on P4 CPU than original *hand-coded* +# SHA1 assembler implementation. To address this problem (and +# prove that humans are still better than machines:-), the +# original code was overhauled, which resulted in following +# performance changes: +# +# compared with original compared with Intel cc +# assembler impl. generated code +# Pentium -16% +48% +# PIII/AMD +8% +16% +# P4 +85%(!) +45% +# +# As you can see Pentium came out as looser:-( Yet I reckoned that +# improvement on P4 outweights the loss and incorporate this +# re-tuned code to 0.9.7 and later. +# ---------------------------------------------------------------- +# <appro@fy.chalmers.se> + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386"); + +$A="eax"; +$B="ebx"; +$C="ecx"; +$D="edx"; +$E="edi"; +$T="esi"; +$tmp1="ebp"; + +@V=($A,$B,$C,$D,$E,$T); + +sub BODY_00_15 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("00_15 $n"); + + &mov($f,$c); # f to hold F_00_19(b,c,d) + if ($n==0) { &mov($tmp1,$a); } + else { &mov($a,$tmp1); } + &rotl($tmp1,5); # tmp1=ROTATE(a,5) + &xor($f,$d); + &add($tmp1,$e); # tmp1+=e; + &and($f,$b); + &mov($e,&swtmp($n%16)); # e becomes volatile and is loaded + # with xi, also note that e becomes + # f in next round... + &xor($f,$d); # f holds F_00_19(b,c,d) + &rotr($b,2); # b=ROTATE(b,30) + &lea($tmp1,&DWP(0x5a827999,$tmp1,$e)); # tmp1+=K_00_19+xi + + if ($n==15) { &add($f,$tmp1); } # f+=tmp1 + else { &add($tmp1,$f); } # f becomes a in next round + } + +sub BODY_16_19 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("16_19 $n"); + + &mov($f,&swtmp($n%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &mov($tmp1,$c); # tmp1 to hold F_00_19(b,c,d) + &xor($f,&swtmp(($n+2)%16)); + &xor($tmp1,$d); + &xor($f,&swtmp(($n+8)%16)); + &and($tmp1,$b); # tmp1 holds F_00_19(b,c,d) + &rotr($b,2); # b=ROTATE(b,30) + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &xor($tmp1,$d); # tmp1=F_00_19(b,c,d) + &mov(&swtmp($n%16),$f); # xi=f + &lea($f,&DWP(0x5a827999,$f,$e));# f+=K_00_19+e + &mov($e,$a); # e becomes volatile + &rotl($e,5); # e=ROTATE(a,5) + &add($f,$tmp1); # f+=F_00_19(b,c,d) + &add($f,$e); # f+=ROTATE(a,5) + } + +sub BODY_20_39 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + local $K=($n<40)?0x6ed9eba1:0xca62c1d6; + + &comment("20_39 $n"); + + &mov($tmp1,$b); # tmp1 to hold F_20_39(b,c,d) + &mov($f,&swtmp($n%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &rotr($b,2); # b=ROTATE(b,30) + &xor($f,&swtmp(($n+2)%16)); + &xor($tmp1,$c); + &xor($f,&swtmp(($n+8)%16)); + &xor($tmp1,$d); # tmp1 holds F_20_39(b,c,d) + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &add($tmp1,$e); + &mov(&swtmp($n%16),$f); # xi=f + &mov($e,$a); # e becomes volatile + &rotl($e,5); # e=ROTATE(a,5) + &lea($f,&DWP($K,$f,$tmp1)); # f+=K_20_39+e + &add($f,$e); # f+=ROTATE(a,5) + } + +sub BODY_40_59 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("40_59 $n"); + + &mov($f,&swtmp($n%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &mov($tmp1,&swtmp(($n+2)%16)); + &xor($f,$tmp1); + &mov($tmp1,&swtmp(($n+8)%16)); + &xor($f,$tmp1); + &mov($tmp1,&swtmp(($n+13)%16)); + &xor($f,$tmp1); # f holds xa^xb^xc^xd + &mov($tmp1,$b); # tmp1 to hold F_40_59(b,c,d) + &rotl($f,1); # f=ROTATE(f,1) + &or($tmp1,$c); + &mov(&swtmp($n%16),$f); # xi=f + &and($tmp1,$d); + &lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e + &mov($e,$b); # e becomes volatile and is used + # to calculate F_40_59(b,c,d) + &rotr($b,2); # b=ROTATE(b,30) + &and($e,$c); + &or($tmp1,$e); # tmp1 holds F_40_59(b,c,d) + &mov($e,$a); + &rotl($e,5); # e=ROTATE(a,5) + &add($f,$tmp1); # f+=tmp1; + &add($f,$e); # f+=ROTATE(a,5) + } + +&function_begin("sha1_block_data_order"); + &mov($tmp1,&wparam(0)); # SHA_CTX *c + &mov($T,&wparam(1)); # const void *input + &mov($A,&wparam(2)); # size_t num + &stack_push(16); # allocate X[16] + &shl($A,6); + &add($A,$T); + &mov(&wparam(2),$A); # pointer beyond the end of input + &mov($E,&DWP(16,$tmp1));# pre-load E + + &set_label("loop",16); + + # copy input chunk to X, but reversing byte order! + for ($i=0; $i<16; $i+=4) + { + &mov($A,&DWP(4*($i+0),$T)); + &mov($B,&DWP(4*($i+1),$T)); + &mov($C,&DWP(4*($i+2),$T)); + &mov($D,&DWP(4*($i+3),$T)); + &bswap($A); + &bswap($B); + &bswap($C); + &bswap($D); + &mov(&swtmp($i+0),$A); + &mov(&swtmp($i+1),$B); + &mov(&swtmp($i+2),$C); + &mov(&swtmp($i+3),$D); + } + &mov(&wparam(1),$T); # redundant in 1st spin + + &mov($A,&DWP(0,$tmp1)); # load SHA_CTX + &mov($B,&DWP(4,$tmp1)); + &mov($C,&DWP(8,$tmp1)); + &mov($D,&DWP(12,$tmp1)); + # E is pre-loaded + + for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } + for(;$i<20;$i++) { &BODY_16_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)); } + + (($V[5] eq $D) and ($V[0] eq $E)) or die; # double-check + + &mov($tmp1,&wparam(0)); # re-load SHA_CTX* + &mov($D,&wparam(1)); # D is last "T" and is discarded + + &add($E,&DWP(0,$tmp1)); # E is last "A"... + &add($T,&DWP(4,$tmp1)); + &add($A,&DWP(8,$tmp1)); + &add($B,&DWP(12,$tmp1)); + &add($C,&DWP(16,$tmp1)); + + &mov(&DWP(0,$tmp1),$E); # update SHA_CTX + &add($D,64); # advance input pointer + &mov(&DWP(4,$tmp1),$T); + &cmp($D,&wparam(2)); # have we reached the end yet? + &mov(&DWP(8,$tmp1),$A); + &mov($E,$C); # C is last "E" which needs to be "pre-loaded" + &mov(&DWP(12,$tmp1),$B); + &mov($T,$D); # input pointer + &mov(&DWP(16,$tmp1),$C); + &jb(&label("loop")); + + &stack_pop(16); +&function_end("sha1_block_data_order"); + +&asm_finish(); diff --git a/openssl/crypto/sha/asm/sha1-ia64.pl b/openssl/crypto/sha/asm/sha1-ia64.pl new file mode 100644 index 000000000..51c4f47ec --- /dev/null +++ b/openssl/crypto/sha/asm/sha1-ia64.pl @@ -0,0 +1,306 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov <appro@fy.chalmers.se> 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/. +# ==================================================================== +# +# Eternal question is what's wrong with compiler generated code? The +# trick is that it's possible to reduce the number of shifts required +# to perform rotations by maintaining copy of 32-bit value in upper +# bits of 64-bit register. Just follow mux2 and shrp instructions... +# Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which +# is >50% better than HP C and >2x better than gcc. + +$code=<<___; +.ident \"sha1-ia64.s, version 1.2\" +.ident \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\" +.explicit + +___ + + +if ($^O eq "hpux") { + $ADDP="addp4"; + for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } +} else { $ADDP="add"; } +for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/); + $big_endian=0 if (/\-DL_ENDIAN/); } +if (!defined($big_endian)) + { $big_endian=(unpack('L',pack('N',1))==1); } + +#$human=1; +if ($human) { # useful for visual code auditing... + ($A,$B,$C,$D,$E,$T) = ("A","B","C","D","E","T"); + ($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4"); + ($K_00_19, $K_20_39, $K_40_59, $K_60_79) = + ( "K_00_19","K_20_39","K_40_59","K_60_79" ); + @X= ( "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", + "X8", "X9","X10","X11","X12","X13","X14","X15" ); +} +else { + ($A,$B,$C,$D,$E,$T) = ("loc0","loc1","loc2","loc3","loc4","loc5"); + ($h0,$h1,$h2,$h3,$h4) = ("loc6","loc7","loc8","loc9","loc10"); + ($K_00_19, $K_20_39, $K_40_59, $K_60_79) = + ( "r14", "r15", "loc11", "loc12" ); + @X= ( "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" ); +} + +sub BODY_00_15 { +local *code=shift; +local ($i,$a,$b,$c,$d,$e,$f)=@_; + +$code.=<<___ if ($i==0); +{ .mmi; ld1 $X[$i&0xf]=[inp],2 // MSB + ld1 tmp2=[tmp3],2 };; +{ .mmi; ld1 tmp0=[inp],2 + ld1 tmp4=[tmp3],2 // LSB + dep $X[$i&0xf]=$X[$i&0xf],tmp2,8,8 };; +___ +if ($i<15) { + $code.=<<___; +{ .mmi; ld1 $X[($i+1)&0xf]=[inp],2 // +1 + dep tmp1=tmp0,tmp4,8,8 };; +{ .mmi; ld1 tmp2=[tmp3],2 // +1 + and tmp4=$c,$b + dep $X[$i&0xf]=$X[$i&0xf],tmp1,16,16 } //;; +{ .mmi; andcm tmp1=$d,$b + add tmp0=$e,$K_00_19 + dep.z tmp5=$a,5,27 };; // a<<5 +{ .mmi; or tmp4=tmp4,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) + add $f=tmp0,$X[$i&0xf] // f=xi+e+K_00_19 + extr.u tmp1=$a,27,5 };; // a>>27 +{ .mmi; ld1 tmp0=[inp],2 // +1 + add $f=$f,tmp4 // f+=F_00_19(b,c,d) + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; ld1 tmp4=[tmp3],2 // +1 + or tmp5=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $f=$f,tmp5 // f+=ROTATE(a,5) + dep $X[($i+1)&0xf]=$X[($i+1)&0xf],tmp2,8,8 // +1 + mux2 $X[$i&0xf]=$X[$i&0xf],0x44 } //;; + +___ + } +else { + $code.=<<___; +{ .mii; and tmp3=$c,$b + dep tmp1=tmp0,tmp4,8,8;; + dep $X[$i&0xf]=$X[$i&0xf],tmp1,16,16 } //;; +{ .mmi; andcm tmp1=$d,$b + add tmp0=$e,$K_00_19 + dep.z tmp5=$a,5,27 };; // a<<5 +{ .mmi; or tmp4=tmp3,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) + add $f=tmp0,$X[$i&0xf] // f=xi+e+K_00_19 + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1 + xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1 + nop.i 0 };; +{ .mmi; add $f=$f,tmp4 // f+=F_00_19(b,c,d) + xor tmp2=tmp2,tmp3 // +1 + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5) + shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1) + mux2 $X[$i&0xf]=$X[$i&0xf],0x44 };; + +___ + } +} + +sub BODY_16_19 { +local *code=shift; +local ($i,$a,$b,$c,$d,$e,$f)=@_; + +$code.=<<___; +{ .mmi; mov $X[$i&0xf]=$f // Xupdate + and tmp0=$c,$b + dep.z tmp5=$a,5,27 } // a<<5 +{ .mmi; andcm tmp1=$d,$b + add tmp4=$e,$K_00_19 };; +{ .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) + add $f=$f,tmp4 // f+=e+K_00_19 + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1 + xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1 + nop.i 0 };; +{ .mmi; add $f=$f,tmp0 // f+=F_00_19(b,c,d) + xor tmp2=tmp2,tmp3 // +1 + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5) + shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1) + nop.i 0 };; + +___ +} + +sub BODY_20_39 { +local *code=shift; +local ($i,$a,$b,$c,$d,$e,$f,$Konst)=@_; + $Konst = $K_20_39 if (!defined($Konst)); + +if ($i<79) { +$code.=<<___; +{ .mib; mov $X[$i&0xf]=$f // Xupdate + dep.z tmp5=$a,5,27 } // a<<5 +{ .mib; xor tmp0=$c,$b + add tmp4=$e,$Konst };; +{ .mmi; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d + add $f=$f,tmp4 // f+=e+K_20_39 + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1 + xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1 + nop.i 0 };; +{ .mmi; add $f=$f,tmp0 // f+=F_20_39(b,c,d) + xor tmp2=tmp2,tmp3 // +1 + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5) + shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1) + nop.i 0 };; + +___ +} +else { +$code.=<<___; +{ .mib; mov $X[$i&0xf]=$f // Xupdate + dep.z tmp5=$a,5,27 } // a<<5 +{ .mib; xor tmp0=$c,$b + add tmp4=$e,$Konst };; +{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d + extr.u tmp1=$a,27,5 } // a>>27 +{ .mib; add $f=$f,tmp4 // f+=e+K_20_39 + add $h1=$h1,$a };; // wrap up +{ .mmi; add $f=$f,tmp0 // f+=F_20_39(b,c,d) + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) ;;? +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + add $h3=$h3,$c };; // wrap up +{ .mib; add tmp3=1,inp // used in unaligned codepath + add $f=$f,tmp1 } // f+=ROTATE(a,5) +{ .mib; add $h2=$h2,$b // wrap up + add $h4=$h4,$d };; // wrap up + +___ +} +} + +sub BODY_40_59 { +local *code=shift; +local ($i,$a,$b,$c,$d,$e,$f)=@_; + +$code.=<<___; +{ .mmi; mov $X[$i&0xf]=$f // Xupdate + and tmp0=$c,$b + dep.z tmp5=$a,5,27 } // a<<5 +{ .mmi; and tmp1=$d,$b + add tmp4=$e,$K_40_59 };; +{ .mmi; or tmp0=tmp0,tmp1 // (b&c)|(b&d) + add $f=$f,tmp4 // f+=e+K_40_59 + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; and tmp4=$c,$d + xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1 + xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1 + };; +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + xor tmp2=tmp2,tmp3 // +1 + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp0=tmp0,tmp4 // F_40_59(b,c,d)=(b&c)|(b&d)|(c&d) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $f=$f,tmp0 // f+=F_40_59(b,c,d) + shrp $e=tmp2,tmp2,31;; // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1) + add $f=$f,tmp1 };; // f+=ROTATE(a,5) + +___ +} +sub BODY_60_79 { &BODY_20_39(@_,$K_60_79); } + +$code.=<<___; +.text + +tmp0=r8; +tmp1=r9; +tmp2=r10; +tmp3=r11; +ctx=r32; // in0 +inp=r33; // in1 + +// void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num); +.global sha1_block_data_order# +.proc sha1_block_data_order# +.align 32 +sha1_block_data_order: + .prologue +{ .mmi; alloc tmp1=ar.pfs,3,15,0,0 + $ADDP tmp0=4,ctx + .save ar.lc,r3 + mov r3=ar.lc } +{ .mmi; $ADDP ctx=0,ctx + $ADDP inp=0,inp + mov r2=pr };; +tmp4=in2; +tmp5=loc13; +tmp6=loc14; + .body +{ .mlx; ld4 $h0=[ctx],8 + movl $K_00_19=0x5a827999 } +{ .mlx; ld4 $h1=[tmp0],8 + movl $K_20_39=0x6ed9eba1 };; +{ .mlx; ld4 $h2=[ctx],8 + movl $K_40_59=0x8f1bbcdc } +{ .mlx; ld4 $h3=[tmp0] + movl $K_60_79=0xca62c1d6 };; +{ .mmi; ld4 $h4=[ctx],-16 + add in2=-1,in2 // adjust num for ar.lc + mov ar.ec=1 };; +{ .mmi; nop.m 0 + add tmp3=1,inp + mov ar.lc=in2 };; // brp.loop.imp: too far + +.Ldtop: +{ .mmi; mov $A=$h0 + mov $B=$h1 + mux2 tmp6=$h1,0x44 } +{ .mmi; mov $C=$h2 + mov $D=$h3 + mov $E=$h4 };; + +___ + +{ my $i,@V=($A,$B,$C,$D,$E,$T); + + for($i=0;$i<16;$i++) { &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<20;$i++) { &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<40;$i++) { &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<60;$i++) { &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<80;$i++) { &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); } + + (($V[5] eq $D) and ($V[0] eq $E)) or die; # double-check +} + +$code.=<<___; +{ .mmb; add $h0=$h0,$E + nop.m 0 + br.ctop.dptk.many .Ldtop };; +.Ldend: +{ .mmi; add tmp0=4,ctx + mov ar.lc=r3 };; +{ .mmi; st4 [ctx]=$h0,8 + st4 [tmp0]=$h1,8 };; +{ .mmi; st4 [ctx]=$h2,8 + st4 [tmp0]=$h3 };; +{ .mib; st4 [ctx]=$h4,-16 + mov pr=r2,0x1ffff + br.ret.sptk.many b0 };; +.endp sha1_block_data_order# +stringz "SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>" +___ + +$output=shift and open STDOUT,">$output"; +print $code; diff --git a/openssl/crypto/sha/asm/sha1-x86_64.pl b/openssl/crypto/sha/asm/sha1-x86_64.pl new file mode 100644 index 000000000..f7ed67a72 --- /dev/null +++ b/openssl/crypto/sha/asm/sha1-x86_64.pl @@ -0,0 +1,242 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov <appro@fy.chalmers.se> 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_block procedure for x86_64. +# +# It was brought to my attention that on EM64T compiler-generated code +# was far behind 32-bit assembler implementation. This is unlike on +# Opteron where compiler-generated code was only 15% behind 32-bit +# assembler, which originally made it hard to motivate the effort. +# There was suggestion to mechanically translate 32-bit code, but I +# dismissed it, reasoning that x86_64 offers enough register bank +# capacity to fully utilize SHA-1 parallelism. Therefore this fresh +# implementation:-) However! While 64-bit code does performs better +# on Opteron, I failed to beat 32-bit assembler on EM64T core. Well, +# x86_64 does offer larger *addressable* bank, but out-of-order core +# reaches for even more registers through dynamic aliasing, and EM64T +# core must have managed to run-time optimize even 32-bit code just as +# good as 64-bit one. Performance improvement is summarized in the +# following table: +# +# gcc 3.4 32-bit asm cycles/byte +# Opteron +45% +20% 6.8 +# Xeon P4 +65% +0% 9.9 +# Core2 +60% +10% 7.0 + +$output=shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open STDOUT,"| $^X $xlate $output"; + +$ctx="%rdi"; # 1st arg +$inp="%rsi"; # 2nd arg +$num="%rdx"; # 3rd arg + +# reassign arguments in order to produce more compact code +$ctx="%r8"; +$inp="%r9"; +$num="%r10"; + +$xi="%eax"; +$t0="%ebx"; +$t1="%ecx"; +$A="%edx"; +$B="%esi"; +$C="%edi"; +$D="%ebp"; +$E="%r11d"; +$T="%r12d"; + +@V=($A,$B,$C,$D,$E,$T); + +sub PROLOGUE { +my $func=shift; +$code.=<<___; +.globl $func +.type $func,\@function,3 +.align 16 +$func: + push %rbx + push %rbp + push %r12 + mov %rsp,%rax + mov %rdi,$ctx # reassigned argument + sub \$`8+16*4`,%rsp + mov %rsi,$inp # reassigned argument + and \$-64,%rsp + mov %rdx,$num # reassigned argument + mov %rax,`16*4`(%rsp) + + mov 0($ctx),$A + mov 4($ctx),$B + mov 8($ctx),$C + mov 12($ctx),$D + mov 16($ctx),$E +___ +} + +sub EPILOGUE { +my $func=shift; +$code.=<<___; + mov `16*4`(%rsp),%rsp + pop %r12 + pop %rbp + pop %rbx + ret +.size $func,.-$func +___ +} + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e,$f,$host)=@_; +my $j=$i+1; +$code.=<<___ if ($i==0); + mov `4*$i`($inp),$xi + `"bswap $xi" if(!defined($host))` + mov $xi,`4*$i`(%rsp) +___ +$code.=<<___ if ($i<15); + lea 0x5a827999($xi,$e),$f + mov $c,$t0 + mov `4*$j`($inp),$xi + mov $a,$e + xor $d,$t0 + `"bswap $xi" if(!defined($host))` + rol \$5,$e + and $b,$t0 + mov $xi,`4*$j`(%rsp) + add $e,$f + xor $d,$t0 + rol \$30,$b + add $t0,$f +___ +$code.=<<___ if ($i>=15); + lea 0x5a827999($xi,$e),$f + mov `4*($j%16)`(%rsp),$xi + mov $c,$t0 + mov $a,$e + xor `4*(($j+2)%16)`(%rsp),$xi + xor $d,$t0 + rol \$5,$e + xor `4*(($j+8)%16)`(%rsp),$xi + and $b,$t0 + add $e,$f + xor `4*(($j+13)%16)`(%rsp),$xi + xor $d,$t0 + rol \$30,$b + add $t0,$f + rol \$1,$xi + mov $xi,`4*($j%16)`(%rsp) +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e,$f)=@_; +my $j=$i+1; +my $K=($i<40)?0x6ed9eba1:0xca62c1d6; +$code.=<<___ if ($i<79); + lea $K($xi,$e),$f + mov `4*($j%16)`(%rsp),$xi + mov $c,$t0 + mov $a,$e + xor `4*(($j+2)%16)`(%rsp),$xi + xor $b,$t0 + rol \$5,$e + xor `4*(($j+8)%16)`(%rsp),$xi + xor $d,$t0 + add $e,$f + xor `4*(($j+13)%16)`(%rsp),$xi + rol \$30,$b + add $t0,$f + rol \$1,$xi +___ +$code.=<<___ if ($i<76); + mov $xi,`4*($j%16)`(%rsp) +___ +$code.=<<___ if ($i==79); + lea $K($xi,$e),$f + mov $c,$t0 + mov $a,$e + xor $b,$t0 + rol \$5,$e + xor $d,$t0 + add $e,$f + rol \$30,$b + add $t0,$f +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e,$f)=@_; +my $j=$i+1; +$code.=<<___; + lea 0x8f1bbcdc($xi,$e),$f + mov `4*($j%16)`(%rsp),$xi + mov $b,$t0 + mov $b,$t1 + xor `4*(($j+2)%16)`(%rsp),$xi + mov $a,$e + and $c,$t0 + xor `4*(($j+8)%16)`(%rsp),$xi + or $c,$t1 + rol \$5,$e + xor `4*(($j+13)%16)`(%rsp),$xi + and $d,$t1 + add $e,$f + rol \$1,$xi + or $t1,$t0 + rol \$30,$b + mov $xi,`4*($j%16)`(%rsp) + add $t0,$f +___ +} + +$code=".text\n"; + +&PROLOGUE("sha1_block_data_order"); +$code.=".align 4\n.Lloop:\n"; +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 0($ctx),$E + add 4($ctx),$T + add 8($ctx),$A + add 12($ctx),$B + add 16($ctx),$C + mov $E,0($ctx) + mov $T,4($ctx) + mov $A,8($ctx) + mov $B,12($ctx) + mov $C,16($ctx) + + xchg $E,$A # mov $E,$A + xchg $T,$B # mov $T,$B + xchg $E,$C # mov $A,$C + xchg $T,$D # mov $B,$D + # mov $C,$E + lea `16*4`($inp),$inp + sub \$1,$num + jnz .Lloop +___ +&EPILOGUE("sha1_block_data_order"); +$code.=<<___; +.asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>" +___ + +#################################################################### + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/openssl/crypto/sha/asm/sha512-ia64.pl b/openssl/crypto/sha/asm/sha512-ia64.pl new file mode 100644 index 000000000..1c6ce5652 --- /dev/null +++ b/openssl/crypto/sha/asm/sha512-ia64.pl @@ -0,0 +1,672 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov <appro@fy.chalmers.se> 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_Transform for Itanium. +# +# sha512_block runs in 1003 cycles on Itanium 2, which is almost 50% +# faster than gcc and >60%(!) faster than code generated by HP-UX +# compiler (yes, HP-UX is generating slower code, because unlike gcc, +# it failed to deploy "shift right pair," 'shrp' instruction, which +# substitutes for 64-bit rotate). +# +# 924 cycles long sha256_block outperforms gcc by over factor of 2(!) +# and HP-UX compiler - by >40% (yes, gcc won sha512_block, but lost +# this one big time). Note that "formally" 924 is about 100 cycles +# too much. I mean it's 64 32-bit rounds vs. 80 virtually identical +# 64-bit ones and 1003*64/80 gives 802. Extra cycles, 2 per round, +# are spent on extra work to provide for 32-bit rotations. 32-bit +# rotations are still handled by 'shrp' instruction and for this +# reason lower 32 bits are deposited to upper half of 64-bit register +# prior 'shrp' issue. And in order to minimize the amount of such +# operations, X[16] values are *maintained* with copies of lower +# halves in upper halves, which is why you'll spot such instructions +# as custom 'mux2', "parallel 32-bit add," 'padd4' and "parallel +# 32-bit unsigned right shift," 'pshr4.u' instructions here. +# +# Rules of engagement. +# +# There is only one integer shifter meaning that if I have two rotate, +# deposit or extract instructions in adjacent bundles, they shall +# split [at run-time if they have to]. But note that variable and +# parallel shifts are performed by multi-media ALU and *are* pairable +# with rotates [and alike]. On the backside MMALU is rather slow: it +# takes 2 extra cycles before the result of integer operation is +# available *to* MMALU and 2(*) extra cycles before the result of MM +# operation is available "back" *to* integer ALU, not to mention that +# MMALU itself has 2 cycles latency. However! I explicitly scheduled +# these MM instructions to avoid MM stalls, so that all these extra +# latencies get "hidden" in instruction-level parallelism. +# +# (*) 2 cycles on Itanium 1 and 1 cycle on Itanium 2. But I schedule +# for 2 in order to provide for best *overall* performance, +# because on Itanium 1 stall on MM result is accompanied by +# pipeline flush, which takes 6 cycles:-( +# +# Resulting performance numbers for 900MHz Itanium 2 system: +# +# The 'numbers' are in 1000s of bytes per second processed. +# type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes +# sha1(*) 6210.14k 20376.30k 52447.83k 85870.05k 105478.12k +# sha256 7476.45k 20572.05k 41538.34k 56062.29k 62093.18k +# sha512 4996.56k 20026.28k 47597.20k 85278.79k 111501.31k +# +# (*) SHA1 numbers are for HP-UX compiler and are presented purely +# for reference purposes. I bet it can improved too... +# +# To generate code, pass the file name with either 256 or 512 in its +# name and compiler flags. + +$output=shift; + +if ($output =~ /512.*\.[s|asm]/) { + $SZ=8; + $BITS=8*$SZ; + $LDW="ld8"; + $STW="st8"; + $ADD="add"; + $SHRU="shr.u"; + $TABLE="K512"; + $func="sha512_block_data_order"; + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=(1, 8, 7); + @sigma1=(19,61, 6); + $rounds=80; +} elsif ($output =~ /256.*\.[s|asm]/) { + $SZ=4; + $BITS=8*$SZ; + $LDW="ld4"; + $STW="st4"; + $ADD="padd4"; + $SHRU="pshr4.u"; + $TABLE="K256"; + $func="sha256_block_data_order"; + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 7,18, 3); + @sigma1=(17,19,10); + $rounds=64; +} else { die "nonsense $output"; } + +open STDOUT,">$output" || die "can't open $output: $!"; + +if ($^O eq "hpux") { + $ADDP="addp4"; + for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } +} else { $ADDP="add"; } +for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/); + $big_endian=0 if (/\-DL_ENDIAN/); } +if (!defined($big_endian)) + { $big_endian=(unpack('L',pack('N',1))==1); } + +$code=<<___; +.ident \"$output, version 1.1\" +.ident \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\" +.explicit +.text + +pfssave=r2; +lcsave=r3; +prsave=r14; +K=r15; +A=r16; B=r17; C=r18; D=r19; +E=r20; F=r21; G=r22; H=r23; +T1=r24; T2=r25; +s0=r26; s1=r27; t0=r28; t1=r29; +Ktbl=r30; +ctx=r31; // 1st arg +input=r48; // 2nd arg +num=r49; // 3rd arg +sgm0=r50; sgm1=r51; // small constants +A_=r54; B_=r55; C_=r56; D_=r57; +E_=r58; F_=r59; G_=r60; H_=r61; + +// void $func (SHA_CTX *ctx, const void *in,size_t num[,int host]) +.global $func# +.proc $func# +.align 32 +$func: + .prologue + .save ar.pfs,pfssave +{ .mmi; alloc pfssave=ar.pfs,3,27,0,16 + $ADDP ctx=0,r32 // 1st arg + .save ar.lc,lcsave + mov lcsave=ar.lc } +{ .mmi; $ADDP input=0,r33 // 2nd arg + mov num=r34 // 3rd arg + .save pr,prsave + mov prsave=pr };; + + .body +{ .mib; add r8=0*$SZ,ctx + add r9=1*$SZ,ctx + brp.loop.imp .L_first16,.L_first16_end-16 } +{ .mib; add r10=2*$SZ,ctx + add r11=3*$SZ,ctx + brp.loop.imp .L_rest,.L_rest_end-16 };; + +// load A-H +.Lpic_point: +{ .mmi; $LDW A_=[r8],4*$SZ + $LDW B_=[r9],4*$SZ + mov Ktbl=ip } +{ .mmi; $LDW C_=[r10],4*$SZ + $LDW D_=[r11],4*$SZ + mov sgm0=$sigma0[2] };; +{ .mmi; $LDW E_=[r8] + $LDW F_=[r9] + add Ktbl=($TABLE#-.Lpic_point),Ktbl } +{ .mmi; $LDW G_=[r10] + $LDW H_=[r11] + cmp.ne p0,p16=0,r0 };; // used in sha256_block +___ +$code.=<<___ if ($BITS==64); +{ .mii; and r8=7,input + and input=~7,input;; + cmp.eq p9,p0=1,r8 } +{ .mmi; cmp.eq p10,p0=2,r8 + cmp.eq p11,p0=3,r8 + cmp.eq p12,p0=4,r8 } +{ .mmi; cmp.eq p13,p0=5,r8 + cmp.eq p14,p0=6,r8 + cmp.eq p15,p0=7,r8 };; +___ +$code.=<<___; +.L_outer: +.rotr X[16] +{ .mmi; mov A=A_ + mov B=B_ + mov ar.lc=14 } +{ .mmi; mov C=C_ + mov D=D_ + mov E=E_ } +{ .mmi; mov F=F_ + mov G=G_ + mov ar.ec=2 } +{ .mmi; ld1 X[15]=[input],$SZ // eliminated in 64-bit + mov H=H_ + mov sgm1=$sigma1[2] };; + +___ +$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32); +.align 32 +.L_first16: +{ .mmi; add r9=1-$SZ,input + add r10=2-$SZ,input + add r11=3-$SZ,input };; +{ .mmi; ld1 r9=[r9] + ld1 r10=[r10] + dep.z $t1=E,32,32 } +{ .mmi; $LDW K=[Ktbl],$SZ + ld1 r11=[r11] + zxt4 E=E };; +{ .mii; or $t1=$t1,E + dep X[15]=X[15],r9,8,8 + dep r11=r10,r11,8,8 };; +{ .mmi; and T1=F,E + and T2=A,B + dep X[15]=X[15],r11,16,16 } +{ .mmi; andcm r8=G,E + and r9=A,C + mux2 $t0=A,0x44 };; // copy lower half to upper +{ .mmi; (p16) ld1 X[15-1]=[input],$SZ // prefetch + xor T1=T1,r8 // T1=((e & f) ^ (~e & g)) + _rotr r11=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mib; and r10=B,C + xor T2=T2,r9 };; +___ +$t0="A", $t1="E", $code.=<<___ if ($BITS==64); +// in 64-bit mode I load whole X[16] at once and take care of alignment... +{ .mmi; add r8=1*$SZ,input + add r9=2*$SZ,input + add r10=3*$SZ,input };; +{ .mmb; $LDW X[15]=[input],4*$SZ + $LDW X[14]=[r8],4*$SZ +(p9) br.cond.dpnt.many .L1byte };; +{ .mmb; $LDW X[13]=[r9],4*$SZ + $LDW X[12]=[r10],4*$SZ +(p10) br.cond.dpnt.many .L2byte };; +{ .mmb; $LDW X[11]=[input],4*$SZ + $LDW X[10]=[r8],4*$SZ +(p11) br.cond.dpnt.many .L3byte };; +{ .mmb; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ +(p12) br.cond.dpnt.many .L4byte };; +{ .mmb; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ +(p13) br.cond.dpnt.many .L5byte };; +{ .mmb; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ +(p14) br.cond.dpnt.many .L6byte };; +{ .mmb; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ +(p15) br.cond.dpnt.many .L7byte };; +{ .mmb; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + br.many .L_first16 };; +.L1byte: +{ .mmi; $LDW X[13]=[r9],4*$SZ + $LDW X[12]=[r10],4*$SZ + shrp X[15]=X[15],X[14],56 };; +{ .mmi; $LDW X[11]=[input],4*$SZ + $LDW X[10]=[r8],4*$SZ + shrp X[14]=X[14],X[13],56 } +{ .mmi; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ + shrp X[13]=X[13],X[12],56 };; +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[12]=X[12],X[11],56 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[11]=X[11],X[10],56 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[10]=X[10],X[ 9],56 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[ 9]=X[ 9],X[ 8],56 };; +{ .mii; $LDW T1=[input] + shrp X[ 8]=X[ 8],X[ 7],56 + shrp X[ 7]=X[ 7],X[ 6],56 } +{ .mii; shrp X[ 6]=X[ 6],X[ 5],56 + shrp X[ 5]=X[ 5],X[ 4],56 };; +{ .mii; shrp X[ 4]=X[ 4],X[ 3],56 + shrp X[ 3]=X[ 3],X[ 2],56 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],56 + shrp X[ 1]=X[ 1],X[ 0],56 } +{ .mib; shrp X[ 0]=X[ 0],T1,56 + br.many .L_first16 };; +.L2byte: +{ .mmi; $LDW X[11]=[input],4*$SZ + $LDW X[10]=[r8],4*$SZ + shrp X[15]=X[15],X[14],48 } +{ .mmi; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ + shrp X[14]=X[14],X[13],48 };; +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[13]=X[13],X[12],48 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[12]=X[12],X[11],48 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[11]=X[11],X[10],48 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[10]=X[10],X[ 9],48 };; +{ .mii; $LDW T1=[input] + shrp X[ 9]=X[ 9],X[ 8],48 + shrp X[ 8]=X[ 8],X[ 7],48 } +{ .mii; shrp X[ 7]=X[ 7],X[ 6],48 + shrp X[ 6]=X[ 6],X[ 5],48 };; +{ .mii; shrp X[ 5]=X[ 5],X[ 4],48 + shrp X[ 4]=X[ 4],X[ 3],48 } +{ .mii; shrp X[ 3]=X[ 3],X[ 2],48 + shrp X[ 2]=X[ 2],X[ 1],48 } +{ .mii; shrp X[ 1]=X[ 1],X[ 0],48 + shrp X[ 0]=X[ 0],T1,48 } +{ .mfb; br.many .L_first16 };; +.L3byte: +{ .mmi; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ + shrp X[15]=X[15],X[14],40 };; +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[14]=X[14],X[13],40 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[13]=X[13],X[12],40 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[12]=X[12],X[11],40 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[11]=X[11],X[10],40 };; +{ .mii; $LDW T1=[input] + shrp X[10]=X[10],X[ 9],40 + shrp X[ 9]=X[ 9],X[ 8],40 } +{ .mii; shrp X[ 8]=X[ 8],X[ 7],40 + shrp X[ 7]=X[ 7],X[ 6],40 };; +{ .mii; shrp X[ 6]=X[ 6],X[ 5],40 + shrp X[ 5]=X[ 5],X[ 4],40 } +{ .mii; shrp X[ 4]=X[ 4],X[ 3],40 + shrp X[ 3]=X[ 3],X[ 2],40 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],40 + shrp X[ 1]=X[ 1],X[ 0],40 } +{ .mib; shrp X[ 0]=X[ 0],T1,40 + br.many .L_first16 };; +.L4byte: +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[15]=X[15],X[14],32 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[14]=X[14],X[13],32 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[13]=X[13],X[12],32 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[12]=X[12],X[11],32 };; +{ .mii; $LDW T1=[input] + shrp X[11]=X[11],X[10],32 + shrp X[10]=X[10],X[ 9],32 } +{ .mii; shrp X[ 9]=X[ 9],X[ 8],32 + shrp X[ 8]=X[ 8],X[ 7],32 };; +{ .mii; shrp X[ 7]=X[ 7],X[ 6],32 + shrp X[ 6]=X[ 6],X[ 5],32 } +{ .mii; shrp X[ 5]=X[ 5],X[ 4],32 + shrp X[ 4]=X[ 4],X[ 3],32 } +{ .mii; shrp X[ 3]=X[ 3],X[ 2],32 + shrp X[ 2]=X[ 2],X[ 1],32 } +{ .mii; shrp X[ 1]=X[ 1],X[ 0],32 + shrp X[ 0]=X[ 0],T1,32 } +{ .mfb; br.many .L_first16 };; +.L5byte: +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[15]=X[15],X[14],24 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[14]=X[14],X[13],24 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[13]=X[13],X[12],24 };; +{ .mii; $LDW T1=[input] + shrp X[12]=X[12],X[11],24 + shrp X[11]=X[11],X[10],24 } +{ .mii; shrp X[10]=X[10],X[ 9],24 + shrp X[ 9]=X[ 9],X[ 8],24 };; +{ .mii; shrp X[ 8]=X[ 8],X[ 7],24 + shrp X[ 7]=X[ 7],X[ 6],24 } +{ .mii; shrp X[ 6]=X[ 6],X[ 5],24 + shrp X[ 5]=X[ 5],X[ 4],24 } +{ .mii; shrp X[ 4]=X[ 4],X[ 3],24 + shrp X[ 3]=X[ 3],X[ 2],24 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],24 + shrp X[ 1]=X[ 1],X[ 0],24 } +{ .mib; shrp X[ 0]=X[ 0],T1,24 + br.many .L_first16 };; +.L6byte: +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[15]=X[15],X[14],16 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[14]=X[14],X[13],16 };; +{ .mii; $LDW T1=[input] + shrp X[13]=X[13],X[12],16 + shrp X[12]=X[12],X[11],16 } +{ .mii; shrp X[11]=X[11],X[10],16 + shrp X[10]=X[10],X[ 9],16 };; +{ .mii; shrp X[ 9]=X[ 9],X[ 8],16 + shrp X[ 8]=X[ 8],X[ 7],16 } +{ .mii; shrp X[ 7]=X[ 7],X[ 6],16 + shrp X[ 6]=X[ 6],X[ 5],16 } +{ .mii; shrp X[ 5]=X[ 5],X[ 4],16 + shrp X[ 4]=X[ 4],X[ 3],16 } +{ .mii; shrp X[ 3]=X[ 3],X[ 2],16 + shrp X[ 2]=X[ 2],X[ 1],16 } +{ .mii; shrp X[ 1]=X[ 1],X[ 0],16 + shrp X[ 0]=X[ 0],T1,16 } +{ .mfb; br.many .L_first16 };; +.L7byte: +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[15]=X[15],X[14],8 };; +{ .mii; $LDW T1=[input] + shrp X[14]=X[14],X[13],8 + shrp X[13]=X[13],X[12],8 } +{ .mii; shrp X[12]=X[12],X[11],8 + shrp X[11]=X[11],X[10],8 };; +{ .mii; shrp X[10]=X[10],X[ 9],8 + shrp X[ 9]=X[ 9],X[ 8],8 } +{ .mii; shrp X[ 8]=X[ 8],X[ 7],8 + shrp X[ 7]=X[ 7],X[ 6],8 } +{ .mii; shrp X[ 6]=X[ 6],X[ 5],8 + shrp X[ 5]=X[ 5],X[ 4],8 } +{ .mii; shrp X[ 4]=X[ 4],X[ 3],8 + shrp X[ 3]=X[ 3],X[ 2],8 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],8 + shrp X[ 1]=X[ 1],X[ 0],8 } +{ .mib; shrp X[ 0]=X[ 0],T1,8 + br.many .L_first16 };; + +.align 32 +.L_first16: +{ .mmi; $LDW K=[Ktbl],$SZ + and T1=F,E + and T2=A,B } +{ .mmi; //$LDW X[15]=[input],$SZ // X[i]=*input++ + andcm r8=G,E + and r9=A,C };; +{ .mmi; xor T1=T1,r8 //T1=((e & f) ^ (~e & g)) + and r10=B,C + _rotr r11=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mmi; xor T2=T2,r9 + mux1 X[15]=X[15],\@rev };; // eliminated in big-endian +___ +$code.=<<___; +{ .mib; add T1=T1,H // T1=Ch(e,f,g)+h + _rotr r8=$t1,$Sigma1[1] } // ROTR(e,18) +{ .mib; xor T2=T2,r10 // T2=((a & b) ^ (a & c) ^ (b & c)) + mov H=G };; +{ .mib; xor r11=r8,r11 + _rotr r9=$t1,$Sigma1[2] } // ROTR(e,41) +{ .mib; mov G=F + mov F=E };; +{ .mib; xor r9=r9,r11 // r9=Sigma1(e) + _rotr r10=$t0,$Sigma0[0] } // ROTR(a,28) +{ .mib; add T1=T1,K // T1=Ch(e,f,g)+h+K512[i] + mov E=D };; +{ .mib; add T1=T1,r9 // T1+=Sigma1(e) + _rotr r11=$t0,$Sigma0[1] } // ROTR(a,34) +{ .mib; mov D=C + mov C=B };; +{ .mib; add T1=T1,X[15] // T1+=X[i] + _rotr r8=$t0,$Sigma0[2] } // ROTR(a,39) +{ .mib; xor r10=r10,r11 + mux2 X[15]=X[15],0x44 };; // eliminated in 64-bit +{ .mmi; xor r10=r8,r10 // r10=Sigma0(a) + mov B=A + add A=T1,T2 };; +{ .mib; add E=E,T1 + add A=A,r10 // T2=Maj(a,b,c)+Sigma0(a) + br.ctop.sptk .L_first16 };; +.L_first16_end: + +{ .mii; mov ar.lc=$rounds-17 + mov ar.ec=1 };; + +.align 32 +.L_rest: +.rotr X[16] +{ .mib; $LDW K=[Ktbl],$SZ + _rotr r8=X[15-1],$sigma0[0] } // ROTR(s0,1) +{ .mib; $ADD X[15]=X[15],X[15-9] // X[i&0xF]+=X[(i+9)&0xF] + $SHRU s0=X[15-1],sgm0 };; // s0=X[(i+1)&0xF]>>7 +{ .mib; and T1=F,E + _rotr r9=X[15-1],$sigma0[1] } // ROTR(s0,8) +{ .mib; andcm r10=G,E + $SHRU s1=X[15-14],sgm1 };; // s1=X[(i+14)&0xF]>>6 +{ .mmi; xor T1=T1,r10 // T1=((e & f) ^ (~e & g)) + xor r9=r8,r9 + _rotr r10=X[15-14],$sigma1[0] };;// ROTR(s1,19) +{ .mib; and T2=A,B + _rotr r11=X[15-14],$sigma1[1] }// ROTR(s1,61) +{ .mib; and r8=A,C };; +___ +$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32); +// I adhere to mmi; in order to hold Itanium 1 back and avoid 6 cycle +// pipeline flush in last bundle. Note that even on Itanium2 the +// latter stalls for one clock cycle... +{ .mmi; xor s0=s0,r9 // s0=sigma0(X[(i+1)&0xF]) + dep.z $t1=E,32,32 } +{ .mmi; xor r10=r11,r10 + zxt4 E=E };; +{ .mmi; or $t1=$t1,E + xor s1=s1,r10 // s1=sigma1(X[(i+14)&0xF]) + mux2 $t0=A,0x44 };; // copy lower half to upper +{ .mmi; xor T2=T2,r8 + _rotr r9=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mmi; and r10=B,C + add T1=T1,H // T1=Ch(e,f,g)+h + $ADD X[15]=X[15],s0 };; // X[i&0xF]+=sigma0(X[(i+1)&0xF]) +___ +$t0="A", $t1="E", $code.=<<___ if ($BITS==64); +{ .mib; xor s0=s0,r9 // s0=sigma0(X[(i+1)&0xF]) + _rotr r9=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mib; xor r10=r11,r10 + xor T2=T2,r8 };; +{ .mib; xor s1=s1,r10 // s1=sigma1(X[(i+14)&0xF]) + add T1=T1,H } +{ .mib; and r10=B,C + $ADD X[15]=X[15],s0 };; // X[i&0xF]+=sigma0(X[(i+1)&0xF]) +___ +$code.=<<___; +{ .mmi; xor T2=T2,r10 // T2=((a & b) ^ (a & c) ^ (b & c)) + mov H=G + _rotr r8=$t1,$Sigma1[1] };; // ROTR(e,18) +{ .mmi; xor r11=r8,r9 + $ADD X[15]=X[15],s1 // X[i&0xF]+=sigma1(X[(i+14)&0xF]) + _rotr r9=$t1,$Sigma1[2] } // ROTR(e,41) +{ .mmi; mov G=F + mov F=E };; +{ .mib; xor r9=r9,r11 // r9=Sigma1(e) + _rotr r10=$t0,$Sigma0[0] } // ROTR(a,28) +{ .mib; add T1=T1,K // T1=Ch(e,f,g)+h+K512[i] + mov E=D };; +{ .mib; add T1=T1,r9 // T1+=Sigma1(e) + _rotr r11=$t0,$Sigma0[1] } // ROTR(a,34) +{ .mib; mov D=C + mov C=B };; +{ .mmi; add T1=T1,X[15] // T1+=X[i] + xor r10=r10,r11 + _rotr r8=$t0,$Sigma0[2] };; // ROTR(a,39) +{ .mmi; xor r10=r8,r10 // r10=Sigma0(a) + mov B=A + add A=T1,T2 };; +{ .mib; add E=E,T1 + add A=A,r10 // T2=Maj(a,b,c)+Sigma0(a) + br.ctop.sptk .L_rest };; +.L_rest_end: + +{ .mmi; add A_=A_,A + add B_=B_,B + add C_=C_,C } +{ .mmi; add D_=D_,D + add E_=E_,E + cmp.ltu p16,p0=1,num };; +{ .mmi; add F_=F_,F + add G_=G_,G + add H_=H_,H } +{ .mmb; add Ktbl=-$SZ*$rounds,Ktbl +(p16) add num=-1,num +(p16) br.dptk.many .L_outer };; + +{ .mib; add r8=0*$SZ,ctx + add r9=1*$SZ,ctx } +{ .mib; add r10=2*$SZ,ctx + add r11=3*$SZ,ctx };; +{ .mmi; $STW [r8]=A_,4*$SZ + $STW [r9]=B_,4*$SZ + mov ar.lc=lcsave } +{ .mmi; $STW [r10]=C_,4*$SZ + $STW [r11]=D_,4*$SZ + mov pr=prsave,0x1ffff };; +{ .mmb; $STW [r8]=E_ + $STW [r9]=F_ } +{ .mmb; $STW [r10]=G_ + $STW [r11]=H_ + br.ret.sptk.many b0 };; +.endp $func# +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/_rotr(\s+)([^=]+)=([^,]+),([0-9]+)/shrp$1$2=$3,$3,$4/gm; +if ($BITS==64) { + $code =~ s/mux2(\s+)\S+/nop.i$1 0x0/gm; + $code =~ s/mux1(\s+)\S+/nop.i$1 0x0/gm if ($big_endian); + $code =~ s/(shrp\s+X\[[^=]+)=([^,]+),([^,]+),([1-9]+)/$1=$3,$2,64-$4/gm + if (!$big_endian); + $code =~ s/ld1(\s+)X\[\S+/nop.m$1 0x0/gm; +} + +print $code; + +print<<___ if ($BITS==32); +.align 64 +.type K256#,\@object +K256: data4 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + data4 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + data4 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + data4 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + data4 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + data4 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + data4 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + data4 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + data4 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + data4 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + data4 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + data4 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + data4 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + data4 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + data4 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + data4 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.size K256#,$SZ*$rounds +stringz "SHA256 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>" +___ +print<<___ if ($BITS==64); +.align 64 +.type K512#,\@object +K512: data8 0x428a2f98d728ae22,0x7137449123ef65cd + data8 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc + data8 0x3956c25bf348b538,0x59f111f1b605d019 + data8 0x923f82a4af194f9b,0xab1c5ed5da6d8118 + data8 0xd807aa98a3030242,0x12835b0145706fbe + data8 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 + data8 0x72be5d74f27b896f,0x80deb1fe3b1696b1 + data8 0x9bdc06a725c71235,0xc19bf174cf692694 + data8 0xe49b69c19ef14ad2,0xefbe4786384f25e3 + data8 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 + data8 0x2de92c6f592b0275,0x4a7484aa6ea6e483 + data8 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 + data8 0x983e5152ee66dfab,0xa831c66d2db43210 + data8 0xb00327c898fb213f,0xbf597fc7beef0ee4 + data8 0xc6e00bf33da88fc2,0xd5a79147930aa725 + data8 0x06ca6351e003826f,0x142929670a0e6e70 + data8 0x27b70a8546d22ffc,0x2e1b21385c26c926 + data8 0x4d2c6dfc5ac42aed,0x53380d139d95b3df + data8 0x650a73548baf63de,0x766a0abb3c77b2a8 + data8 0x81c2c92e47edaee6,0x92722c851482353b + data8 0xa2bfe8a14cf10364,0xa81a664bbc423001 + data8 0xc24b8b70d0f89791,0xc76c51a30654be30 + data8 0xd192e819d6ef5218,0xd69906245565a910 + data8 0xf40e35855771202a,0x106aa07032bbd1b8 + data8 0x19a4c116b8d2d0c8,0x1e376c085141ab53 + data8 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 + data8 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb + data8 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 + data8 0x748f82ee5defb2fc,0x78a5636f43172f60 + data8 0x84c87814a1f0ab72,0x8cc702081a6439ec + data8 0x90befffa23631e28,0xa4506cebde82bde9 + data8 0xbef9a3f7b2c67915,0xc67178f2e372532b + data8 0xca273eceea26619c,0xd186b8c721c0c207 + data8 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 + data8 0x06f067aa72176fba,0x0a637dc5a2c898a6 + data8 0x113f9804bef90dae,0x1b710b35131c471b + data8 0x28db77f523047d84,0x32caab7b40c72493 + data8 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c + data8 0x4cc5d4becb3e42b6,0x597f299cfc657e2a + data8 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.size K512#,$SZ*$rounds +stringz "SHA512 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>" +___ diff --git a/openssl/crypto/sha/asm/sha512-sse2.pl b/openssl/crypto/sha/asm/sha512-sse2.pl new file mode 100644 index 000000000..10902bf67 --- /dev/null +++ b/openssl/crypto/sha/asm/sha512-sse2.pl @@ -0,0 +1,404 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL +# project. Rights for redistribution and usage in source and binary +# forms are granted according to the OpenSSL license. +# ==================================================================== +# +# SHA512_Transform_SSE2. +# +# As the name suggests, this is an IA-32 SSE2 implementation of +# SHA512_Transform. Motivating factor for the undertaken effort was that +# SHA512 was observed to *consistently* perform *significantly* poorer +# than SHA256 [2x and slower is common] on 32-bit platforms. On 64-bit +# platforms on the other hand SHA512 tend to outperform SHA256 [~50% +# seem to be common improvement factor]. All this is perfectly natural, +# as SHA512 is a 64-bit algorithm. But isn't IA-32 SSE2 essentially +# a 64-bit instruction set? Is it rich enough to implement SHA512? +# If answer was "no," then you wouldn't have been reading this... +# +# Throughput performance in MBps (larger is better): +# +# 2.4GHz P4 1.4GHz AMD32 1.4GHz AMD64(*) +# SHA256/gcc(*) 54 43 59 +# SHA512/gcc 17 23 92 +# SHA512/sse2 61(**) 57(**) +# SHA512/icc 26 28 +# SHA256/icc(*) 65 54 +# +# (*) AMD64 and SHA256 numbers are presented mostly for amusement or +# reference purposes. +# (**) I.e. it gives ~2-3x speed-up if compared with compiler generated +# code. One can argue that hand-coded *non*-SSE2 implementation +# would perform better than compiler generated one as well, and +# that comparison is therefore not exactly fair. Well, as SHA512 +# puts enormous pressure on IA-32 GP register bank, I reckon that +# hand-coded version wouldn't perform significantly better than +# one compiled with icc, ~20% perhaps... So that this code would +# still outperform it with distinguishing marginal. But feel free +# to prove me wrong:-) +# <appro@fy.chalmers.se> +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"sha512-sse2.pl",$ARGV[$#ARGV] eq "386"); + +$K512="esi"; # K512[80] table, found at the end... +#$W512="esp"; # $W512 is not just W512[16]: it comprises *two* copies + # of W512[16] and a copy of A-H variables... +$W512_SZ=8*(16+16+8); # see above... +#$Kidx="ebx"; # index in K512 table, advances from 0 to 80... +$Widx="edx"; # index in W512, wraps around at 16... +$data="edi"; # 16 qwords of input data... +$A="mm0"; # B-D and +$E="mm1"; # F-H are allocated dynamically... +$Aoff=256+0; # A-H offsets relative to $W512... +$Boff=256+8; +$Coff=256+16; +$Doff=256+24; +$Eoff=256+32; +$Foff=256+40; +$Goff=256+48; +$Hoff=256+56; + +sub SHA2_ROUND() +{ local ($kidx,$widx)=@_; + + # One can argue that one could reorder instructions for better + # performance. Well, I tried and it doesn't seem to make any + # noticeable difference. Modern out-of-order execution cores + # reorder instructions to their liking in either case and they + # apparently do decent job. So we can keep the code more + # readable/regular/comprehensible:-) + + # I adhere to 64-bit %mmX registers in order to avoid/not care + # about #GP exceptions on misaligned 128-bit access, most + # notably in paddq with memory operand. Not to mention that + # SSE2 intructions operating on %mmX can be scheduled every + # cycle [and not every second one if operating on %xmmN]. + + &movq ("mm4",&QWP($Foff,$W512)); # load f + &movq ("mm5",&QWP($Goff,$W512)); # load g + &movq ("mm6",&QWP($Hoff,$W512)); # load h + + &movq ("mm2",$E); # %mm2 is sliding right + &movq ("mm3",$E); # %mm3 is sliding left + &psrlq ("mm2",14); + &psllq ("mm3",23); + &movq ("mm7","mm2"); # %mm7 is T1 + &pxor ("mm7","mm3"); + &psrlq ("mm2",4); + &psllq ("mm3",23); + &pxor ("mm7","mm2"); + &pxor ("mm7","mm3"); + &psrlq ("mm2",23); + &psllq ("mm3",4); + &pxor ("mm7","mm2"); + &pxor ("mm7","mm3"); # T1=Sigma1_512(e) + + &movq (&QWP($Foff,$W512),$E); # f = e + &movq (&QWP($Goff,$W512),"mm4"); # g = f + &movq (&QWP($Hoff,$W512),"mm5"); # h = g + + &pxor ("mm4","mm5"); # f^=g + &pand ("mm4",$E); # f&=e + &pxor ("mm4","mm5"); # f^=g + &paddq ("mm7","mm4"); # T1+=Ch(e,f,g) + + &movq ("mm2",&QWP($Boff,$W512)); # load b + &movq ("mm3",&QWP($Coff,$W512)); # load c + &movq ($E,&QWP($Doff,$W512)); # e = d + + &paddq ("mm7","mm6"); # T1+=h + &paddq ("mm7",&QWP(0,$K512,$kidx,8)); # T1+=K512[i] + &paddq ("mm7",&QWP(0,$W512,$widx,8)); # T1+=W512[i] + &paddq ($E,"mm7"); # e += T1 + + &movq ("mm4",$A); # %mm4 is sliding right + &movq ("mm5",$A); # %mm5 is sliding left + &psrlq ("mm4",28); + &psllq ("mm5",25); + &movq ("mm6","mm4"); # %mm6 is T2 + &pxor ("mm6","mm5"); + &psrlq ("mm4",6); + &psllq ("mm5",5); + &pxor ("mm6","mm4"); + &pxor ("mm6","mm5"); + &psrlq ("mm4",5); + &psllq ("mm5",6); + &pxor ("mm6","mm4"); + &pxor ("mm6","mm5"); # T2=Sigma0_512(a) + + &movq (&QWP($Boff,$W512),$A); # b = a + &movq (&QWP($Coff,$W512),"mm2"); # c = b + &movq (&QWP($Doff,$W512),"mm3"); # d = c + + &movq ("mm4",$A); # %mm4=a + &por ($A,"mm3"); # a=a|c + &pand ("mm4","mm3"); # %mm4=a&c + &pand ($A,"mm2"); # a=(a|c)&b + &por ("mm4",$A); # %mm4=(a&c)|((a|c)&b) + &paddq ("mm6","mm4"); # T2+=Maj(a,b,c) + + &movq ($A,"mm7"); # a=T1 + &paddq ($A,"mm6"); # a+=T2 +} + +$func="sha512_block_sse2"; + +&function_begin_B($func); + if (0) {# Caller is expected to check if it's appropriate to + # call this routine. Below 3 lines are retained for + # debugging purposes... + &picmeup("eax","OPENSSL_ia32cap"); + &bt (&DWP(0,"eax"),26); + &jnc ("SHA512_Transform"); + } + + &push ("ebp"); + &mov ("ebp","esp"); + &push ("ebx"); + &push ("esi"); + &push ("edi"); + + &mov ($Widx,&DWP(8,"ebp")); # A-H state, 1st arg + &mov ($data,&DWP(12,"ebp")); # input data, 2nd arg + &call (&label("pic_point")); # make it PIC! +&set_label("pic_point"); + &blindpop($K512); + &lea ($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512)); + + $W512 = "esp"; # start using %esp as W512 + &sub ($W512,$W512_SZ); + &and ($W512,-16); # ensure 128-bit alignment + + # make private copy of A-H + # v assume the worst and stick to unaligned load + &movdqu ("xmm0",&QWP(0,$Widx)); + &movdqu ("xmm1",&QWP(16,$Widx)); + &movdqu ("xmm2",&QWP(32,$Widx)); + &movdqu ("xmm3",&QWP(48,$Widx)); + +&align(8); +&set_label("_chunk_loop"); + + &movdqa (&QWP($Aoff,$W512),"xmm0"); # a,b + &movdqa (&QWP($Coff,$W512),"xmm1"); # c,d + &movdqa (&QWP($Eoff,$W512),"xmm2"); # e,f + &movdqa (&QWP($Goff,$W512),"xmm3"); # g,h + + &xor ($Widx,$Widx); + + &movdq2q($A,"xmm0"); # load a + &movdq2q($E,"xmm2"); # load e + + # Why aren't loops unrolled? It makes sense to unroll if + # execution time for loop body is comparable with branch + # penalties and/or if whole data-set resides in register bank. + # Neither is case here... Well, it would be possible to + # eliminate few store operations, but it would hardly affect + # so to say stop-watch performance, as there is a lot of + # available memory slots to fill. It will only relieve some + # pressure off memory bus... + + # flip input stream byte order... + &mov ("eax",&DWP(0,$data,$Widx,8)); + &mov ("ebx",&DWP(4,$data,$Widx,8)); + &bswap ("eax"); + &bswap ("ebx"); + &mov (&DWP(0,$W512,$Widx,8),"ebx"); # W512[i] + &mov (&DWP(4,$W512,$Widx,8),"eax"); + &mov (&DWP(128+0,$W512,$Widx,8),"ebx"); # copy of W512[i] + &mov (&DWP(128+4,$W512,$Widx,8),"eax"); + +&align(8); +&set_label("_1st_loop"); # 0-15 + # flip input stream byte order... + &mov ("eax",&DWP(0+8,$data,$Widx,8)); + &mov ("ebx",&DWP(4+8,$data,$Widx,8)); + &bswap ("eax"); + &bswap ("ebx"); + &mov (&DWP(0+8,$W512,$Widx,8),"ebx"); # W512[i] + &mov (&DWP(4+8,$W512,$Widx,8),"eax"); + &mov (&DWP(128+0+8,$W512,$Widx,8),"ebx"); # copy of W512[i] + &mov (&DWP(128+4+8,$W512,$Widx,8),"eax"); +&set_label("_1st_looplet"); + &SHA2_ROUND($Widx,$Widx); &inc($Widx); + +&cmp ($Widx,15) +&jl (&label("_1st_loop")); +&je (&label("_1st_looplet")); # playing similar trick on 2nd loop + # does not improve performance... + + $Kidx = "ebx"; # start using %ebx as Kidx + &mov ($Kidx,$Widx); + +&align(8); +&set_label("_2nd_loop"); # 16-79 + &and($Widx,0xf); + + # 128-bit fragment! I update W512[i] and W512[i+1] in + # parallel:-) Note that I refer to W512[(i&0xf)+N] and not to + # W512[(i+N)&0xf]! This is exactly what I maintain the second + # copy of W512[16] for... + &movdqu ("xmm0",&QWP(8*1,$W512,$Widx,8)); # s0=W512[i+1] + &movdqa ("xmm2","xmm0"); # %xmm2 is sliding right + &movdqa ("xmm3","xmm0"); # %xmm3 is sliding left + &psrlq ("xmm2",1); + &psllq ("xmm3",56); + &movdqa ("xmm0","xmm2"); + &pxor ("xmm0","xmm3"); + &psrlq ("xmm2",6); + &psllq ("xmm3",7); + &pxor ("xmm0","xmm2"); + &pxor ("xmm0","xmm3"); + &psrlq ("xmm2",1); + &pxor ("xmm0","xmm2"); # s0 = sigma0_512(s0); + + &movdqa ("xmm1",&QWP(8*14,$W512,$Widx,8)); # s1=W512[i+14] + &movdqa ("xmm4","xmm1"); # %xmm4 is sliding right + &movdqa ("xmm5","xmm1"); # %xmm5 is sliding left + &psrlq ("xmm4",6); + &psllq ("xmm5",3); + &movdqa ("xmm1","xmm4"); + &pxor ("xmm1","xmm5"); + &psrlq ("xmm4",13); + &psllq ("xmm5",42); + &pxor ("xmm1","xmm4"); + &pxor ("xmm1","xmm5"); + &psrlq ("xmm4",42); + &pxor ("xmm1","xmm4"); # s1 = sigma1_512(s1); + + # + have to explictly load W512[i+9] as it's not 128-bit + # v aligned and paddq would throw an exception... + &movdqu ("xmm6",&QWP(8*9,$W512,$Widx,8)); + &paddq ("xmm0","xmm1"); # s0 += s1 + &paddq ("xmm0","xmm6"); # s0 += W512[i+9] + &paddq ("xmm0",&QWP(0,$W512,$Widx,8)); # s0 += W512[i] + + &movdqa (&QWP(0,$W512,$Widx,8),"xmm0"); # W512[i] = s0 + &movdqa (&QWP(16*8,$W512,$Widx,8),"xmm0"); # copy of W512[i] + + # as the above fragment was 128-bit, we "owe" 2 rounds... + &SHA2_ROUND($Kidx,$Widx); &inc($Kidx); &inc($Widx); + &SHA2_ROUND($Kidx,$Widx); &inc($Kidx); &inc($Widx); + +&cmp ($Kidx,80); +&jl (&label("_2nd_loop")); + + # update A-H state + &mov ($Widx,&DWP(8,"ebp")); # A-H state, 1st arg + &movq (&QWP($Aoff,$W512),$A); # write out a + &movq (&QWP($Eoff,$W512),$E); # write out e + &movdqu ("xmm0",&QWP(0,$Widx)); + &movdqu ("xmm1",&QWP(16,$Widx)); + &movdqu ("xmm2",&QWP(32,$Widx)); + &movdqu ("xmm3",&QWP(48,$Widx)); + &paddq ("xmm0",&QWP($Aoff,$W512)); # 128-bit additions... + &paddq ("xmm1",&QWP($Coff,$W512)); + &paddq ("xmm2",&QWP($Eoff,$W512)); + &paddq ("xmm3",&QWP($Goff,$W512)); + &movdqu (&QWP(0,$Widx),"xmm0"); + &movdqu (&QWP(16,$Widx),"xmm1"); + &movdqu (&QWP(32,$Widx),"xmm2"); + &movdqu (&QWP(48,$Widx),"xmm3"); + +&add ($data,16*8); # advance input data pointer +&dec (&DWP(16,"ebp")); # decrement 3rd arg +&jnz (&label("_chunk_loop")); + + # epilogue + &emms (); # required for at least ELF and Win32 ABIs + &mov ("edi",&DWP(-12,"ebp")); + &mov ("esi",&DWP(-8,"ebp")); + &mov ("ebx",&DWP(-4,"ebp")); + &leave (); +&ret (); + +&align(64); +&set_label("K512"); # Yes! I keep it in the code segment! + &data_word(0xd728ae22,0x428a2f98); # u64 + &data_word(0x23ef65cd,0x71374491); # u64 + &data_word(0xec4d3b2f,0xb5c0fbcf); # u64 + &data_word(0x8189dbbc,0xe9b5dba5); # u64 + &data_word(0xf348b538,0x3956c25b); # u64 + &data_word(0xb605d019,0x59f111f1); # u64 + &data_word(0xaf194f9b,0x923f82a4); # u64 + &data_word(0xda6d8118,0xab1c5ed5); # u64 + &data_word(0xa3030242,0xd807aa98); # u64 + &data_word(0x45706fbe,0x12835b01); # u64 + &data_word(0x4ee4b28c,0x243185be); # u64 + &data_word(0xd5ffb4e2,0x550c7dc3); # u64 + &data_word(0xf27b896f,0x72be5d74); # u64 + &data_word(0x3b1696b1,0x80deb1fe); # u64 + &data_word(0x25c71235,0x9bdc06a7); # u64 + &data_word(0xcf692694,0xc19bf174); # u64 + &data_word(0x9ef14ad2,0xe49b69c1); # u64 + &data_word(0x384f25e3,0xefbe4786); # u64 + &data_word(0x8b8cd5b5,0x0fc19dc6); # u64 + &data_word(0x77ac9c65,0x240ca1cc); # u64 + &data_word(0x592b0275,0x2de92c6f); # u64 + &data_word(0x6ea6e483,0x4a7484aa); # u64 + &data_word(0xbd41fbd4,0x5cb0a9dc); # u64 + &data_word(0x831153b5,0x76f988da); # u64 + &data_word(0xee66dfab,0x983e5152); # u64 + &data_word(0x2db43210,0xa831c66d); # u64 + &data_word(0x98fb213f,0xb00327c8); # u64 + &data_word(0xbeef0ee4,0xbf597fc7); # u64 + &data_word(0x3da88fc2,0xc6e00bf3); # u64 + &data_word(0x930aa725,0xd5a79147); # u64 + &data_word(0xe003826f,0x06ca6351); # u64 + &data_word(0x0a0e6e70,0x14292967); # u64 + &data_word(0x46d22ffc,0x27b70a85); # u64 + &data_word(0x5c26c926,0x2e1b2138); # u64 + &data_word(0x5ac42aed,0x4d2c6dfc); # u64 + &data_word(0x9d95b3df,0x53380d13); # u64 + &data_word(0x8baf63de,0x650a7354); # u64 + &data_word(0x3c77b2a8,0x766a0abb); # u64 + &data_word(0x47edaee6,0x81c2c92e); # u64 + &data_word(0x1482353b,0x92722c85); # u64 + &data_word(0x4cf10364,0xa2bfe8a1); # u64 + &data_word(0xbc423001,0xa81a664b); # u64 + &data_word(0xd0f89791,0xc24b8b70); # u64 + &data_word(0x0654be30,0xc76c51a3); # u64 + &data_word(0xd6ef5218,0xd192e819); # u64 + &data_word(0x5565a910,0xd6990624); # u64 + &data_word(0x5771202a,0xf40e3585); # u64 + &data_word(0x32bbd1b8,0x106aa070); # u64 + &data_word(0xb8d2d0c8,0x19a4c116); # u64 + &data_word(0x5141ab53,0x1e376c08); # u64 + &data_word(0xdf8eeb99,0x2748774c); # u64 + &data_word(0xe19b48a8,0x34b0bcb5); # u64 + &data_word(0xc5c95a63,0x391c0cb3); # u64 + &data_word(0xe3418acb,0x4ed8aa4a); # u64 + &data_word(0x7763e373,0x5b9cca4f); # u64 + &data_word(0xd6b2b8a3,0x682e6ff3); # u64 + &data_word(0x5defb2fc,0x748f82ee); # u64 + &data_word(0x43172f60,0x78a5636f); # u64 + &data_word(0xa1f0ab72,0x84c87814); # u64 + &data_word(0x1a6439ec,0x8cc70208); # u64 + &data_word(0x23631e28,0x90befffa); # u64 + &data_word(0xde82bde9,0xa4506ceb); # u64 + &data_word(0xb2c67915,0xbef9a3f7); # u64 + &data_word(0xe372532b,0xc67178f2); # u64 + &data_word(0xea26619c,0xca273ece); # u64 + &data_word(0x21c0c207,0xd186b8c7); # u64 + &data_word(0xcde0eb1e,0xeada7dd6); # u64 + &data_word(0xee6ed178,0xf57d4f7f); # u64 + &data_word(0x72176fba,0x06f067aa); # u64 + &data_word(0xa2c898a6,0x0a637dc5); # u64 + &data_word(0xbef90dae,0x113f9804); # u64 + &data_word(0x131c471b,0x1b710b35); # u64 + &data_word(0x23047d84,0x28db77f5); # u64 + &data_word(0x40c72493,0x32caab7b); # u64 + &data_word(0x15c9bebc,0x3c9ebe0a); # u64 + &data_word(0x9c100d4c,0x431d67c4); # u64 + &data_word(0xcb3e42b6,0x4cc5d4be); # u64 + &data_word(0xfc657e2a,0x597f299c); # u64 + &data_word(0x3ad6faec,0x5fcb6fab); # u64 + &data_word(0x4a475817,0x6c44198c); # u64 + +&function_end_B($func); + +&asm_finish(); diff --git a/openssl/crypto/sha/asm/sha512-x86_64.pl b/openssl/crypto/sha/asm/sha512-x86_64.pl new file mode 100644 index 000000000..b6252d31e --- /dev/null +++ b/openssl/crypto/sha/asm/sha512-x86_64.pl @@ -0,0 +1,344 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL +# project. Rights for redistribution and usage in source and binary +# forms are granted according to the OpenSSL license. +# ==================================================================== +# +# sha256/512_block procedure for x86_64. +# +# 40% improvement over compiler-generated code on Opteron. On EM64T +# sha256 was observed to run >80% faster and sha512 - >40%. No magical +# tricks, just straight implementation... I really wonder why gcc +# [being armed with inline assembler] fails to generate as fast code. +# The only thing which is cool about this module is that it's very +# same instruction sequence used for both SHA-256 and SHA-512. In +# former case the instructions operate on 32-bit operands, while in +# latter - on 64-bit ones. All I had to do is to get one flavor right, +# the other one passed the test right away:-) +# +# sha256_block runs in ~1005 cycles on Opteron, which gives you +# asymptotic performance of 64*1000/1005=63.7MBps times CPU clock +# frequency in GHz. sha512_block runs in ~1275 cycles, which results +# in 128*1000/1275=100MBps per GHz. Is there room for improvement? +# Well, if you compare it to IA-64 implementation, which maintains +# X[16] in register bank[!], tends to 4 instructions per CPU clock +# cycle and runs in 1003 cycles, 1275 is very good result for 3-way +# issue Opteron pipeline and X[16] maintained in memory. So that *if* +# there is a way to improve it, *then* the only way would be to try to +# offload X[16] updates to SSE unit, but that would require "deeper" +# loop unroll, which in turn would naturally cause size blow-up, not +# to mention increased complexity! And once again, only *if* it's +# actually possible to noticeably improve overall ILP, instruction +# level parallelism, on a given CPU implementation in this case. +# +# Special note on Intel EM64T. While Opteron CPU exhibits perfect +# perfromance ratio of 1.5 between 64- and 32-bit flavors [see above], +# [currently available] EM64T CPUs apparently are far from it. On the +# contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit +# sha256_block:-( This is presumably because 64-bit shifts/rotates +# apparently are not atomic instructions, but implemented in microcode. + +$output=shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open STDOUT,"| $^X $xlate $output"; + +if ($output =~ /512/) { + $func="sha512_block_data_order"; + $TABLE="K512"; + $SZ=8; + @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx", + "%r8", "%r9", "%r10","%r11"); + ($T1,$a0,$a1,$a2)=("%r12","%r13","%r14","%r15"); + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=(1, 8, 7); + @sigma1=(19,61, 6); + $rounds=80; +} else { + $func="sha256_block_data_order"; + $TABLE="K256"; + $SZ=4; + @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx", + "%r8d","%r9d","%r10d","%r11d"); + ($T1,$a0,$a1,$a2)=("%r12d","%r13d","%r14d","%r15d"); + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 7,18, 3); + @sigma1=(17,19,10); + $rounds=64; +} + +$ctx="%rdi"; # 1st arg +$round="%rdi"; # zaps $ctx +$inp="%rsi"; # 2nd arg +$Tbl="%rbp"; + +$_ctx="16*$SZ+0*8(%rsp)"; +$_inp="16*$SZ+1*8(%rsp)"; +$_end="16*$SZ+2*8(%rsp)"; +$_rsp="16*$SZ+3*8(%rsp)"; +$framesz="16*$SZ+4*8"; + + +sub ROUND_00_15() +{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___; + mov $e,$a0 + mov $e,$a1 + mov $f,$a2 + + ror \$$Sigma1[0],$a0 + ror \$$Sigma1[1],$a1 + xor $g,$a2 # f^g + + xor $a1,$a0 + ror \$`$Sigma1[2]-$Sigma1[1]`,$a1 + and $e,$a2 # (f^g)&e + mov $T1,`$SZ*($i&0xf)`(%rsp) + + xor $a1,$a0 # Sigma1(e) + xor $g,$a2 # Ch(e,f,g)=((f^g)&e)^g + add $h,$T1 # T1+=h + + mov $a,$h + add $a0,$T1 # T1+=Sigma1(e) + + add $a2,$T1 # T1+=Ch(e,f,g) + mov $a,$a0 + mov $a,$a1 + + ror \$$Sigma0[0],$h + ror \$$Sigma0[1],$a0 + mov $a,$a2 + add ($Tbl,$round,$SZ),$T1 # T1+=K[round] + + xor $a0,$h + ror \$`$Sigma0[2]-$Sigma0[1]`,$a0 + or $c,$a1 # a|c + + xor $a0,$h # h=Sigma0(a) + and $c,$a2 # a&c + add $T1,$d # d+=T1 + + and $b,$a1 # (a|c)&b + add $T1,$h # h+=T1 + + or $a2,$a1 # Maj(a,b,c)=((a|c)&b)|(a&c) + lea 1($round),$round # round++ + + add $a1,$h # h+=Maj(a,b,c) +___ +} + +sub ROUND_16_XX() +{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___; + mov `$SZ*(($i+1)&0xf)`(%rsp),$a0 + mov `$SZ*(($i+14)&0xf)`(%rsp),$T1 + + mov $a0,$a2 + + shr \$$sigma0[2],$a0 + ror \$$sigma0[0],$a2 + + xor $a2,$a0 + ror \$`$sigma0[1]-$sigma0[0]`,$a2 + + xor $a2,$a0 # sigma0(X[(i+1)&0xf]) + mov $T1,$a1 + + shr \$$sigma1[2],$T1 + ror \$$sigma1[0],$a1 + + xor $a1,$T1 + ror \$`$sigma1[1]-$sigma1[0]`,$a1 + + xor $a1,$T1 # sigma1(X[(i+14)&0xf]) + + add $a0,$T1 + + add `$SZ*(($i+9)&0xf)`(%rsp),$T1 + + add `$SZ*($i&0xf)`(%rsp),$T1 +___ + &ROUND_00_15(@_); +} + +$code=<<___; +.text + +.globl $func +.type $func,\@function,4 +.align 16 +$func: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + mov %rsp,%rbp # copy %rsp + shl \$4,%rdx # num*16 + sub \$$framesz,%rsp + lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ + and \$-64,%rsp # align stack frame + mov $ctx,$_ctx # save ctx, 1st arg + mov $inp,$_inp # save inp, 2nd arh + mov %rdx,$_end # save end pointer, "3rd" arg + mov %rbp,$_rsp # save copy of %rsp + + .picmeup $Tbl + lea $TABLE-.($Tbl),$Tbl + + mov $SZ*0($ctx),$A + mov $SZ*1($ctx),$B + mov $SZ*2($ctx),$C + mov $SZ*3($ctx),$D + mov $SZ*4($ctx),$E + mov $SZ*5($ctx),$F + mov $SZ*6($ctx),$G + mov $SZ*7($ctx),$H + jmp .Lloop + +.align 16 +.Lloop: + xor $round,$round +___ + for($i=0;$i<16;$i++) { + $code.=" mov $SZ*$i($inp),$T1\n"; + $code.=" bswap $T1\n"; + &ROUND_00_15($i,@ROT); + unshift(@ROT,pop(@ROT)); + } +$code.=<<___; + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: +___ + for(;$i<32;$i++) { + &ROUND_16_XX($i,@ROT); + unshift(@ROT,pop(@ROT)); + } + +$code.=<<___; + cmp \$$rounds,$round + jb .Lrounds_16_xx + + mov $_ctx,$ctx + lea 16*$SZ($inp),$inp + + add $SZ*0($ctx),$A + add $SZ*1($ctx),$B + add $SZ*2($ctx),$C + add $SZ*3($ctx),$D + add $SZ*4($ctx),$E + add $SZ*5($ctx),$F + add $SZ*6($ctx),$G + add $SZ*7($ctx),$H + + cmp $_end,$inp + + mov $A,$SZ*0($ctx) + mov $B,$SZ*1($ctx) + mov $C,$SZ*2($ctx) + mov $D,$SZ*3($ctx) + mov $E,$SZ*4($ctx) + mov $F,$SZ*5($ctx) + mov $G,$SZ*6($ctx) + mov $H,$SZ*7($ctx) + jb .Lloop + + mov $_rsp,%rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + + ret +.size $func,.-$func +___ + +if ($SZ==4) { +$code.=<<___; +.align 64 +.type $TABLE,\@object +$TABLE: + .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 +___ +} else { +$code.=<<___; +.align 64 +.type $TABLE,\@object +$TABLE: + .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 +___ +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/openssl/crypto/sha/sha.c b/openssl/crypto/sha/sha.c new file mode 100644 index 000000000..42126551d --- /dev/null +++ b/openssl/crypto/sha/sha.c @@ -0,0 +1,124 @@ +/* crypto/sha/sha.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/sha.h> + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +int read(int, void *, unsigned int); +int main(int argc, char **argv) + { + int i,err=0; + FILE *IN; + + if (argc == 1) + { + do_fp(stdin); + } + else + { + for (i=1; i<argc; i++) + { + IN=fopen(argv[i],"r"); + if (IN == NULL) + { + perror(argv[i]); + err++; + continue; + } + printf("SHA(%s)= ",argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); + } + +void do_fp(FILE *f) + { + SHA_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + int fd; + int i; + unsigned char buf[BUFSIZE]; + + fd=fileno(f); + SHA_Init(&c); + for (;;) + { + i=read(fd,buf,BUFSIZE); + if (i <= 0) break; + SHA_Update(&c,buf,(unsigned long)i); + } + SHA_Final(&(md[0]),&c); + pt(md); + } + +void pt(unsigned char *md) + { + int i; + + for (i=0; i<SHA_DIGEST_LENGTH; i++) + printf("%02x",md[i]); + printf("\n"); + } + diff --git a/openssl/crypto/sha/sha.h b/openssl/crypto/sha/sha.h new file mode 100644 index 000000000..47a2c29f6 --- /dev/null +++ b/openssl/crypto/sha/sha.h @@ -0,0 +1,203 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +#define HEADER_SHA_H + +#include <openssl/e_os2.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) +#error SHA is disabled. +#endif + +#if defined(OPENSSL_FIPS) +#define FIPS_SHA_SIZE_T size_t +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) +#define SHA_LONG unsigned long +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +#define SHA_LONG unsigned long +#define SHA_LONG_LOG2 3 +#else +#define SHA_LONG unsigned int +#endif + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK-8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st + { + SHA_LONG h0,h1,h2,h3,h4; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; + } SHA_CTX; + +#ifndef OPENSSL_NO_SHA0 +#ifdef OPENSSL_FIPS +int private_SHA_Init(SHA_CTX *c); +#endif +int SHA_Init(SHA_CTX *c); +int SHA_Update(SHA_CTX *c, const void *data, size_t len); +int SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); +void SHA_Transform(SHA_CTX *c, const unsigned char *data); +#endif +#ifndef OPENSSL_NO_SHA1 +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +#endif + +#define SHA256_CBLOCK (SHA_LBLOCK*4) /* SHA-256 treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA224_DIGEST_LENGTH 28 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st + { + SHA_LONG h[8]; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num,md_len; + } SHA256_CTX; + +#ifndef OPENSSL_NO_SHA256 +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +#endif + +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. */ +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +#define SHA_LONG64 unsigned __int64 +#define U64(C) C##UI64 +#elif defined(__arch64__) +#define SHA_LONG64 unsigned long +#define U64(C) C##UL +#else +#define SHA_LONG64 unsigned long long +#define U64(C) C##ULL +#endif + +typedef struct SHA512state_st + { + SHA_LONG64 h[8]; + SHA_LONG64 Nl,Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num,md_len; + } SHA512_CTX; +#endif + +#ifndef OPENSSL_NO_SHA512 +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openssl/crypto/sha/sha1.c b/openssl/crypto/sha/sha1.c new file mode 100644 index 000000000..d350c88ee --- /dev/null +++ b/openssl/crypto/sha/sha1.c @@ -0,0 +1,127 @@ +/* crypto/sha/sha1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/sha.h> + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#ifndef _OSD_POSIX +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) + { + int i,err=0; + FILE *IN; + + if (argc == 1) + { + do_fp(stdin); + } + else + { + for (i=1; i<argc; i++) + { + IN=fopen(argv[i],"r"); + if (IN == NULL) + { + perror(argv[i]); + err++; + continue; + } + printf("SHA1(%s)= ",argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); + } + +void do_fp(FILE *f) + { + SHA_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + int fd; + int i; + unsigned char buf[BUFSIZE]; + + fd=fileno(f); + SHA1_Init(&c); + for (;;) + { + i=read(fd,buf,BUFSIZE); + if (i <= 0) break; + SHA1_Update(&c,buf,(unsigned long)i); + } + SHA1_Final(&(md[0]),&c); + pt(md); + } + +void pt(unsigned char *md) + { + int i; + + for (i=0; i<SHA_DIGEST_LENGTH; i++) + printf("%02x",md[i]); + printf("\n"); + } + diff --git a/openssl/crypto/sha/sha1_one.c b/openssl/crypto/sha/sha1_one.c new file mode 100644 index 000000000..483117419 --- /dev/null +++ b/openssl/crypto/sha/sha1_one.c @@ -0,0 +1,78 @@ +/* crypto/sha/sha1_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <openssl/sha.h> +#include <openssl/crypto.h> + +#if !defined(OPENSSL_NO_SHA1) +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) + { + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) md=m; + if (!SHA1_Init(&c)) + return NULL; + SHA1_Update(&c,d,n); + SHA1_Final(md,&c); + OPENSSL_cleanse(&c,sizeof(c)); + return(md); + } +#endif diff --git a/openssl/crypto/sha/sha1dgst.c b/openssl/crypto/sha/sha1dgst.c new file mode 100644 index 000000000..d31f0781a --- /dev/null +++ b/openssl/crypto/sha/sha1dgst.c @@ -0,0 +1,78 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <openssl/opensslconf.h> +#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA) + +#undef SHA_0 +#define SHA_1 + +#include <openssl/opensslv.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + + +const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT; + +/* The implementation is in ../md32_common.h */ + +#include "sha_locl.h" + +#endif + diff --git a/openssl/crypto/sha/sha1s.cpp b/openssl/crypto/sha/sha1s.cpp new file mode 100644 index 000000000..af23d1e0f --- /dev/null +++ b/openssl/crypto/sha/sha1s.cpp @@ -0,0 +1,82 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/sha.h> + +#define sha1_block_x86 sha1_block_asm_data_order +extern "C" { +void sha1_block_x86(SHA_CTX *ctx, unsigned char *buffer,int num); +} + +void main(int argc,char *argv[]) + { + unsigned char buffer[64*256]; + SHA_CTX ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=0,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=16; + if (num > 250) num=16; + numm=num+2; +#if 0 + num*=64; + numm*=64; +#endif + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + sha1_block_x86(&ctx,buffer,numm); + GetTSC(s1); + sha1_block_x86(&ctx,buffer,numm); + GetTSC(e1); + GetTSC(s2); + sha1_block_x86(&ctx,buffer,num); + GetTSC(e2); + sha1_block_x86(&ctx,buffer,num); + } + + printf("sha1 (%d bytes) %d %d (%.2f)\n",num*64, + e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2); + } + } + diff --git a/openssl/crypto/sha/sha1test.c b/openssl/crypto/sha/sha1test.c new file mode 100644 index 000000000..6feb3964c --- /dev/null +++ b/openssl/crypto/sha/sha1test.c @@ -0,0 +1,178 @@ +/* crypto/sha/sha1test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "../e_os.h" + +#ifdef OPENSSL_NO_SHA +int main(int argc, char *argv[]) +{ + printf("No SHA support\n"); + return(0); +} +#else +#include <openssl/evp.h> +#include <openssl/sha.h> + +#ifdef CHARSET_EBCDIC +#include <openssl/ebcdic.h> +#endif + +#undef SHA_0 /* FIPS 180 */ +#define SHA_1 /* FIPS 180-1 */ + +static char *test[]={ + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL, + }; + +#ifdef SHA_0 +static char *ret[]={ + "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880", + "d2516ee1acfa5baf33dfc1c471e438449ef134c8", + }; +static char *bigret= + "3232affa48628a26653b5aaa44541fd90d690603"; +#endif +#ifdef SHA_1 +static char *ret[]={ + "a9993e364706816aba3e25717850c26c9cd0d89d", + "84983e441c3bd26ebaae4aa1f95129e5e54670f1", + }; +static char *bigret= + "34aa973cd4c4daa4f61eeb2bdbad27316534016f"; +#endif + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) + { + int i,err=0; + char **P,**R; + static unsigned char buf[1000]; + char *p,*r; + EVP_MD_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + +#ifdef CHARSET_EBCDIC + ebcdic2ascii(test[0], test[0], strlen(test[0])); + ebcdic2ascii(test[1], test[1], strlen(test[1])); +#endif + + EVP_MD_CTX_init(&c); + P=test; + R=ret; + i=1; + while (*P != NULL) + { + EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha1(), NULL); + p=pt(md); + if (strcmp(p,(char *)*R) != 0) + { + printf("error calculating SHA1 on '%s'\n",*P); + printf("got %s instead of %s\n",p,*R); + err++; + } + else + printf("test %d ok\n",i); + i++; + R++; + P++; + } + + memset(buf,'a',1000); +#ifdef CHARSET_EBCDIC + ebcdic2ascii(buf, buf, 1000); +#endif /*CHARSET_EBCDIC*/ + EVP_DigestInit_ex(&c,EVP_sha1(), NULL); + for (i=0; i<1000; i++) + EVP_DigestUpdate(&c,buf,1000); + EVP_DigestFinal_ex(&c,md,NULL); + p=pt(md); + + r=bigret; + if (strcmp(p,r) != 0) + { + printf("error calculating SHA1 on 'a' * 1000\n"); + printf("got %s instead of %s\n",p,r); + err++; + } + else + printf("test 3 ok\n"); + +#ifdef OPENSSL_SYS_NETWARE + if (err) printf("ERROR: %d\n", err); +#endif + EXIT(err); + EVP_MD_CTX_cleanup(&c); + return(0); + } + +static char *pt(unsigned char *md) + { + int i; + static char buf[80]; + + for (i=0; i<SHA_DIGEST_LENGTH; i++) + sprintf(&(buf[i*2]),"%02x",md[i]); + return(buf); + } +#endif diff --git a/openssl/crypto/sha/sha256.c b/openssl/crypto/sha/sha256.c new file mode 100644 index 000000000..3256a83e9 --- /dev/null +++ b/openssl/crypto/sha/sha256.c @@ -0,0 +1,292 @@ +/* crypto/sha/sha256.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +#include <openssl/opensslconf.h> +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + +#include <stdlib.h> +#include <string.h> + +#include <openssl/crypto.h> +#include <openssl/sha.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + +#include <openssl/opensslv.h> + +const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; + +int SHA224_Init (SHA256_CTX *c) + { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif + c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; + c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; + c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; + c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL; + c->Nl=0; c->Nh=0; + c->num=0; c->md_len=SHA224_DIGEST_LENGTH; + return 1; + } + +int SHA256_Init (SHA256_CTX *c) + { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif + c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; + c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; + c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; + c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL; + c->Nl=0; c->Nh=0; + c->num=0; c->md_len=SHA256_DIGEST_LENGTH; + return 1; + } + +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) + { + SHA256_CTX c; + static unsigned char m[SHA224_DIGEST_LENGTH]; + + if (md == NULL) md=m; + SHA224_Init(&c); + SHA256_Update(&c,d,n); + SHA256_Final(md,&c); + OPENSSL_cleanse(&c,sizeof(c)); + return(md); + } + +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) + { + SHA256_CTX c; + static unsigned char m[SHA256_DIGEST_LENGTH]; + + if (md == NULL) md=m; + SHA256_Init(&c); + SHA256_Update(&c,d,n); + SHA256_Final(md,&c); + OPENSSL_cleanse(&c,sizeof(c)); + return(md); + } + +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) +{ return SHA256_Update (c,data,len); } +int SHA224_Final (unsigned char *md, SHA256_CTX *c) +{ return SHA256_Final (md,c); } + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_CTX SHA256_CTX +#define HASH_CBLOCK SHA_CBLOCK +/* + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." + * default: case below covers for it. It's not clear however if it's + * permitted to truncate to amount of bytes not divisible by 4. I bet not, + * but if it is, then default: case shall be extended. For reference. + * Idea behind separate cases for pre-defined lenghts is to let the + * compiler decide if it's appropriate to unroll small loops. + */ +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + unsigned int xn; \ + switch ((c)->md_len) \ + { case SHA224_DIGEST_LENGTH: \ + for (xn=0;xn<SHA224_DIGEST_LENGTH/4;xn++) \ + { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ + break; \ + case SHA256_DIGEST_LENGTH: \ + for (xn=0;xn<SHA256_DIGEST_LENGTH/4;xn++) \ + { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ + break; \ + default: \ + if ((c)->md_len > SHA256_DIGEST_LENGTH) \ + return 0; \ + for (xn=0;xn<(c)->md_len/4;xn++) \ + { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ + break; \ + } \ + } while (0) + +#define HASH_UPDATE SHA256_Update +#define HASH_TRANSFORM SHA256_Transform +#define HASH_FINAL SHA256_Final +#define HASH_BLOCK_DATA_ORDER sha256_block_data_order +#ifndef SHA256_ASM +static +#endif +void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num); + +#include "md32_common.h" + +#ifndef SHA256_ASM +static const SHA_LONG K256[64] = { + 0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL, + 0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL, + 0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL, + 0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL, + 0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL, + 0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL, + 0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL, + 0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL, + 0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL, + 0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL, + 0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL, + 0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL, + 0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL, + 0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL, + 0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL, + 0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL }; + +/* + * FIPS specification refers to right rotations, while our ROTATE macro + * is left one. This is why you might notice that rotation coefficients + * differ from those observed in FIPS document by 32-N... + */ +#define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) +#define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) +#define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) +#define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) + +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#ifdef OPENSSL_SMALL_FOOTPRINT + +static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num) + { + unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1,T2; + SHA_LONG X[16],l; + int i; + const unsigned char *data=in; + + while (num--) { + + a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; + e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; + + for (i=0;i<16;i++) + { + HOST_c2l(data,l); T1 = X[i] = l; + T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; + T2 = Sigma0(a) + Maj(a,b,c); + h = g; g = f; f = e; e = d + T1; + d = c; c = b; b = a; a = T1 + T2; + } + + for (;i<64;i++) + { + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); + + T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf]; + T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; + T2 = Sigma0(a) + Maj(a,b,c); + h = g; g = f; f = e; e = d + T1; + d = c; c = b; b = a; a = T1 + T2; + } + + ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; + ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; + + } +} + +#else + +#define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) + +#define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ + ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) + +static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num) + { + unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1; + SHA_LONG X[16]; + int i; + const unsigned char *data=in; + const union { long one; char little; } is_endian = {1}; + + while (num--) { + + a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; + e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; + + if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)in%4)==0) + { + const SHA_LONG *W=(const SHA_LONG *)data; + + T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h); + T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g); + T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f); + T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e); + T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d); + T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c); + T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b); + T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a); + T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h); + T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g); + T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f); + T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e); + T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d); + T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c); + T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b); + T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a); + + data += SHA256_CBLOCK; + } + else + { + SHA_LONG l; + + HOST_c2l(data,l); T1 = X[0] = l; ROUND_00_15(0,a,b,c,d,e,f,g,h); + HOST_c2l(data,l); T1 = X[1] = l; ROUND_00_15(1,h,a,b,c,d,e,f,g); + HOST_c2l(data,l); T1 = X[2] = l; ROUND_00_15(2,g,h,a,b,c,d,e,f); + HOST_c2l(data,l); T1 = X[3] = l; ROUND_00_15(3,f,g,h,a,b,c,d,e); + HOST_c2l(data,l); T1 = X[4] = l; ROUND_00_15(4,e,f,g,h,a,b,c,d); + HOST_c2l(data,l); T1 = X[5] = l; ROUND_00_15(5,d,e,f,g,h,a,b,c); + HOST_c2l(data,l); T1 = X[6] = l; ROUND_00_15(6,c,d,e,f,g,h,a,b); + HOST_c2l(data,l); T1 = X[7] = l; ROUND_00_15(7,b,c,d,e,f,g,h,a); + HOST_c2l(data,l); T1 = X[8] = l; ROUND_00_15(8,a,b,c,d,e,f,g,h); + HOST_c2l(data,l); T1 = X[9] = l; ROUND_00_15(9,h,a,b,c,d,e,f,g); + HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f); + HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e); + HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d); + HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c); + HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b); + HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a); + } + + for (i=16;i<64;i+=8) + { + ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X); + ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X); + ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X); + ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X); + ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X); + ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X); + ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X); + ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X); + } + + ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; + ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; + + } + } + +#endif +#endif /* SHA256_ASM */ + +#endif /* OPENSSL_NO_SHA256 */ diff --git a/openssl/crypto/sha/sha256t.c b/openssl/crypto/sha/sha256t.c new file mode 100644 index 000000000..6b4a3bd00 --- /dev/null +++ b/openssl/crypto/sha/sha256t.c @@ -0,0 +1,147 @@ +/* crypto/sha/sha256t.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * ==================================================================== + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <openssl/sha.h> +#include <openssl/evp.h> + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256) +int main(int argc, char *argv[]) +{ + printf("No SHA256 support\n"); + return(0); +} +#else + +unsigned char app_b1[SHA256_DIGEST_LENGTH] = { + 0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea, + 0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, + 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c, + 0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad }; + +unsigned char app_b2[SHA256_DIGEST_LENGTH] = { + 0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8, + 0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, + 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67, + 0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1 }; + +unsigned char app_b3[SHA256_DIGEST_LENGTH] = { + 0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92, + 0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, + 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e, + 0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0 }; + +unsigned char addenum_1[SHA224_DIGEST_LENGTH] = { + 0x23,0x09,0x7d,0x22,0x34,0x05,0xd8,0x22, + 0x86,0x42,0xa4,0x77,0xbd,0xa2,0x55,0xb3, + 0x2a,0xad,0xbc,0xe4,0xbd,0xa0,0xb3,0xf7, + 0xe3,0x6c,0x9d,0xa7 }; + +unsigned char addenum_2[SHA224_DIGEST_LENGTH] = { + 0x75,0x38,0x8b,0x16,0x51,0x27,0x76,0xcc, + 0x5d,0xba,0x5d,0xa1,0xfd,0x89,0x01,0x50, + 0xb0,0xc6,0x45,0x5c,0xb4,0xf5,0x8b,0x19, + 0x52,0x52,0x25,0x25 }; + +unsigned char addenum_3[SHA224_DIGEST_LENGTH] = { + 0x20,0x79,0x46,0x55,0x98,0x0c,0x91,0xd8, + 0xbb,0xb4,0xc1,0xea,0x97,0x61,0x8a,0x4b, + 0xf0,0x3f,0x42,0x58,0x19,0x48,0xb2,0xee, + 0x4e,0xe7,0xad,0x67 }; + +int main (int argc,char **argv) +{ unsigned char md[SHA256_DIGEST_LENGTH]; + int i; + EVP_MD_CTX evp; + + fprintf(stdout,"Testing SHA-256 "); + + EVP_Digest ("abc",3,md,NULL,EVP_sha256(),NULL); + if (memcmp(md,app_b1,sizeof(app_b1))) + { fflush(stdout); + fprintf(stderr,"\nTEST 1 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk" + "ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha256(),NULL); + if (memcmp(md,app_b2,sizeof(app_b2))) + { fflush(stdout); + fprintf(stderr,"\nTEST 2 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_MD_CTX_init (&evp); + EVP_DigestInit_ex (&evp,EVP_sha256(),NULL); + for (i=0;i<1000000;i+=160) + EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa", + (1000000-i)<160?1000000-i:160); + EVP_DigestFinal_ex (&evp,md,NULL); + EVP_MD_CTX_cleanup (&evp); + + if (memcmp(md,app_b3,sizeof(app_b3))) + { fflush(stdout); + fprintf(stderr,"\nTEST 3 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + fprintf(stdout," passed.\n"); fflush(stdout); + + fprintf(stdout,"Testing SHA-224 "); + + EVP_Digest ("abc",3,md,NULL,EVP_sha224(),NULL); + if (memcmp(md,addenum_1,sizeof(addenum_1))) + { fflush(stdout); + fprintf(stderr,"\nTEST 1 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_Digest ("abcdbcde""cdefdefg""efghfghi""ghijhijk" + "ijkljklm""klmnlmno""mnopnopq",56,md,NULL,EVP_sha224(),NULL); + if (memcmp(md,addenum_2,sizeof(addenum_2))) + { fflush(stdout); + fprintf(stderr,"\nTEST 2 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_MD_CTX_init (&evp); + EVP_DigestInit_ex (&evp,EVP_sha224(),NULL); + for (i=0;i<1000000;i+=64) + EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa", + (1000000-i)<64?1000000-i:64); + EVP_DigestFinal_ex (&evp,md,NULL); + EVP_MD_CTX_cleanup (&evp); + + if (memcmp(md,addenum_3,sizeof(addenum_3))) + { fflush(stdout); + fprintf(stderr,"\nTEST 3 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + fprintf(stdout," passed.\n"); fflush(stdout); + + return 0; +} +#endif diff --git a/openssl/crypto/sha/sha512.c b/openssl/crypto/sha/sha512.c new file mode 100644 index 000000000..f5ed468b8 --- /dev/null +++ b/openssl/crypto/sha/sha512.c @@ -0,0 +1,547 @@ +/* crypto/sha/sha512.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +#include <openssl/opensslconf.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) +/* + * IMPLEMENTATION NOTES. + * + * As you might have noticed 32-bit hash algorithms: + * + * - permit SHA_LONG to be wider than 32-bit (case on CRAY); + * - optimized versions implement two transform functions: one operating + * on [aligned] data in host byte order and one - on data in input + * stream byte order; + * - share common byte-order neutral collector and padding function + * implementations, ../md32_common.h; + * + * Neither of the above applies to this SHA-512 implementations. Reasons + * [in reverse order] are: + * + * - it's the only 64-bit hash algorithm for the moment of this writing, + * there is no need for common collector/padding implementation [yet]; + * - by supporting only one transform function [which operates on + * *aligned* data in input stream byte order, big-endian in this case] + * we minimize burden of maintenance in two ways: a) collector/padding + * function is simpler; b) only one transform function to stare at; + * - SHA_LONG64 is required to be exactly 64-bit in order to be able to + * apply a number of optimizations to mitigate potential performance + * penalties caused by previous design decision; + * + * Caveat lector. + * + * Implementation relies on the fact that "long long" is 64-bit on + * both 32- and 64-bit platforms. If some compiler vendor comes up + * with 128-bit long long, adjustment to sha.h would be required. + * As this implementation relies on 64-bit integer type, it's totally + * inappropriate for platforms which don't support it, most notably + * 16-bit platforms. + * <appro@fy.chalmers.se> + */ +#include <stdlib.h> +#include <string.h> + +#include <openssl/crypto.h> +#include <openssl/sha.h> +#include <openssl/opensslv.h> + +#include "cryptlib.h" + +const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT; + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) || \ + defined(SHA512_ASM) +#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +#endif + +int SHA384_Init (SHA512_CTX *c) + { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif + c->h[0]=U64(0xcbbb9d5dc1059ed8); + c->h[1]=U64(0x629a292a367cd507); + c->h[2]=U64(0x9159015a3070dd17); + c->h[3]=U64(0x152fecd8f70e5939); + c->h[4]=U64(0x67332667ffc00b31); + c->h[5]=U64(0x8eb44a8768581511); + c->h[6]=U64(0xdb0c2e0d64f98fa7); + c->h[7]=U64(0x47b5481dbefa4fa4); + c->Nl=0; c->Nh=0; + c->num=0; c->md_len=SHA384_DIGEST_LENGTH; + return 1; + } + +int SHA512_Init (SHA512_CTX *c) + { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif + c->h[0]=U64(0x6a09e667f3bcc908); + c->h[1]=U64(0xbb67ae8584caa73b); + c->h[2]=U64(0x3c6ef372fe94f82b); + c->h[3]=U64(0xa54ff53a5f1d36f1); + c->h[4]=U64(0x510e527fade682d1); + c->h[5]=U64(0x9b05688c2b3e6c1f); + c->h[6]=U64(0x1f83d9abfb41bd6b); + c->h[7]=U64(0x5be0cd19137e2179); + c->Nl=0; c->Nh=0; + c->num=0; c->md_len=SHA512_DIGEST_LENGTH; + return 1; + } + +#ifndef SHA512_ASM +static +#endif +void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num); + +int SHA512_Final (unsigned char *md, SHA512_CTX *c) + { + unsigned char *p=(unsigned char *)c->u.p; + size_t n=c->num; + + p[n]=0x80; /* There always is a room for one */ + n++; + if (n > (sizeof(c->u)-16)) + memset (p+n,0,sizeof(c->u)-n), n=0, + sha512_block_data_order (c,p,1); + + memset (p+n,0,sizeof(c->u)-16-n); +#ifdef B_ENDIAN + c->u.d[SHA_LBLOCK-2] = c->Nh; + c->u.d[SHA_LBLOCK-1] = c->Nl; +#else + p[sizeof(c->u)-1] = (unsigned char)(c->Nl); + p[sizeof(c->u)-2] = (unsigned char)(c->Nl>>8); + p[sizeof(c->u)-3] = (unsigned char)(c->Nl>>16); + p[sizeof(c->u)-4] = (unsigned char)(c->Nl>>24); + p[sizeof(c->u)-5] = (unsigned char)(c->Nl>>32); + p[sizeof(c->u)-6] = (unsigned char)(c->Nl>>40); + p[sizeof(c->u)-7] = (unsigned char)(c->Nl>>48); + p[sizeof(c->u)-8] = (unsigned char)(c->Nl>>56); + p[sizeof(c->u)-9] = (unsigned char)(c->Nh); + p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8); + p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16); + p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24); + p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32); + p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40); + p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48); + p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56); +#endif + + sha512_block_data_order (c,p,1); + + if (md==0) return 0; + + switch (c->md_len) + { + /* Let compiler decide if it's appropriate to unroll... */ + case SHA384_DIGEST_LENGTH: + for (n=0;n<SHA384_DIGEST_LENGTH/8;n++) + { + SHA_LONG64 t = c->h[n]; + + *(md++) = (unsigned char)(t>>56); + *(md++) = (unsigned char)(t>>48); + *(md++) = (unsigned char)(t>>40); + *(md++) = (unsigned char)(t>>32); + *(md++) = (unsigned char)(t>>24); + *(md++) = (unsigned char)(t>>16); + *(md++) = (unsigned char)(t>>8); + *(md++) = (unsigned char)(t); + } + break; + case SHA512_DIGEST_LENGTH: + for (n=0;n<SHA512_DIGEST_LENGTH/8;n++) + { + SHA_LONG64 t = c->h[n]; + + *(md++) = (unsigned char)(t>>56); + *(md++) = (unsigned char)(t>>48); + *(md++) = (unsigned char)(t>>40); + *(md++) = (unsigned char)(t>>32); + *(md++) = (unsigned char)(t>>24); + *(md++) = (unsigned char)(t>>16); + *(md++) = (unsigned char)(t>>8); + *(md++) = (unsigned char)(t); + } + break; + /* ... as well as make sure md_len is not abused. */ + default: return 0; + } + + return 1; + } + +int SHA384_Final (unsigned char *md,SHA512_CTX *c) +{ return SHA512_Final (md,c); } + +int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len) + { + SHA_LONG64 l; + unsigned char *p=c->u.p; + const unsigned char *data=(const unsigned char *)_data; + + if (len==0) return 1; + + l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff); + if (l < c->Nl) c->Nh++; + if (sizeof(len)>=8) c->Nh+=(((SHA_LONG64)len)>>61); + c->Nl=l; + + if (c->num != 0) + { + size_t n = sizeof(c->u) - c->num; + + if (len < n) + { + memcpy (p+c->num,data,len), c->num += len; + return 1; + } + else { + memcpy (p+c->num,data,n), c->num = 0; + len-=n, data+=n; + sha512_block_data_order (c,p,1); + } + } + + if (len >= sizeof(c->u)) + { +#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)data%sizeof(c->u.d[0]) != 0) + while (len >= sizeof(c->u)) + memcpy (p,data,sizeof(c->u)), + sha512_block_data_order (c,p,1), + len -= sizeof(c->u), + data += sizeof(c->u); + else +#endif + sha512_block_data_order (c,data,len/sizeof(c->u)), + data += len, + len %= sizeof(c->u), + data -= len; + } + + if (len != 0) memcpy (p,data,len), c->num = (int)len; + + return 1; + } + +int SHA384_Update (SHA512_CTX *c, const void *data, size_t len) +{ return SHA512_Update (c,data,len); } + +void SHA512_Transform (SHA512_CTX *c, const unsigned char *data) +{ sha512_block_data_order (c,data,1); } + +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) + { + SHA512_CTX c; + static unsigned char m[SHA384_DIGEST_LENGTH]; + + if (md == NULL) md=m; + SHA384_Init(&c); + SHA512_Update(&c,d,n); + SHA512_Final(md,&c); + OPENSSL_cleanse(&c,sizeof(c)); + return(md); + } + +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) + { + SHA512_CTX c; + static unsigned char m[SHA512_DIGEST_LENGTH]; + + if (md == NULL) md=m; + SHA512_Init(&c); + SHA512_Update(&c,d,n); + SHA512_Final(md,&c); + OPENSSL_cleanse(&c,sizeof(c)); + return(md); + } + +#ifndef SHA512_ASM +static const SHA_LONG64 K512[80] = { + U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd), + U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc), + U64(0x3956c25bf348b538),U64(0x59f111f1b605d019), + U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118), + U64(0xd807aa98a3030242),U64(0x12835b0145706fbe), + U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2), + U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1), + U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694), + U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3), + U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65), + U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483), + U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5), + U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210), + U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4), + U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725), + U64(0x06ca6351e003826f),U64(0x142929670a0e6e70), + U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926), + U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df), + U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8), + U64(0x81c2c92e47edaee6),U64(0x92722c851482353b), + U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001), + U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30), + U64(0xd192e819d6ef5218),U64(0xd69906245565a910), + U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8), + U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53), + U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8), + U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb), + U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3), + U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60), + U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec), + U64(0x90befffa23631e28),U64(0xa4506cebde82bde9), + U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b), + U64(0xca273eceea26619c),U64(0xd186b8c721c0c207), + U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178), + U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6), + U64(0x113f9804bef90dae),U64(0x1b710b35131c471b), + U64(0x28db77f523047d84),U64(0x32caab7b40c72493), + U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c), + U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a), + U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) }; + +#ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__x86_64) || defined(__x86_64__) +# define ROTR(a,n) ({ unsigned long ret; \ + asm ("rorq %1,%0" \ + : "=r"(ret) \ + : "J"(n),"0"(a) \ + : "cc"); ret; }) +# if !defined(B_ENDIAN) +# define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \ + asm ("bswapq %0" \ + : "=r"(ret) \ + : "0"(ret)); ret; }) +# endif +# elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN) +# if defined(I386_ONLY) +# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ + unsigned int hi=p[0],lo=p[1]; \ + asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\ + "roll $16,%%eax; roll $16,%%edx; "\ + "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \ + : "=a"(lo),"=d"(hi) \ + : "0"(lo),"1"(hi) : "cc"); \ + ((SHA_LONG64)hi)<<32|lo; }) +# else +# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ + unsigned int hi=p[0],lo=p[1]; \ + asm ("bswapl %0; bswapl %1;" \ + : "=r"(lo),"=r"(hi) \ + : "0"(lo),"1"(hi)); \ + ((SHA_LONG64)hi)<<32|lo; }) +# endif +# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) +# define ROTR(a,n) ({ unsigned long ret; \ + asm ("rotrdi %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a),"K"(n)); ret; }) +# endif +# elif defined(_MSC_VER) +# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# define ROTR(a,n) _rotr64((a),n) +# endif +# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(I386_ONLY) + static SHA_LONG64 __fastcall __pull64be(const void *x) + { _asm mov edx, [ecx + 0] + _asm mov eax, [ecx + 4] + _asm xchg dh,dl + _asm xchg ah,al + _asm rol edx,16 + _asm rol eax,16 + _asm xchg dh,dl + _asm xchg ah,al + } +# else + static SHA_LONG64 __fastcall __pull64be(const void *x) + { _asm mov edx, [ecx + 0] + _asm mov eax, [ecx + 4] + _asm bswap edx + _asm bswap eax + } +# endif +# define PULL64(x) __pull64be(&(x)) +# if _MSC_VER<=1200 +# pragma inline_depth(0) +# endif +# endif +# endif +#endif + +#ifndef PULL64 +#define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) +#define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) +#endif + +#ifndef ROTR +#define ROTR(x,s) (((x)>>s) | (x)<<(64-s)) +#endif + +#define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) +#define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) +#define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) +#define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) +#define GO_FOR_SSE2(ctx,in,num) do { \ + void sha512_block_sse2(void *,const void *,size_t); \ + if (!(OPENSSL_ia32cap_P & (1<<26))) break; \ + sha512_block_sse2(ctx->h,in,num); return; \ + } while (0) +#endif + +#ifdef OPENSSL_SMALL_FOOTPRINT + +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) + { + const SHA_LONG64 *W=in; + SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1,T2; + SHA_LONG64 X[16]; + int i; + +#ifdef GO_FOR_SSE2 + GO_FOR_SSE2(ctx,in,num); +#endif + + while (num--) { + + a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; + e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; + + for (i=0;i<16;i++) + { +#ifdef B_ENDIAN + T1 = X[i] = W[i]; +#else + T1 = X[i] = PULL64(W[i]); +#endif + T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; + T2 = Sigma0(a) + Maj(a,b,c); + h = g; g = f; f = e; e = d + T1; + d = c; c = b; b = a; a = T1 + T2; + } + + for (;i<80;i++) + { + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); + + T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf]; + T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; + T2 = Sigma0(a) + Maj(a,b,c); + h = g; g = f; f = e; e = d + T1; + d = c; c = b; b = a; a = T1 + T2; + } + + ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; + ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; + + W+=SHA_LBLOCK; + } + } + +#else + +#define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) + +#define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ + ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) + +static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) + { + const SHA_LONG64 *W=in; + SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1; + SHA_LONG64 X[16]; + int i; + +#ifdef GO_FOR_SSE2 + GO_FOR_SSE2(ctx,in,num); +#endif + + while (num--) { + + a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; + e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; + +#ifdef B_ENDIAN + T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h); + T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g); + T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f); + T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e); + T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d); + T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c); + T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b); + T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a); + T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h); + T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g); + T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f); + T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e); + T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d); + T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c); + T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b); + T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a); +#else + T1 = X[0] = PULL64(W[0]); ROUND_00_15(0,a,b,c,d,e,f,g,h); + T1 = X[1] = PULL64(W[1]); ROUND_00_15(1,h,a,b,c,d,e,f,g); + T1 = X[2] = PULL64(W[2]); ROUND_00_15(2,g,h,a,b,c,d,e,f); + T1 = X[3] = PULL64(W[3]); ROUND_00_15(3,f,g,h,a,b,c,d,e); + T1 = X[4] = PULL64(W[4]); ROUND_00_15(4,e,f,g,h,a,b,c,d); + T1 = X[5] = PULL64(W[5]); ROUND_00_15(5,d,e,f,g,h,a,b,c); + T1 = X[6] = PULL64(W[6]); ROUND_00_15(6,c,d,e,f,g,h,a,b); + T1 = X[7] = PULL64(W[7]); ROUND_00_15(7,b,c,d,e,f,g,h,a); + T1 = X[8] = PULL64(W[8]); ROUND_00_15(8,a,b,c,d,e,f,g,h); + T1 = X[9] = PULL64(W[9]); ROUND_00_15(9,h,a,b,c,d,e,f,g); + T1 = X[10] = PULL64(W[10]); ROUND_00_15(10,g,h,a,b,c,d,e,f); + T1 = X[11] = PULL64(W[11]); ROUND_00_15(11,f,g,h,a,b,c,d,e); + T1 = X[12] = PULL64(W[12]); ROUND_00_15(12,e,f,g,h,a,b,c,d); + T1 = X[13] = PULL64(W[13]); ROUND_00_15(13,d,e,f,g,h,a,b,c); + T1 = X[14] = PULL64(W[14]); ROUND_00_15(14,c,d,e,f,g,h,a,b); + T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); +#endif + + for (i=16;i<80;i+=8) + { + ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X); + ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X); + ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X); + ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X); + ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X); + ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X); + ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X); + ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X); + } + + ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; + ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; + + W+=SHA_LBLOCK; + } + } + +#endif + +#endif /* SHA512_ASM */ + +#endif /* OPENSSL_NO_SHA512 */ diff --git a/openssl/crypto/sha/sha512t.c b/openssl/crypto/sha/sha512t.c new file mode 100644 index 000000000..210041d43 --- /dev/null +++ b/openssl/crypto/sha/sha512t.c @@ -0,0 +1,184 @@ +/* crypto/sha/sha512t.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * ==================================================================== + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <openssl/sha.h> +#include <openssl/evp.h> +#include <openssl/crypto.h> + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512) +int main(int argc, char *argv[]) +{ + printf("No SHA512 support\n"); + return(0); +} +#else + +unsigned char app_c1[SHA512_DIGEST_LENGTH] = { + 0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba, + 0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31, + 0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2, + 0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a, + 0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8, + 0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd, + 0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e, + 0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f }; + +unsigned char app_c2[SHA512_DIGEST_LENGTH] = { + 0x8e,0x95,0x9b,0x75,0xda,0xe3,0x13,0xda, + 0x8c,0xf4,0xf7,0x28,0x14,0xfc,0x14,0x3f, + 0x8f,0x77,0x79,0xc6,0xeb,0x9f,0x7f,0xa1, + 0x72,0x99,0xae,0xad,0xb6,0x88,0x90,0x18, + 0x50,0x1d,0x28,0x9e,0x49,0x00,0xf7,0xe4, + 0x33,0x1b,0x99,0xde,0xc4,0xb5,0x43,0x3a, + 0xc7,0xd3,0x29,0xee,0xb6,0xdd,0x26,0x54, + 0x5e,0x96,0xe5,0x5b,0x87,0x4b,0xe9,0x09 }; + +unsigned char app_c3[SHA512_DIGEST_LENGTH] = { + 0xe7,0x18,0x48,0x3d,0x0c,0xe7,0x69,0x64, + 0x4e,0x2e,0x42,0xc7,0xbc,0x15,0xb4,0x63, + 0x8e,0x1f,0x98,0xb1,0x3b,0x20,0x44,0x28, + 0x56,0x32,0xa8,0x03,0xaf,0xa9,0x73,0xeb, + 0xde,0x0f,0xf2,0x44,0x87,0x7e,0xa6,0x0a, + 0x4c,0xb0,0x43,0x2c,0xe5,0x77,0xc3,0x1b, + 0xeb,0x00,0x9c,0x5c,0x2c,0x49,0xaa,0x2e, + 0x4e,0xad,0xb2,0x17,0xad,0x8c,0xc0,0x9b }; + +unsigned char app_d1[SHA384_DIGEST_LENGTH] = { + 0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b, + 0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07, + 0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63, + 0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed, + 0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23, + 0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7 }; + +unsigned char app_d2[SHA384_DIGEST_LENGTH] = { + 0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8, + 0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47, + 0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2, + 0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12, + 0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9, + 0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39 }; + +unsigned char app_d3[SHA384_DIGEST_LENGTH] = { + 0x9d,0x0e,0x18,0x09,0x71,0x64,0x74,0xcb, + 0x08,0x6e,0x83,0x4e,0x31,0x0a,0x4a,0x1c, + 0xed,0x14,0x9e,0x9c,0x00,0xf2,0x48,0x52, + 0x79,0x72,0xce,0xc5,0x70,0x4c,0x2a,0x5b, + 0x07,0xb8,0xb3,0xdc,0x38,0xec,0xc4,0xeb, + 0xae,0x97,0xdd,0xd8,0x7f,0x3d,0x89,0x85 }; + +int main (int argc,char **argv) +{ unsigned char md[SHA512_DIGEST_LENGTH]; + int i; + EVP_MD_CTX evp; + +#ifdef OPENSSL_IA32_SSE2 + /* Alternative to this is to call OpenSSL_add_all_algorithms... + * The below code is retained exclusively for debugging purposes. */ + { char *env; + + if ((env=getenv("OPENSSL_ia32cap"))) + OPENSSL_ia32cap = strtoul (env,NULL,0); + } +#endif + + fprintf(stdout,"Testing SHA-512 "); + + EVP_Digest ("abc",3,md,NULL,EVP_sha512(),NULL); + if (memcmp(md,app_c1,sizeof(app_c1))) + { fflush(stdout); + fprintf(stderr,"\nTEST 1 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk" + "efghijkl""fghijklm""ghijklmn""hijklmno" + "ijklmnop""jklmnopq""klmnopqr""lmnopqrs" + "mnopqrst""nopqrstu",112,md,NULL,EVP_sha512(),NULL); + if (memcmp(md,app_c2,sizeof(app_c2))) + { fflush(stdout); + fprintf(stderr,"\nTEST 2 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_MD_CTX_init (&evp); + EVP_DigestInit_ex (&evp,EVP_sha512(),NULL); + for (i=0;i<1000000;i+=288) + EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa", + (1000000-i)<288?1000000-i:288); + EVP_DigestFinal_ex (&evp,md,NULL); + EVP_MD_CTX_cleanup (&evp); + + if (memcmp(md,app_c3,sizeof(app_c3))) + { fflush(stdout); + fprintf(stderr,"\nTEST 3 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + fprintf(stdout," passed.\n"); fflush(stdout); + + fprintf(stdout,"Testing SHA-384 "); + + EVP_Digest ("abc",3,md,NULL,EVP_sha384(),NULL); + if (memcmp(md,app_d1,sizeof(app_d1))) + { fflush(stdout); + fprintf(stderr,"\nTEST 1 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_Digest ("abcdefgh""bcdefghi""cdefghij""defghijk" + "efghijkl""fghijklm""ghijklmn""hijklmno" + "ijklmnop""jklmnopq""klmnopqr""lmnopqrs" + "mnopqrst""nopqrstu",112,md,NULL,EVP_sha384(),NULL); + if (memcmp(md,app_d2,sizeof(app_d2))) + { fflush(stdout); + fprintf(stderr,"\nTEST 2 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + EVP_MD_CTX_init (&evp); + EVP_DigestInit_ex (&evp,EVP_sha384(),NULL); + for (i=0;i<1000000;i+=64) + EVP_DigestUpdate (&evp, "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa" + "aaaaaaaa""aaaaaaaa""aaaaaaaa""aaaaaaaa", + (1000000-i)<64?1000000-i:64); + EVP_DigestFinal_ex (&evp,md,NULL); + EVP_MD_CTX_cleanup (&evp); + + if (memcmp(md,app_d3,sizeof(app_d3))) + { fflush(stdout); + fprintf(stderr,"\nTEST 3 of 3 failed.\n"); + return 1; + } + else + fprintf(stdout,"."); fflush(stdout); + + fprintf(stdout," passed.\n"); fflush(stdout); + + return 0; +} +#endif diff --git a/openssl/crypto/sha/sha_dgst.c b/openssl/crypto/sha/sha_dgst.c new file mode 100644 index 000000000..598f4d721 --- /dev/null +++ b/openssl/crypto/sha/sha_dgst.c @@ -0,0 +1,80 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <openssl/opensslconf.h> +#include <openssl/crypto.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + +#include <openssl/err.h> +#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA) + +#undef SHA_1 +#define SHA_0 + +#include <openssl/opensslv.h> + +const char SHA_version[]="SHA" OPENSSL_VERSION_PTEXT; + +/* The implementation is in ../md32_common.h */ + +#include "sha_locl.h" + +#endif + diff --git a/openssl/crypto/sha/sha_locl.h b/openssl/crypto/sha/sha_locl.h new file mode 100644 index 000000000..da46ddfe7 --- /dev/null +++ b/openssl/crypto/sha/sha_locl.h @@ -0,0 +1,446 @@ +/* crypto/sha/sha_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdlib.h> +#include <string.h> + +#include <openssl/opensslconf.h> +#include <openssl/sha.h> + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK SHA_CBLOCK +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->h0; HOST_l2c(ll,(s)); \ + ll=(c)->h1; HOST_l2c(ll,(s)); \ + ll=(c)->h2; HOST_l2c(ll,(s)); \ + ll=(c)->h3; HOST_l2c(ll,(s)); \ + ll=(c)->h4; HOST_l2c(ll,(s)); \ + } while (0) + +#if defined(SHA_0) + +# define HASH_UPDATE SHA_Update +# define HASH_TRANSFORM SHA_Transform +# define HASH_FINAL SHA_Final +# define HASH_INIT SHA_Init +# define HASH_BLOCK_DATA_ORDER sha_block_data_order +# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id)) + +static void sha_block_data_order (SHA_CTX *c, const void *p,size_t num); + +#elif defined(SHA_1) + +# define HASH_UPDATE SHA1_Update +# define HASH_TRANSFORM SHA1_Transform +# define HASH_FINAL SHA1_Final +# define HASH_INIT SHA1_Init +# define HASH_BLOCK_DATA_ORDER sha1_block_data_order +# if defined(__MWERKS__) && defined(__MC68K__) + /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */ +# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \ + ix=(a)=ROTATE((a),1); \ + } while (0) +# else +# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ + ix=(a)=ROTATE((a),1) \ + ) +# endif + +#ifndef SHA1_ASM +static +#endif +void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num); + +#else +# error "Either SHA_0 or SHA_1 must be defined." +#endif + +#include "md32_common.h" + +#define INIT_DATA_h0 0x67452301UL +#define INIT_DATA_h1 0xefcdab89UL +#define INIT_DATA_h2 0x98badcfeUL +#define INIT_DATA_h3 0x10325476UL +#define INIT_DATA_h4 0xc3d2e1f0UL + +#if defined(SHA_0) && defined(OPENSSL_FIPS) +FIPS_NON_FIPS_MD_Init(SHA) +#else +int HASH_INIT (SHA_CTX *c) +#endif + { +#if defined(SHA_1) && defined(OPENSSL_FIPS) + FIPS_selftest_check(); +#endif + c->h0=INIT_DATA_h0; + c->h1=INIT_DATA_h1; + c->h2=INIT_DATA_h2; + c->h3=INIT_DATA_h3; + c->h4=INIT_DATA_h4; + c->Nl=0; + c->Nh=0; + c->num=0; + return 1; + } + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +/* As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be + * simplified to the code in F_00_19. Wei attributes these optimisations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) + * I've just become aware of another tweak to be made, again from Wei Dai, + * in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#ifndef OPENSSL_SMALL_FOOTPRINT + +#define BODY_00_15(i,a,b,c,d,e,f,xi) \ + (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#ifdef X +#undef X +#endif +#ifndef MD32_XARRAY + /* + * Originally X was an array. As it's automatic it's natural + * to expect RISC compiler to accomodate at least part of it in + * the register bank, isn't it? Unfortunately not all compilers + * "find" this expectation reasonable:-( On order to make such + * compilers generate better code I replace X[] with a bunch of + * X0, X1, etc. See the function body below... + * <appro@fy.chalmers.se> + */ +# define X(i) XX##i +#else + /* + * However! Some compilers (most notably HP C) get overwhelmed by + * that many local variables so that we have to have the way to + * fall down to the original behavior. + */ +# define X(i) XX[i] +#endif + +#if !defined(SHA_1) || !defined(SHA1_ASM) +static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num) + { + const unsigned char *data=p; + register unsigned MD32_REG_T A,B,C,D,E,T,l; +#ifndef MD32_XARRAY + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; +#else + SHA_LONG XX[16]; +#endif + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + for (;;) + { + const union { long one; char little; } is_endian = {1}; + + if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)p%4)==0) + { + const SHA_LONG *W=(const SHA_LONG *)data; + + X( 0) = W[0]; X( 1) = W[ 1]; + BODY_00_15( 0,A,B,C,D,E,T,X( 0)); X( 2) = W[ 2]; + BODY_00_15( 1,T,A,B,C,D,E,X( 1)); X( 3) = W[ 3]; + BODY_00_15( 2,E,T,A,B,C,D,X( 2)); X( 4) = W[ 4]; + BODY_00_15( 3,D,E,T,A,B,C,X( 3)); X( 5) = W[ 5]; + BODY_00_15( 4,C,D,E,T,A,B,X( 4)); X( 6) = W[ 6]; + BODY_00_15( 5,B,C,D,E,T,A,X( 5)); X( 7) = W[ 7]; + BODY_00_15( 6,A,B,C,D,E,T,X( 6)); X( 8) = W[ 8]; + BODY_00_15( 7,T,A,B,C,D,E,X( 7)); X( 9) = W[ 9]; + BODY_00_15( 8,E,T,A,B,C,D,X( 8)); X(10) = W[10]; + BODY_00_15( 9,D,E,T,A,B,C,X( 9)); X(11) = W[11]; + BODY_00_15(10,C,D,E,T,A,B,X(10)); X(12) = W[12]; + BODY_00_15(11,B,C,D,E,T,A,X(11)); X(13) = W[13]; + BODY_00_15(12,A,B,C,D,E,T,X(12)); X(14) = W[14]; + BODY_00_15(13,T,A,B,C,D,E,X(13)); X(15) = W[15]; + BODY_00_15(14,E,T,A,B,C,D,X(14)); + BODY_00_15(15,D,E,T,A,B,C,X(15)); + + data += SHA_CBLOCK; + } + else + { + HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l; + BODY_00_15( 0,A,B,C,D,E,T,X( 0)); HOST_c2l(data,l); X( 2)=l; + BODY_00_15( 1,T,A,B,C,D,E,X( 1)); HOST_c2l(data,l); X( 3)=l; + BODY_00_15( 2,E,T,A,B,C,D,X( 2)); HOST_c2l(data,l); X( 4)=l; + BODY_00_15( 3,D,E,T,A,B,C,X( 3)); HOST_c2l(data,l); X( 5)=l; + BODY_00_15( 4,C,D,E,T,A,B,X( 4)); HOST_c2l(data,l); X( 6)=l; + BODY_00_15( 5,B,C,D,E,T,A,X( 5)); HOST_c2l(data,l); X( 7)=l; + BODY_00_15( 6,A,B,C,D,E,T,X( 6)); HOST_c2l(data,l); X( 8)=l; + BODY_00_15( 7,T,A,B,C,D,E,X( 7)); HOST_c2l(data,l); X( 9)=l; + BODY_00_15( 8,E,T,A,B,C,D,X( 8)); HOST_c2l(data,l); X(10)=l; + BODY_00_15( 9,D,E,T,A,B,C,X( 9)); HOST_c2l(data,l); X(11)=l; + BODY_00_15(10,C,D,E,T,A,B,X(10)); HOST_c2l(data,l); X(12)=l; + BODY_00_15(11,B,C,D,E,T,A,X(11)); HOST_c2l(data,l); X(13)=l; + BODY_00_15(12,A,B,C,D,E,T,X(12)); HOST_c2l(data,l); X(14)=l; + BODY_00_15(13,T,A,B,C,D,E,X(13)); HOST_c2l(data,l); X(15)=l; + BODY_00_15(14,E,T,A,B,C,D,X(14)); + BODY_00_15(15,D,E,T,A,B,C,X(15)); + } + + BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13)); + BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14)); + BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15)); + BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0)); + + BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1)); + BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2)); + BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3)); + BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4)); + BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5)); + BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6)); + BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7)); + BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8)); + BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9)); + BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10)); + BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11)); + BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12)); + + BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13)); + BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14)); + BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15)); + BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0)); + BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1)); + BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2)); + BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3)); + BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4)); + + BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5)); + BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6)); + BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7)); + BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8)); + BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9)); + BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10)); + BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11)); + BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12)); + BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13)); + BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14)); + BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15)); + BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0)); + BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1)); + BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2)); + BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3)); + BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4)); + BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5)); + BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6)); + BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7)); + BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8)); + + BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9)); + BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10)); + BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11)); + BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12)); + BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13)); + BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14)); + BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15)); + BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0)); + BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1)); + BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2)); + BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3)); + BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4)); + BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5)); + BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6)); + BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7)); + BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8)); + BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9)); + BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10)); + BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11)); + BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12)); + + c->h0=(c->h0+E)&0xffffffffL; + c->h1=(c->h1+T)&0xffffffffL; + c->h2=(c->h2+A)&0xffffffffL; + c->h3=(c->h3+B)&0xffffffffL; + c->h4=(c->h4+C)&0xffffffffL; + + if (--num == 0) break; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + } + } +#endif + +#else /* OPENSSL_SMALL_FOOTPRINT */ + +#define BODY_00_15(xi) do { \ + T=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xi; } while(0) + +#define BODY_16_19(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +#define BODY_20_39(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_20_39+F_20_39(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +#define BODY_40_59(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_40_59+F_40_59(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +#define BODY_60_79(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T=E+K_60_79+F_60_79(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xa; } while(0) + +#if !defined(SHA_1) || !defined(SHA1_ASM) +static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num) + { + const unsigned char *data=p; + register unsigned MD32_REG_T A,B,C,D,E,T,l; + int i; + SHA_LONG X[16]; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + for (;;) + { + for (i=0;i<16;i++) + { HOST_c2l(data,l); X[i]=l; BODY_00_15(X[i]); } + for (i=0;i<4;i++) + { BODY_16_19(X[i], X[i+2], X[i+8], X[(i+13)&15]); } + for (;i<24;i++) + { BODY_20_39(X[i&15], X[(i+2)&15], X[(i+8)&15],X[(i+13)&15]); } + for (i=0;i<20;i++) + { BODY_40_59(X[(i+8)&15],X[(i+10)&15],X[i&15], X[(i+5)&15]); } + for (i=4;i<24;i++) + { BODY_60_79(X[(i+8)&15],X[(i+10)&15],X[i&15], X[(i+5)&15]); } + + c->h0=(c->h0+A)&0xffffffffL; + c->h1=(c->h1+B)&0xffffffffL; + c->h2=(c->h2+C)&0xffffffffL; + c->h3=(c->h3+D)&0xffffffffL; + c->h4=(c->h4+E)&0xffffffffL; + + if (--num == 0) break; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + } + } +#endif + +#endif diff --git a/openssl/crypto/sha/sha_one.c b/openssl/crypto/sha/sha_one.c new file mode 100644 index 000000000..3bae623ce --- /dev/null +++ b/openssl/crypto/sha/sha_one.c @@ -0,0 +1,78 @@ +/* crypto/sha/sha_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <openssl/sha.h> +#include <openssl/crypto.h> + +#ifndef OPENSSL_NO_SHA0 +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md) + { + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) md=m; + if (!SHA_Init(&c)) + return NULL; + SHA_Update(&c,d,n); + SHA_Final(md,&c); + OPENSSL_cleanse(&c,sizeof(c)); + return(md); + } +#endif diff --git a/openssl/crypto/sha/shatest.c b/openssl/crypto/sha/shatest.c new file mode 100644 index 000000000..ed0fe06a7 --- /dev/null +++ b/openssl/crypto/sha/shatest.c @@ -0,0 +1,178 @@ +/* crypto/sha/shatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "../e_os.h" + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) +int main(int argc, char *argv[]) +{ + printf("No SHA0 support\n"); + return(0); +} +#else +#include <openssl/evp.h> +#include <openssl/sha.h> + +#ifdef CHARSET_EBCDIC +#include <openssl/ebcdic.h> +#endif + +#define SHA_0 /* FIPS 180 */ +#undef SHA_1 /* FIPS 180-1 */ + +static char *test[]={ + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL, + }; + +#ifdef SHA_0 +static char *ret[]={ + "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880", + "d2516ee1acfa5baf33dfc1c471e438449ef134c8", + }; +static char *bigret= + "3232affa48628a26653b5aaa44541fd90d690603"; +#endif +#ifdef SHA_1 +static char *ret[]={ + "a9993e364706816aba3e25717850c26c9cd0d89d", + "84983e441c3bd26ebaae4aa1f95129e5e54670f1", + }; +static char *bigret= + "34aa973cd4c4daa4f61eeb2bdbad27316534016f"; +#endif + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) + { + int i,err=0; + char **P,**R; + static unsigned char buf[1000]; + char *p,*r; + EVP_MD_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + +#ifdef CHARSET_EBCDIC + ebcdic2ascii(test[0], test[0], strlen(test[0])); + ebcdic2ascii(test[1], test[1], strlen(test[1])); +#endif + + EVP_MD_CTX_init(&c); + P=test; + R=ret; + i=1; + while (*P != NULL) + { + EVP_Digest(*P,strlen((char *)*P),md,NULL,EVP_sha(), NULL); + p=pt(md); + if (strcmp(p,(char *)*R) != 0) + { + printf("error calculating SHA on '%s'\n",*P); + printf("got %s instead of %s\n",p,*R); + err++; + } + else + printf("test %d ok\n",i); + i++; + R++; + P++; + } + + memset(buf,'a',1000); +#ifdef CHARSET_EBCDIC + ebcdic2ascii(buf, buf, 1000); +#endif /*CHARSET_EBCDIC*/ + EVP_DigestInit_ex(&c,EVP_sha(), NULL); + for (i=0; i<1000; i++) + EVP_DigestUpdate(&c,buf,1000); + EVP_DigestFinal_ex(&c,md,NULL); + p=pt(md); + + r=bigret; + if (strcmp(p,r) != 0) + { + printf("error calculating SHA on '%s'\n",p); + printf("got %s instead of %s\n",p,r); + err++; + } + else + printf("test 3 ok\n"); + +#ifdef OPENSSL_SYS_NETWARE + if (err) printf("ERROR: %d\n", err); +#endif + EVP_MD_CTX_cleanup(&c); + EXIT(err); + return(0); + } + +static char *pt(unsigned char *md) + { + int i; + static char buf[80]; + + for (i=0; i<SHA_DIGEST_LENGTH; i++) + sprintf(&(buf[i*2]),"%02x",md[i]); + return(buf); + } +#endif |