📄 mech_sha.c
字号:
}done: sign_mgr_cleanup( &hmac_ctx ); return rc;}//// CKM routines//////CK_RVckm_sha1_update( DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ){ if( token_specific.t_sha_update == NULL ){ if (!ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaUpdate( (SHA1_CONTEXT *)ctx->context, in_data, in_data_len ); return CKR_OK; } return token_specific.t_sha_update(ctx, in_data, in_data_len);}////CK_RVckm_sha1_final( DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ){ if (token_specific.t_sha_final == NULL ){ if (!ctx || !out_data || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (*out_data_len < SHA1_HASH_SIZE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } shaFinal( (SHA1_CONTEXT *)ctx->context, out_data ); *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return token_specific.t_sha_final(ctx, out_data, out_data_len);}//// Software SHA-1 implementation//voidckm_sha1_init( DIGEST_CONTEXT * ctx){ // Set the h-vars to their initial values if (token_specific.t_sha_init == NULL ) { SHA1_CONTEXT *sha1_ctx; /* Allocate the context */ ctx->context_len = sizeof(SHA1_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(SHA1_CONTEXT)); if( ctx->context == NULL ) return; sha1_ctx = (SHA1_CONTEXT *)ctx->context; sha1_ctx->hash_value[0] = h0init; sha1_ctx->hash_value[1] = h1init; sha1_ctx->hash_value[2] = h2init; sha1_ctx->hash_value[3] = h3init; sha1_ctx->hash_value[4] = h4init; // Initialise bit count sha1_ctx->bits_lo = sha1_ctx->bits_hi = 0; } else { // SAB XXX call token specific init... the init MUST allocate it's context token_specific.t_sha_init(ctx); }}// Perform the SHA transformation. Note that this code, like MD5, seems to// break some optimizing compilers due to the complexity of the expressions// and the size of the basic block. It may be necessary to split it into// sections, e.g. based on the four subrounds//// Note that this corrupts the sha->data area//voidshaTransform( SHA1_CONTEXT *ctx ){ register unsigned int A, B, C, D, E; // Set up first buffer // A = ctx->hash_value[0]; B = ctx->hash_value[1]; C = ctx->hash_value[2]; D = ctx->hash_value[3]; E = ctx->hash_value[4]; // Heavy mangling, in 4 sub-rounds of 20 interations each. // subRound( A, B, C, D, E, f1, K1, ctx->buf[ 0] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 1] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 2] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 3] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 4] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[ 5] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[ 6] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[ 7] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[ 8] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[ 9] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[10] ); subRound( E, A, B, C, D, f1, K1, ctx->buf[11] ); subRound( D, E, A, B, C, f1, K1, ctx->buf[12] ); subRound( C, D, E, A, B, f1, K1, ctx->buf[13] ); subRound( B, C, D, E, A, f1, K1, ctx->buf[14] ); subRound( A, B, C, D, E, f1, K1, ctx->buf[15] ); subRound( E, A, B, C, D, f1, K1, expand(ctx->buf, 16) ); subRound( D, E, A, B, C, f1, K1, expand(ctx->buf, 17) ); subRound( C, D, E, A, B, f1, K1, expand(ctx->buf, 18) ); subRound( B, C, D, E, A, f1, K1, expand(ctx->buf, 19) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 20) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 21) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 22) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 23) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 24) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 25) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 26) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 27) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 28) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 29) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 30) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 31) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 32) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 33) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 34) ); subRound( A, B, C, D, E, f2, K2, expand(ctx->buf, 35) ); subRound( E, A, B, C, D, f2, K2, expand(ctx->buf, 36) ); subRound( D, E, A, B, C, f2, K2, expand(ctx->buf, 37) ); subRound( C, D, E, A, B, f2, K2, expand(ctx->buf, 38) ); subRound( B, C, D, E, A, f2, K2, expand(ctx->buf, 39) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 40) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 41) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 42) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 43) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 44) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 45) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 46) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 47) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 48) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 49) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 50) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 51) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 52) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 53) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 54) ); subRound( A, B, C, D, E, f3, K3, expand(ctx->buf, 55) ); subRound( E, A, B, C, D, f3, K3, expand(ctx->buf, 56) ); subRound( D, E, A, B, C, f3, K3, expand(ctx->buf, 57) ); subRound( C, D, E, A, B, f3, K3, expand(ctx->buf, 58) ); subRound( B, C, D, E, A, f3, K3, expand(ctx->buf, 59) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 60) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 61) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 62) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 63) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 64) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 65) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 66) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 67) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 68) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 69) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 70) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 71) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 72) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 73) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 74) ); subRound( A, B, C, D, E, f4, K4, expand(ctx->buf, 75) ); subRound( E, A, B, C, D, f4, K4, expand(ctx->buf, 76) ); subRound( D, E, A, B, C, f4, K4, expand(ctx->buf, 77) ); subRound( C, D, E, A, B, f4, K4, expand(ctx->buf, 78) ); subRound( B, C, D, E, A, f4, K4, expand(ctx->buf, 79) ); // Build message digest // ctx->hash_value[0] += A; ctx->hash_value[1] += B; ctx->hash_value[2] += C; ctx->hash_value[3] += D; ctx->hash_value[4] += E;}// SHA is defined in big-endian form, so this converts the buffer from// bytes to words, independent of the machine's native endianness.//// Assuming a consistent byte ordering for the machine, this also// has the magic property of being self-inverse. It is used as// such.//static voidbyteReverse( unsigned int *buffer, unsigned int byteCount ){#ifndef __BYTE_ORDER#error "Endianess MUST be defined"#endif#if __BYTE_ORDER == __LITTLE_ENDIAN CK_ULONG value, val; byteCount /= sizeof(CK_ULONG_32); while (byteCount--) { val = *buffer; value = ((0x000000FF & val) << 24) | ((0x0000FF00 & val) << 8 ) | ((0x00FF0000 & val) >> 8 ) | ((0xFF000000 & val) >> 24); *buffer++ = value; }#endif// JRM - this code gives funky results on Linux/Intel.// I assume this is a GCC issue since regression tests passed on NT//// byteCount /= sizeof(CK_ULONG);// while ( byteCount-- ) {// value = (CK_ULONG)((unsigned)((CK_BYTE *)buffer)[0] << 8 | ((CK_BYTE *)buffer)[1]) << 16 |// ((unsigned)((CK_BYTE *)buffer)[2] << 8 | ((CK_BYTE *)buffer)[3]);// *buffer++ = value;// }}voidshaUpdate( SHA1_CONTEXT * ctx, CK_BYTE const * buffer, CK_ULONG count){ CK_ULONG t; // Update bitcount // t = ctx->bits_lo; if ((ctx->bits_lo = t + count) < t) ctx->bits_hi++; // Carry from low to high t &= 0x3f; // Bytes already in ctx->buf // Handle any leading odd-sized chunks // if (t) { CK_BYTE *p = (CK_BYTE *)ctx->buf + t; t = 64-t; if (count < t) { memcpy(p, buffer, count); return; } memcpy(p, buffer, t); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += t; count -= t; } // Process data in SHA1_BLOCK_SIZE chunks // while (count >= SHA1_BLOCK_SIZE) { memcpy(ctx->buf, buffer, SHA1_BLOCK_SIZE); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); buffer += SHA1_BLOCK_SIZE; count -= SHA1_BLOCK_SIZE; } // Handle any remaining bytes of data. // memcpy(ctx->buf, buffer, count);}// Final wrapup - pad to 64-byte boundary with the bit pattern// 1 0* (64-bit count of bits processed, MSB-first)//voidshaFinal( SHA1_CONTEXT * ctx, CK_BYTE * hash ){ int count; CK_BYTE *p; // Compute number of bytes mod 64 // count = (int)ctx->bits_lo & 0x3F; // Set the first char of padding to 0x80. // This is safe since there is always at least one byte free // p = (CK_BYTE *)ctx->buf + count; *p++ = 0x80; // Bytes of padding needed to make 64 bytes // count = SHA1_BLOCK_SIZE - 1 - count; // Pad out to 56 mod 64 // if (count < 8) { // Two lots of padding: Pad the first block to 64 bytes // memset(p, 0, count); byteReverse(ctx->buf, SHA1_BLOCK_SIZE); shaTransform(ctx); // Now fill the next block with 56 bytes // memset(ctx->buf, 0, SHA1_BLOCK_SIZE-8); } else { // Pad block to 56 bytes // memset(p, 0, count-8); } byteReverse(ctx->buf, SHA1_BLOCK_SIZE-8); // Append length in *bits* and transform // ctx->buf[14] = ctx->bits_hi << 3 | ctx->bits_lo >> 29; ctx->buf[15] = ctx->bits_lo << 3; shaTransform(ctx); // Store output hash in buffer // byteReverse(ctx->hash_value, SHA1_HASH_SIZE); memcpy(hash, ctx->hash_value, SHA1_HASH_SIZE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -