diff options
author | Ulf Möller <ulf@openssl.org> | 1999-05-05 00:23:53 +0000 |
---|---|---|
committer | Ulf Möller <ulf@openssl.org> | 1999-05-05 00:23:53 +0000 |
commit | 8e7f966bf3579629ce553f9512ee6952588c02a4 (patch) | |
tree | 56a280158be8a9da490d215564792ca4a4967553 /crypto/sha/sha_dgst.c | |
parent | 744029c15470a6b16e9645a16c76bbff15be7596 (diff) | |
download | openssl-8e7f966bf3579629ce553f9512ee6952588c02a4.tar.gz |
SHA-1 cleanups and performance enhancements.
Submitted by: Andy Polyakov <appro@fy.chalmers.se>
Diffstat (limited to 'crypto/sha/sha_dgst.c')
-rw-r--r-- | crypto/sha/sha_dgst.c | 163 |
1 files changed, 110 insertions, 53 deletions
diff --git a/crypto/sha/sha_dgst.c b/crypto/sha/sha_dgst.c index 5827c73cea..d90f497763 100644 --- a/crypto/sha/sha_dgst.c +++ b/crypto/sha/sha_dgst.c @@ -81,12 +81,21 @@ char *SHA_version="SHA" OPENSSL_VERSION_PTEXT; #define K_40_59 0x8f1bbcdcUL #define K_60_79 0xca62c1d6UL - void sha_block(SHA_CTX *c, register SHA_LONG *p, int num); -#define M_c2nl c2nl -#define M_p_c2nl p_c2nl -#define M_c2nl_p c2nl_p -#define M_p_c2nl_p p_c2nl_p -#define M_nl2c nl2c +static void sha_block(SHA_CTX *c, register SHA_LONG *p, int num); + +#if !defined(B_ENDIAN) && defined(SHA_ASM) +# define M_c2nl c2l +# define M_p_c2nl p_c2l +# define M_c2nl_p c2l_p +# define M_p_c2nl_p p_c2l_p +# define M_nl2c l2c +#else +# define M_c2nl c2nl +# define M_p_c2nl p_c2nl +# define M_c2nl_p c2nl_p +# define M_p_c2nl_p p_c2nl_p +# define M_nl2c nl2c +#endif void SHA_Init(SHA_CTX *c) { @@ -133,7 +142,7 @@ void SHA_Update(SHA_CTX *c, const register unsigned char *data, } len-=(SHA_CBLOCK-c->num); - sha_block(c,p,64); + sha_block(c,p,1); c->num=0; /* drop through and do the rest */ } @@ -170,15 +179,15 @@ void SHA_Update(SHA_CTX *c, const register unsigned char *data, * copies it to a local array. I should be able to do this for * the C version as well.... */ -#if 1 +#if SHA_LONG_LOG2==2 #if defined(B_ENDIAN) || defined(SHA_ASM) if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0) { sw=len/SHA_CBLOCK; if (sw) { - sw*=SHA_CBLOCK; sha_block(c,(SHA_LONG *)data,sw); + sw*=SHA_CBLOCK; data+=sw; len-=sw; } @@ -190,35 +199,61 @@ void SHA_Update(SHA_CTX *c, const register unsigned char *data, p=c->data; while (len >= SHA_CBLOCK) { -#if defined(B_ENDIAN) || defined(L_ENDIAN) +#if SHA_LONG_LOG2==2 +#if defined(B_ENDIAN) || defined(SHA_ASM) +#define SHA_NO_TAIL_CODE + /* + * Basically we get here only when data happens + * to be unaligned. + */ if (p != (SHA_LONG *)data) memcpy(p,data,SHA_CBLOCK); data+=SHA_CBLOCK; -# ifdef L_ENDIAN -# ifndef SHA_ASM /* Will not happen */ - for (sw=(SHA_LBLOCK/4); sw; sw--) + sha_block(c,p=c->data,1); + len-=SHA_CBLOCK; +#else /* little-endian */ +#define BE_COPY(dst,src,i) { \ + l = ((SHA_LONG *)src)[i]; \ + Endian_Reverse32(l); \ + dst[i] = l; \ + } + if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0) { - Endian_Reverse32(p[0]); - Endian_Reverse32(p[1]); - Endian_Reverse32(p[2]); - Endian_Reverse32(p[3]); - p+=4; + for (sw=(SHA_LBLOCK/4); sw; sw--) + { + BE_COPY(p,data,0); + BE_COPY(p,data,1); + BE_COPY(p,data,2); + BE_COPY(p,data,3); + p+=4; + data += 4*sizeof(SHA_LONG); + } + sha_block(c,p=c->data,1); + len-=SHA_CBLOCK; + continue; } +#endif +#endif +#ifndef SHA_NO_TAIL_CODE + /* + * In addition to "sizeof(SHA_LONG)!= 4" case the + * following code covers unaligned access cases on + * little-endian machines. + * <appro@fy.chalmers.se> + */ p=c->data; -# endif -# endif -#else - for (sw=(SHA_BLOCK/4); sw; sw--) + for (sw=(SHA_LBLOCK/4); sw; sw--) { - M_c2nl(data,l); *(p++)=l; - M_c2nl(data,l); *(p++)=l; - M_c2nl(data,l); *(p++)=l; - M_c2nl(data,l); *(p++)=l; + M_c2nl(data,l); p[0]=l; + M_c2nl(data,l); p[1]=l; + M_c2nl(data,l); p[2]=l; + M_c2nl(data,l); p[3]=l; + p+=4; } p=c->data; -#endif - sha_block(c,p,64); + sha_block(c,p,1); len-=SHA_CBLOCK; +#endif } ec=(int)len; c->num=ec; @@ -233,26 +268,35 @@ void SHA_Update(SHA_CTX *c, const register unsigned char *data, void SHA_Transform(SHA_CTX *c, unsigned char *b) { - SHA_LONG p[16]; -#if !defined(B_ENDIAN) + SHA_LONG p[SHA_LBLOCK]; SHA_LONG *q; int i; -#endif -#if defined(B_ENDIAN) || defined(L_ENDIAN) - memcpy(p,b,64); -#ifdef L_ENDIAN - q=p; - for (i=(SHA_LBLOCK/4); i; i--) +#if SHA_LONG_LOG2==2 +#if defined(B_ENDIAN) || defined(SHA_ASM) + memcpy(p,b,SHA_CBLOCK); + sha_block(c,p,1); + return; +#else + if (((unsigned long)b%sizeof(SHA_LONG)) == 0) { - Endian_Reverse32(q[0]); - Endian_Reverse32(q[1]); - Endian_Reverse32(q[2]); - Endian_Reverse32(q[3]); - q+=4; + q=p; + for (i=(SHA_LBLOCK/4); i; i--) + { + unsigned long l; + BE_COPY(q,b,0); /* BE_COPY was defined above */ + BE_COPY(q,b,1); + BE_COPY(q,b,2); + BE_COPY(q,b,3); + q+=4; + b+=4*sizeof(SHA_LONG); + } + sha_block(c,p,1); + return; } #endif -#else +#endif +#ifndef SHA_NO_TAIL_CODE /* defined above, see comment */ q=p; for (i=(SHA_LBLOCK/4); i; i--) { @@ -262,14 +306,15 @@ void SHA_Transform(SHA_CTX *c, unsigned char *b) c2nl(b,l); *(q++)=l; c2nl(b,l); *(q++)=l; } + sha_block(c,p,1); #endif - sha_block(c,p,64); } -void sha_block(SHA_CTX *c, register SHA_LONG *W, int num) +#ifndef SHA_ASM +static void sha_block(SHA_CTX *c, register SHA_LONG *W, int num) { register SHA_LONG A,B,C,D,E,T; - SHA_LONG X[16]; + SHA_LONG X[SHA_LBLOCK]; A=c->h0; B=c->h1; @@ -369,8 +414,7 @@ void sha_block(SHA_CTX *c, register SHA_LONG *W, int num) c->h3=(c->h3+B)&0xffffffffL; c->h4=(c->h4+C)&0xffffffffL; - num-=64; - if (num <= 0) break; + if (--num <= 0) break; A=c->h0; B=c->h1; @@ -378,9 +422,15 @@ void sha_block(SHA_CTX *c, register SHA_LONG *W, int num) D=c->h3; E=c->h4; - W+=16; + W+=SHA_LBLOCK; /* Note! This can happen only when sizeof(SHA_LONG) + * is 4. Whenever it's not the actual case this + * function is never called with num larger than 1 + * and we never advance down here. + * <appro@fy.chalmers.se> + */ } } +#endif void SHA_Final(unsigned char *md, SHA_CTX *c) { @@ -406,14 +456,20 @@ void SHA_Final(unsigned char *md, SHA_CTX *c) { for (; i<SHA_LBLOCK; i++) p[i]=0; - sha_block(c,p,64); + sha_block(c,p,1); i=0; } for (; i<(SHA_LBLOCK-2); i++) p[i]=0; p[SHA_LBLOCK-2]=c->Nh; p[SHA_LBLOCK-1]=c->Nl; - sha_block(c,p,64); +#if SHA_LONG_LOG2==2 +#if !defined(B_ENDIAN) && defined(SHA_ASM) + Endian_Reverse32(p[SHA_LBLOCK-2]); + Endian_Reverse32(p[SHA_LBLOCK-1]); +#endif +#endif + sha_block(c,p,1); cp=md; l=c->h0; nl2c(l,cp); l=c->h1; nl2c(l,cp); @@ -421,9 +477,10 @@ void SHA_Final(unsigned char *md, SHA_CTX *c) l=c->h3; nl2c(l,cp); l=c->h4; nl2c(l,cp); - /* clear stuff, sha_block may be leaving some stuff on the stack - * but I'm not worried :-) */ c->num=0; -/* memset((char *)&c,0,sizeof(c));*/ + /* sha_block may be leaving some stuff on the stack + * but I'm not worried :-) + memset((void *)c,0,sizeof(SHA_CTX)); + */ } #endif |