Published 29 Dec 2009, by
Anders Rundgren

No tags
00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00036
00037
00038
00039
00040
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 }