Search Code
About crypto

Published 29 Dec 2009.

Last change message: N/A

Import this program

crypto

Published 29 Dec 2009, by   user Anders Rundgren   tag No tags
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHA1Provider.cpp Source File

SHA1Provider.cpp

00001 /* ====================================================================
00002  * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
00003  *
00004  * This product includes cryptographic software written by Eric Young
00005  * (eay@cryptsoft.com).  This product includes software written by Tim
00006  * Hudson (tjh@cryptsoft.com).
00007  *
00008  * ====================================================================
00009  * C++ adoption was made by Anders Rundgren (anders.rundgren@telia.com)
00010  * ====================================================================
00011  */
00012 
00013 #include <string.h>
00014 #include <stdlib.h>
00015 
00016 #include "crypto.h"
00017 
00018 #include "_shacommon.h"
00019 
00020 #define INIT_DATA_h0 0x67452301UL
00021 #define INIT_DATA_h1 0xefcdab89UL
00022 #define INIT_DATA_h2 0x98badcfeUL
00023 #define INIT_DATA_h3 0x10325476UL
00024 #define INIT_DATA_h4 0xc3d2e1f0UL
00025 
00026 #define Xupdate(a,ix,ia,ib,ic,id)   ( (a)=(ia^ib^ic^id),    \
00027                       ix=(a)=ROTATE((a),1)  \
00028                     )
00029 
00030 #define K_00_19 0x5a827999UL
00031 #define K_20_39 0x6ed9eba1UL
00032 #define K_40_59 0x8f1bbcdcUL
00033 #define K_60_79 0xca62c1d6UL
00034 
00035 /* As  pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
00036  * simplified to the code in F_00_19.  Wei attributes these optimisations
00037  * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
00038  * #define F(x,y,z) (((x) & (y))  |  ((~(x)) & (z)))
00039  * I've just become aware of another tweak to be made, again from Wei Dai,
00040  * in F_40_59, (x&a)|(y&a) -> (x|y)&a
00041  */
00042 #define F_00_19(b,c,d)  ((((c) ^ (d)) & (b)) ^ (d))
00043 #define F_20_39(b,c,d)  ((b) ^ (c) ^ (d))
00044 #define F_40_59(b,c,d)  (((b) & (c)) | (((b)|(c)) & (d)))
00045 #define F_60_79(b,c,d)  F_20_39(b,c,d)
00046 
00047 #define BODY_00_15(xi)       do {   \
00048     T=E+K_00_19+F_00_19(B,C,D); \
00049     E=D, D=C, C=ROTATE(B,30), B=A;  \
00050     A=ROTATE(A,5)+T+xi;     } while(0)
00051 
00052 #define BODY_16_19(xa,xb,xc,xd)  do {   \
00053     Xupdate(T,xa,xa,xb,xc,xd);  \
00054     T+=E+K_00_19+F_00_19(B,C,D);    \
00055     E=D, D=C, C=ROTATE(B,30), B=A;  \
00056     A=ROTATE(A,5)+T;        } while(0)
00057 
00058 #define BODY_20_39(xa,xb,xc,xd)  do {   \
00059     Xupdate(T,xa,xa,xb,xc,xd);  \
00060     T+=E+K_20_39+F_20_39(B,C,D);    \
00061     E=D, D=C, C=ROTATE(B,30), B=A;  \
00062     A=ROTATE(A,5)+T;        } while(0)
00063 
00064 #define BODY_40_59(xa,xb,xc,xd)  do {   \
00065     Xupdate(T,xa,xa,xb,xc,xd);  \
00066     T+=E+K_40_59+F_40_59(B,C,D);    \
00067     E=D, D=C, C=ROTATE(B,30), B=A;  \
00068     A=ROTATE(A,5)+T;        } while(0)
00069 
00070 #define BODY_60_79(xa,xb,xc,xd)  do {   \
00071     Xupdate(T,xa,xa,xb,xc,xd);  \
00072     T=E+K_60_79+F_60_79(B,C,D); \
00073     E=D, D=C, C=ROTATE(B,30), B=A;  \
00074     A=ROTATE(A,5)+T+xa;     } while(0)
00075 
00076 namespace webpki
00077 {
00078 
00079 const int SHA1Provider::DIGEST_LENGTH;
00080 
00081 
00082 SHA1Provider::SHA1Provider ()
00083   {
00084     _init ();
00085   }
00086 
00087 
00088 void SHA1Provider::_init ()
00089   {
00090     m_error = NULL;
00091     m_needs_init = false;
00092     m_sha_ctx.h[0] = INIT_DATA_h0;
00093     m_sha_ctx.h[1] = INIT_DATA_h1;
00094     m_sha_ctx.h[2] = INIT_DATA_h2;
00095     m_sha_ctx.h[3] = INIT_DATA_h3;
00096     m_sha_ctx.h[4] = INIT_DATA_h4;
00097     m_sha_ctx.Nl = 0;
00098     m_sha_ctx.Nh = 0;
00099     m_sha_ctx.num = 0;
00100     m_sha_ctx.digest_length = DIGEST_LENGTH;
00101   }
00102 
00103 
00104 void SHA1Provider::hash_block_data_order (const unsigned char* data, int num)
00105   {
00106     CRYPTO_U32 A, B, C, D, E, T, l;
00107     int i;
00108     CRYPTO_U32 X[16];
00109 
00110     A = m_sha_ctx.h[0];
00111     B = m_sha_ctx.h[1];
00112     C = m_sha_ctx.h[2];
00113     D = m_sha_ctx.h[3];
00114     E = m_sha_ctx.h[4];
00115 
00116     while (true)
00117       {
00118         for (i = 0; i < 16; i++)
00119           {
00120             HOST_c2l(data,l); X[i]=l; BODY_00_15(X[i]);
00121           }
00122         for (i = 0; i < 4; i++)
00123           {
00124             BODY_16_19(X[i], X[i+2], X[i+8], X[(i+13)&15]);
00125           }
00126         for (;i < 24; i++)
00127           {
00128             BODY_20_39(X[i&15], X[(i+2)&15], X[(i+8)&15], X[(i+13)&15]);
00129           }
00130         for (i = 0; i < 20; i++)
00131           {
00132             BODY_40_59(X[(i+8)&15], X[(i+10)&15], X[i&15], X[(i+5)&15]);
00133           }
00134         for (i = 4; i < 24; i++)
00135           {
00136             BODY_60_79(X[(i+8)&15], X[(i+10)&15], X[i&15], X[(i+5)&15]);
00137           }
00138 
00139         m_sha_ctx.h[0] = (m_sha_ctx.h[0] + A) & 0xffffffffL;
00140         m_sha_ctx.h[1] = (m_sha_ctx.h[1] + B) & 0xffffffffL;
00141         m_sha_ctx.h[2] = (m_sha_ctx.h[2] + C) & 0xffffffffL;
00142         m_sha_ctx.h[3] = (m_sha_ctx.h[3] + D) & 0xffffffffL;
00143         m_sha_ctx.h[4] = (m_sha_ctx.h[4] + E) & 0xffffffffL;
00144 
00145         if (--num == 0) break;
00146 
00147         A = m_sha_ctx.h[0];
00148         B = m_sha_ctx.h[1];
00149         C = m_sha_ctx.h[2];
00150         D = m_sha_ctx.h[3];
00151         E = m_sha_ctx.h[4];
00152 
00153       }
00154   }
00155 
00156 
00157 }