00001
00008 #define DKUTIL_C_SHA256_C
00009 #include "dkcSHA256.h"
00010 #include "dkcStdio.h"
00011
00012
00013 # define SHA256_BUFFER_SIZE (SHA256_BLOCK * 4)
00014
00015
00016 const static DWORD c_dwInitH[SHA256_HASH] = {
00017 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
00018 };
00019
00020 const static DWORD c_dwK[SHA256_WORK] = {
00021 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00022 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00023 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00024 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00025 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00026 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00027 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00028 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
00029 };
00030
00031
00032 static DKC_INLINE DWORD ReverseEndian(DWORD x) {
00033 return dkcReverseEndian32(x);
00034
00035 }
00036 static DKC_INLINE DWORD Rotate(DWORD x, DWORD n) {return (x >> n) | (x << (32 - n));}
00037 static DKC_INLINE DWORD Ch(DWORD x, DWORD y, DWORD z) {return (x & (y ^ z)) ^ z;}
00038 static DKC_INLINE DWORD Maj(DWORD x, DWORD y, DWORD z) {return (x & (y | z)) | (y & z);}
00039 static DKC_INLINE DWORD S0(DWORD x) {return Rotate(x, 2) ^ Rotate(x, 13) ^ Rotate(x, 22);}
00040 static DKC_INLINE DWORD S1(DWORD x) {return Rotate(x, 6) ^ Rotate(x, 11) ^ Rotate(x, 25);}
00041 static DKC_INLINE DWORD s0(DWORD x) {return Rotate(x, 7) ^ Rotate(x, 18) ^ (x >> 3);}
00042 static DKC_INLINE DWORD s1(DWORD x) {return Rotate(x, 17) ^ Rotate(x, 19) ^ (x >> 10);}
00043
00044
00045 static void Generate(DKC_SHA256 *p){
00046 int i;
00047 DWORD W[SHA256_WORK];
00048 DWORD Hash[SHA256_WORK + SHA256_HASH];
00049 DWORD *pHash;
00050 DWORD dwT1, dwT2;
00051
00052
00053 for(i = 0; i < SHA256_BLOCK; i++) W[i] = ReverseEndian(p->m_aBlock[i]);
00054 for(i = SHA256_BLOCK; i < SHA256_WORK; i++) W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
00055
00056 for(i = 0; i < SHA256_HASH; i++) Hash[SHA256_WORK + i] = p->m_dwH[i];
00057 pHash = &Hash[SHA256_WORK];
00058
00059 for(i = 0; i < SHA256_WORK; i++){
00060 pHash--;
00061 dwT1 = pHash[8] + S1(pHash[5]) + Ch(pHash[5], pHash[6], pHash[7]) + c_dwK[i] + W[i];
00062 dwT2 = S0(pHash[1]) + Maj(pHash[1], pHash[2], pHash[3]);
00063 pHash[0] = dwT1 + dwT2;
00064 pHash[4] += dwT1;
00065 }
00066 for(i = 0; i < SHA256_HASH; i++) p->m_dwH[i] += pHash[i];
00067 }
00068
00069 DKC_SHA256 *WINAPI dkcAllocSHA256(){
00070 DKC_SHA256 *p = dkcAllocate(sizeof(DKC_SHA256));
00071 if(NULL==p){
00072 return NULL;
00073 }
00074 dkcSHA256Init(p);
00075 return p;
00076 }
00077
00078 void WINAPI dkcSHA256Init(DKC_SHA256 *p){
00079 int i;
00080 for(i = 0; i < SHA256_HASH; i++){
00081 p->m_dwH[i] = c_dwInitH[i];
00082 }
00083 p->m_dwLNumBits = 0;
00084 p->m_dwHNumBits = 0;
00085 p->m_nNumChr = 0;
00086 p->mFinalized = FALSE;
00087 }
00088
00089 void WINAPI dkcSHA256Load(DKC_SHA256 *p,const BYTE *pBuffer,DWORD dwSize){
00090 DWORD dwReadSize;
00091 DWORD dwLNumBits;
00092 BYTE *pBlock;
00093
00094 if(dwSize == 0) return;
00095 if(p->mFinalized){
00096 return;
00097 }
00098 dwLNumBits = (p->m_dwLNumBits + (dwSize << 3));
00099 if(dwLNumBits < p->m_dwLNumBits) p->m_dwHNumBits++;
00100 p->m_dwHNumBits += dwSize >> 29;
00101 p->m_dwLNumBits = dwLNumBits;
00102
00103 pBlock = (BYTE *)p->m_aBlock;
00104
00105 while(dwSize){
00106
00107 dwReadSize = (dwSize < SHA256_BUFFER_SIZE - (DWORD)p->m_nNumChr) ?
00108 dwSize :
00109 (SHA256_BUFFER_SIZE - p->m_nNumChr);
00110
00111 memcpy(pBlock + p->m_nNumChr, pBuffer, dwReadSize);
00112
00113 p->m_nNumChr += dwReadSize;
00114 pBuffer += dwReadSize;
00115 dwSize -= dwReadSize;
00116
00117 if(p->m_nNumChr == SHA256_BUFFER_SIZE){
00118 Generate(p);
00119 p->m_nNumChr = 0;
00120 }
00121 }
00122 }
00123
00124 void WINAPI dkcSHA256Final(DKC_SHA256 *p){
00125
00126 BYTE cZero = 0x00;
00127 BYTE cOne = 0x80;
00128 DWORD dwHNumBits;
00129 DWORD dwLNumBits;
00130
00131 if(p->mFinalized){
00132 return;
00133 }
00134
00135 dwHNumBits = ReverseEndian(p->m_dwHNumBits);
00136 dwLNumBits = ReverseEndian(p->m_dwLNumBits);
00137
00138 dkcSHA256Load(p,&cOne, 1);
00139 while(p->m_nNumChr != SHA256_BUFFER_SIZE - 8) dkcSHA256Load(p,&cZero, 1);
00140
00141 dkcSHA256Load(p,(BYTE *)&dwHNumBits, 4);
00142 dkcSHA256Load(p,(BYTE *)&dwLNumBits, 4);
00143
00144
00145 p->mFinalized = TRUE;
00146 }
00147
00148 int WINAPI dkcSHA256DigestStr(DKC_SHA256 *p,char *buff,size_t size){
00149
00150 char s[SHA256_STR_BUFFER_SIZE];
00151 int i;
00152
00153 s[SHA256_HASH * 8]='\0';
00154 if(SHA256_STR_BUFFER_SIZE > size){
00155 return edk_BufferOverFlow;
00156 }
00157 if(FALSE==p->mFinalized){
00158
00159 return edk_LogicError;
00160 }
00161
00162 for(i = 0; i < SHA256_HASH; i++){
00163 sprintf(s + i * 8, "%08x", p->m_dwH[i]);
00164 }
00165
00166
00167 return dkc_strcpy(buff,size,s,strlen(s));
00168 }
00169 int WINAPI dkcSHA256FinalDigestStr(DKC_SHA256 *p,char *buff,size_t size){
00170 dkcSHA256Final(p);
00171 return dkcSHA256DigestStr(p,buff,size);
00172 }
00173
00174
00175
00176 int WINAPI dkcSHA256Digest(DKC_SHA256 *p,BYTE *buff,size_t size){
00177 size_t i;
00178 if(SHA256_BIN_BUFFER_SIZE > size){
00179 return edk_BufferOverFlow;
00180 }
00181 if(FALSE==p->mFinalized){
00182
00183 return edk_LogicError;
00184 }
00185 for(i = 0; i < SHA256_BIN_BUFFER_SIZE; ++i){
00186 buff[i] = (BYTE)(p->m_dwH[i >> 2] >> (8 * (~i & 3)));
00187 }
00188 return edk_SUCCEEDED;
00189
00190 }
00191
00192 int WINAPI dkcSHA256FinalDigest(DKC_SHA256 *p,BYTE *buff,size_t size){
00193 dkcSHA256Final(p);
00194 return dkcSHA256Digest(p,buff,size);
00195 }
00196
00197
00198 int WINAPI dkcFreeSHA256(DKC_SHA256 **p){
00199 if(NULL==p){
00200 return edk_FAILED;
00201 }
00202 return dkcFree((void **)p);
00203 }