📄 lib_sha.c
字号:
/****************************************************************************
* *
* cryptlib SHA Hash Routines *
* Copyright Peter Gutmann 1992-1997 *
* *
****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "cryptctx.h"
#ifdef INC_ALL
#include "sha.h"
#else
#include "hash/sha.h"
#endif /* Compiler-specific includes */
/****************************************************************************
* *
* SHA Self-test Routines *
* *
****************************************************************************/
/* Test the SHA output against the test vectors given in FIPS 180-1. We skip
the third test since this takes several seconds to execute, which leads to
an unacceptable delay */
void shaHashBuffer( void *hashInfo, BYTE *outBuffer, const BYTE *inBuffer,
const int length, const HASH_STATE hashState );
static const struct {
const char *data; /* Data to hash */
const int length; /* Length of data */
const BYTE digest[ SHA_DIGEST_LENGTH ]; /* Digest of data */
} digestValues[] = {
{ "abc", 3,
{ 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,
0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C,
0x9C, 0xD0, 0xD8, 0x9D } },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 } },
/* { "aaaaa...", 1000000L,
{ 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4,
0xF6, 0x1E, 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31,
0x65, 0x34, 0x01, 0x6F } }, */
{ NULL, 0, { 0 } }
};
int shaSelfTest( void )
{
BYTE digest[ SHA_DIGEST_LENGTH ];
int i;
/* Test SHA-1 against values given in FIPS 180-1 */
for( i = 0; digestValues[ i ].data != NULL; i++ )
{
shaHashBuffer( NULL, digest, ( BYTE * ) digestValues[ i ].data,
digestValues[ i ].length, HASH_ALL );
if( memcmp( digest, digestValues[ i ].digest, SHA_DIGEST_LENGTH ) )
return( CRYPT_ERROR );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int shaInit( CRYPT_INFO *cryptInfo )
{
int status;
/* Allocate memory for the SHA context within the encryption context.
Since hash contexts can be reset by deleting the hash values, this may
already have been allocated previously so we only perform the alloc
if it's actually required */
if( cryptInfo->ctxHash.hashInfo == NULL && \
( status = krnlMemalloc( &cryptInfo->ctxHash.hashInfo,
sizeof( SHA_CTX ) ) ) != CRYPT_OK )
return( status );
SHA1_Init( ( SHA_CTX * ) cryptInfo->ctxHash.hashInfo );
return( CRYPT_OK );
}
int shaEnd( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
krnlMemfree( &cryptInfo->ctxHash.hashInfo );
return( CRYPT_OK );
}
/****************************************************************************
* *
* SHA Hash Routines *
* *
****************************************************************************/
/* Hash data using SHA */
int shaHash( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SHA_CTX *shaInfo = ( SHA_CTX * ) cryptInfo->ctxHash.hashInfo;
/* If we've already called shaFinal(), we can't continue */
if( cryptInfo->ctxHash.done )
return( CRYPT_ERROR_COMPLETE );
if( !noBytes )
{
SHA1_Final( cryptInfo->ctxHash.hash, shaInfo );
cryptInfo->ctxHash.done = TRUE;
}
else
SHA1_Update( shaInfo, buffer, noBytes );
return( CRYPT_OK );
}
/* Internal API: Hash a single block of memory without the overhead of
creating an encryption context. This always uses SHA1 */
void shaHashBuffer( void *hashInfo, BYTE *outBuffer, const BYTE *inBuffer,
const int length, const HASH_STATE hashState )
{
SHA_CTX *shaInfo = ( SHA_CTX * ) hashInfo, shaInfoBuffer;
/* If the user has left it up to us to allocate the hash context buffer,
use the internal buffer */
if( shaInfo == NULL )
shaInfo = &shaInfoBuffer;
if( hashState == HASH_ALL )
{
SHA1_Init( shaInfo );
SHA1_Update( shaInfo, ( BYTE * ) inBuffer, length );
SHA1_Final( outBuffer, shaInfo );
}
else
switch( hashState )
{
case HASH_START:
SHA1_Init( shaInfo );
/* Drop through */
case HASH_CONTINUE:
SHA1_Update( shaInfo, ( BYTE * ) inBuffer, length );
break;
case HASH_END:
if( inBuffer != NULL )
SHA1_Update( shaInfo, ( BYTE * ) inBuffer, length );
SHA1_Final( outBuffer, shaInfo );
}
/* Clean up */
zeroise( &shaInfoBuffer, sizeof( SHA_CTX ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -