📄 mech_sha.c
字号:
#define h4init 0xC3D2E1F0//// Note that it may be necessary to add parentheses to these macros// if they are to be called with expressions as arguments.//// 32-bit rotate left - kludged with shifts//#define ROTL(n,X) ((X << n) | (X >> (32-n)))// The initial expanding function//// The hash function is defined over an 80-word expanded input array W,// where the first 16 are copies of the input data, and the remaining 64// are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This// implementation generates these values on the fly in a circular buffer.//#define expand(W,i) \ (W[i&15] ^= W[(i-14)&15] ^ W[(i-8)&15] ^ W[(i-3)&15], W[i&15] = ROTL(1, W[i&15]))// The prototype SHA sub-round//// The fundamental sub-round is// a' = e + ROTL(5,a) + f(b, c, d) + k + data;// b' = a;// c' = ROTL(30,b);// d' = c;// e' = d;// ... but this is implemented by unrolling the loop 5 times and renaming// the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration.//#define subRound(a, b, c, d, e, f, k, data) \ (e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b))void shaInit( SHA1_CONTEXT *ctx );void shaUpdate( SHA1_CONTEXT *ctx, CK_BYTE const *buffer, CK_ULONG count);void shaFinal( SHA1_CONTEXT *ctx, CK_BYTE *hash );void shaTransform( SHA1_CONTEXT *ctx );////CK_RVsha1_hash( SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ){ CK_RV rv; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } ckm_sha1_init(ctx); if(ctx->context == NULL) return CKR_HOST_MEMORY; if(rv = ckm_sha1_update(ctx, in_data, in_data_len)) return rv; return ckm_sha1_final( ctx, out_data, out_data_len );}////CK_RVsha1_hash_update( SESSION * sess, DIGEST_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ){ if (!sess || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } return ckm_sha1_update( ctx, in_data, in_data_len );}////CK_RVsha1_hash_final( SESSION * sess, CK_BYTE length_only, DIGEST_CONTEXT * ctx, CK_BYTE * out_data, CK_ULONG * out_data_len ){ if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (length_only == TRUE) { *out_data_len = SHA1_HASH_SIZE; return CKR_OK; } return ckm_sha1_final( ctx, out_data, out_data_len );}// this routine gets called for two mechanisms actually:// CKM_SHA_1_HMAC// CKM_SHA_1_HMAC_GENERAL//CK_RVsha1_hmac_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * out_data, CK_ULONG * out_data_len ){ OBJECT * key_obj = NULL; CK_ATTRIBUTE * attr = NULL; CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; CK_MECHANISM digest_mech; CK_BYTE k_ipad[SHA1_BLOCK_SIZE]; CK_BYTE k_opad[SHA1_BLOCK_SIZE]; CK_ULONG key_bytes, hash_len, hmac_len; CK_ULONG i; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) { hmac_len = *(CK_ULONG *)ctx->mech.pParameter; if (hmac_len == 0) { *out_data_len = 0; return CKR_OK; } } else hmac_len = SHA1_HASH_SIZE; if (length_only == TRUE) { *out_data_len = hmac_len; return CKR_OK; } memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } rc = template_attribute_find( key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else key_bytes = attr->ulValueLen; // build (K XOR ipad), (K XOR opad) // if (key_bytes > SHA1_BLOCK_SIZE) { digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, FALSE, &digest_ctx, attr->pValue, attr->ulValueLen, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(124, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); for (i=0; i < hash_len; i++) { k_ipad[i] = hash[i] ^ 0x36; k_opad[i] = hash[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - i); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - i); } else { CK_BYTE *key = attr->pValue; for (i=0; i < key_bytes; i++) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5C; } memset( &k_ipad[i], 0x36, SHA1_BLOCK_SIZE - key_bytes ); memset( &k_opad[i], 0x5C, SHA1_BLOCK_SIZE - key_bytes ); } digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; // inner hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } digest_mgr_cleanup( &digest_ctx ); memset( &digest_ctx, 0x0, sizeof(DIGEST_CONTEXT) ); // outer hash // rc = digest_mgr_init( sess, &digest_ctx, &digest_mech ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, SHA1_BLOCK_SIZE ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(123, __FILE__, __LINE__); return rc; } hash_len = sizeof(hash); rc = digest_mgr_digest_final( sess, FALSE, &digest_ctx, hash, &hash_len ); if (rc != CKR_OK) { digest_mgr_cleanup( &digest_ctx ); st_err_log(126, __FILE__, __LINE__); return rc; } memcpy( out_data, hash, hmac_len ); *out_data_len = hmac_len; digest_mgr_cleanup( &digest_ctx ); return CKR_OK;}////CK_RVsha1_hmac_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ){ CK_BYTE hmac[SHA1_HASH_SIZE]; SIGN_VERIFY_CONTEXT hmac_ctx; CK_ULONG hmac_len, len; CK_RV rc; if (!sess || !ctx || !in_data || !signature){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if (ctx->mech.mechanism == CKM_SHA_1_HMAC_GENERAL) hmac_len = *(CK_ULONG *)ctx->mech.pParameter; else hmac_len = SHA1_HASH_SIZE; memset( &hmac_ctx, 0, sizeof(SIGN_VERIFY_CONTEXT) ); rc = sign_mgr_init( sess, &hmac_ctx, &ctx->mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto done; } len = sizeof(hmac); rc = sign_mgr_sign( sess, FALSE, &hmac_ctx, in_data, in_data_len, hmac, &len ); if (rc != CKR_OK){ st_err_log(128, __FILE__, __LINE__); goto done; } if ((len != hmac_len) || (len != sig_len)) { st_err_log(46, __FILE__, __LINE__); rc = CKR_SIGNATURE_LEN_RANGE; goto done; } if (memcmp(hmac, signature, hmac_len) != 0){ st_err_log(47, __FILE__, __LINE__); rc = CKR_SIGNATURE_INVALID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -