📄 sha1.cpp
字号:
}}/* The function automatically defines if we are Big or Little Endian */static void ReverseDWORD( DWORD *Data, int Length_DWORD ){ int i; DWORD dwTmp; if((*(DWORD *)("ABCD") >> 24) == 'A') return; // Nothing to do for(i=0; i<Length_DWORD; i++) { dwTmp = (Data[i] << 16) | (Data[i] >> 16); Data[i] = ((dwTmp & 0xFF00FF00L) >> 8) | ((dwTmp & 0x00FF00FFL) << 8); }}/********************************************************************** * * SHA1Init() initializes a context of the message digest calculations. * The memory to store the context is reserved before and the pointer * on the context's memory stored in FSHashAlgorithm element * **********************************************************************/int SHA1Init(void *context, byte *key, size_t key_size){ SHA1Context *sha_ctx = (SHA1Context *)context; sha_ctx->digest[0] = A_init; sha_ctx->digest[1] = B_init; sha_ctx->digest[2] = C_init; sha_ctx->digest[3] = D_init; sha_ctx->digest[4] = E_init; /* Initialise bit count */ sha_ctx->countLo = sha_ctx->countHi = 0; return SHA1_ERROR_NO;}/********************************************************************** * * SHA1Process() is called multiple times (if needed) until our message * buffer is not empty * **********************************************************************/int SHA1Process(void *context, byte *data, size_t length){ DWORD dwTmp, dataCount, len; byte *bPtr, *msgPtr; SHA1Context *sha_ctx = (SHA1Context *)context; /* Update byte count */ /* Check if the overflow occured in the countLo */ dwTmp = sha_ctx->countLo; if ((sha_ctx->countLo = dwTmp + length) < dwTmp) (sha_ctx->countHi)++; /* If the previous Message was not multiply of 64 bytes, * we store remain of the previous Message in SHA_CTX->data[] array. * Calculate, how many bytes we currently store in SHA_CTX->data[] */ /* calculate in dataCount number of BUSY bytes in sha_ctx->data buffer */ dataCount = dwTmp & 0x3F; msgPtr = data; len = length; if(dataCount) { bPtr = (byte *)sha_ctx->data + dataCount; /* calculate in dataCount number of FREE bytes in sha_ctx->data buffer */ dataCount = 64 - dataCount; /* 64 bytes == 512 bites == SHA block size */ if( length < dataCount ) { memcpy( bPtr, data, length ); return SHA1_ERROR_NO; } /* in dataCount - number of free bytes in sha_ctx->data buffer */ memcpy( bPtr, data, dataCount ); ReverseDWORD( sha_ctx->data, 16 ); SHA_UpdateDigest( sha_ctx->digest, sha_ctx->data ); msgPtr += dataCount; len -= dataCount; } /* Process data in 64-bytes (512 bites) blocks */ while( len >= 64 ) { memcpy( sha_ctx->data, msgPtr, 64 ); ReverseDWORD( sha_ctx->data, 16 ); SHA_UpdateDigest( sha_ctx->digest, sha_ctx->data ); msgPtr += 64; len -= 64; } /* Save remaining bytes of Message. */ if (len > 0) memcpy( sha_ctx->data, msgPtr, len ); return SHA1_ERROR_NO;}/********************************************************************** * * SHA1Final(): All message buffer is transformed using SHA1Process(). * To get the final Message Digest, we have to call SHA1Final() * **********************************************************************/int SHA1Final(void *context, byte *digest) /* 'digest' array must be >= 20 bytes */{ DWORD count; byte *dataPtr; SHA1Context *sha_ctx = (SHA1Context *)context; /* Calculate number of BUSY bytes in sha_ctx->data buffer */ count = sha_ctx->countLo & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ dataPtr = (byte *)sha_ctx->data + count; *dataPtr++ = 0x80; /* Calculate number of FREE bytes in sha_ctx->data buffer */ count = 63 - count; /* sha_ctx->data is 64 bytes, but we already used one byte for 0x80 */ /* If count is more than 8, it means that we have the place for * 2 DWORDS to place the length of message. * If no, we have to pad the current 64-byte block by 0, re-calculate * digest, then fill the first 56 bytes in sha_ctx->data by 0, place * the length of Message to the last 8 bytes and calculate final Digest */ if( count < 8 ) { memset( dataPtr, 0, count ); ReverseDWORD( sha_ctx->data, 16 ); SHA_UpdateDigest( sha_ctx->digest, sha_ctx->data ); /* prepare to calculate final digest, where the length will be written in last 8 bytes */ memset( sha_ctx->data, 0, 56 ); } else if (count > 8) memset(dataPtr, 0, count - 8); sha_ctx->data[14] = (((sha_ctx->countHi) << 3) &0xffffffff) | (((sha_ctx->countLo) >> 29) & 0x7); sha_ctx->data[15] = ((sha_ctx->countLo) << 3) & 0xffffffff; ReverseDWORD( sha_ctx->data, 14 ); // Do not reverse last 8 bytes SHA_UpdateDigest( sha_ctx->digest, sha_ctx->data ); copyDigestToByteArray( sha_ctx->digest, digest ); return SHA1_ERROR_NO;}/********************************************************************** * * SHA1Update() - the size of byte array "data" must be * equal to the block size of SHA1 algorithm, i.e. 512 bits = 64 bytes * **********************************************************************/int SHA1Update(void *context, byte *data){ SHA1Context *sha_ctx; sha_ctx = (SHA1Context *)context; /* 16 * sizeof(DWORD) == 64 bytes */ memcpy( sha_ctx->data, data, sizeof(sha_ctx->data)); ReverseDWORD( sha_ctx->data, 16 ); SHA_UpdateDigest( sha_ctx->digest, sha_ctx->data ); return SHA1_ERROR_NO;}/********************************************************************** * * SHA1Allocate() - allocates memory needed for SHA1Context structure * **********************************************************************/int SHA1Allocate(void **context){ *context = malloc(sizeof(SHA1Context)); if (*context) { return SHA1_ERROR_NO; } return SHA1_ERROR_INTERNAL_ERROR;}/********************************************************************** * * SHA1Free() - Frees resources allocated in SHA1Allocate * **********************************************************************/int SHA1Free(void **context){ free(*context); *context = 0; return 0;}/********************************************************************** * * SHA1MakeDigest() - Helpful function if the whole message is in the * memory and we have to create digest for it. * **********************************************************************/int SHA1MakeDigest( byte *message, int messageLength, byte *digest ){ SHA1Context *context; if ( SHA1Allocate((void **)(&context)) != SHA1_ERROR_NO ) return SHA1_ERROR_INTERNAL_ERROR; if ( SHA1Init(context, 0, 0) != SHA1_ERROR_NO) { SHA1Free((void **)(&context)); return SHA1_ERROR_INTERNAL_ERROR; } if ( SHA1Process(context, message, messageLength) != SHA1_ERROR_NO ) { SHA1Free((void **)(&context)); return SHA1_ERROR_INTERNAL_ERROR; } if ( SHA1Final(context, digest) != SHA1_ERROR_NO ) { SHA1Free((void **)(&context)); return SHA1_ERROR_INTERNAL_ERROR; } SHA1Free((void **)(&context)); return SHA1_ERROR_NO;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -