⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mech_sha.c

📁 IBM的Linux上的PKCS#11实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -