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

📄 mech_md2.c

📁 IBM的Linux上的PKCS#11实现
💻 C
📖 第 1 页 / 共 2 页
字号:
CK_RVmd2_hash_update( SESSION         * sess,                 DIGEST_CONTEXT  * ctx,                 CK_BYTE         * in_data,                 CK_ULONG          in_data_len ){   if (!sess || !ctx || !in_data){      st_err_log(4, __FILE__, __LINE__, __FUNCTION__);      return CKR_FUNCTION_FAILED;   }   return ckm_md2_update( (MD2_CONTEXT *)ctx->context,                          in_data, in_data_len );}////CK_RVmd2_hash_final( SESSION         * sess,                CK_BYTE           length_only,                DIGEST_CONTEXT  * ctx,                CK_BYTE         * out_data,                CK_ULONG        * out_data_len ){   CK_RV      rc;   if (!sess || !ctx || !out_data_len){      st_err_log(4, __FILE__, __LINE__, __FUNCTION__);      return CKR_FUNCTION_FAILED;   }   if (length_only == TRUE) {      *out_data_len = MD2_HASH_SIZE;      return CKR_OK;   }   rc = ckm_md2_final( (MD2_CONTEXT *)ctx->context,                       out_data, MD2_HASH_SIZE );   if (rc == CKR_OK) {      *out_data_len = MD2_HASH_SIZE;      return rc;   }   return rc;}// this routine gets called for two mechanisms actually://    CKM_MD2_HMAC//    CKM_MD2_HMAC_GENERAL//CK_RVmd2_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[MD2_HASH_SIZE];   DIGEST_CONTEXT    digest_ctx;   CK_MECHANISM      digest_mech;   CK_BYTE           k_ipad[MD2_BLOCK_SIZE];   CK_BYTE           k_opad[MD2_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_MD2_HMAC_GENERAL) {      hmac_len = *(CK_ULONG *)ctx->mech.pParameter;      if (hmac_len == 0)      {         *out_data_len = 0;         return CKR_OK;      }   }   else      hmac_len = MD2_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 > MD2_BLOCK_SIZE)   {      digest_mech.mechanism      = CKM_MD2;      digest_mech.ulParameterLen = 0;      digest_mech.pParameter     = NULL;      rc = digest_mgr_init( sess, &digest_ctx, &digest_mech );      if (rc != CKR_OK){         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){         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, MD2_BLOCK_SIZE - i);      memset( &k_opad[i], 0x5C, MD2_BLOCK_SIZE - i);   }   else   {      CK_BYTE *key = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE);      for (i = 0; i < key_bytes; i++)      {         k_ipad[i] = key[i] ^ 0x36;         k_opad[i] = key[i] ^ 0x5C;      }      memset( &k_ipad[i], 0x36, MD2_BLOCK_SIZE - key_bytes );      memset( &k_opad[i], 0x5C, MD2_BLOCK_SIZE - key_bytes );   }   digest_mech.mechanism      = CKM_MD2;   digest_mech.ulParameterLen = 0;   digest_mech.pParameter     = NULL;   // inner hash   //   rc = digest_mgr_init( sess, &digest_ctx, &digest_mech );   if (rc != CKR_OK){      st_err_log(123, __FILE__, __LINE__);      return rc;   }   rc = digest_mgr_digest_update( sess, &digest_ctx, k_ipad, MD2_BLOCK_SIZE );   if (rc != CKR_OK){      st_err_log(125, __FILE__, __LINE__);      return rc;   }   rc = digest_mgr_digest_update( sess, &digest_ctx, in_data, in_data_len );   if (rc != CKR_OK){      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){      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){      st_err_log(123, __FILE__, __LINE__);      return rc;   }   rc = digest_mgr_digest_update( sess, &digest_ctx, k_opad, MD2_BLOCK_SIZE );   if (rc != CKR_OK){      st_err_log(123, __FILE__, __LINE__);      return rc;   }   rc = digest_mgr_digest_update( sess, &digest_ctx, hash, hash_len );   if (rc != CKR_OK){      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){      st_err_log(126, __FILE__, __LINE__);      return rc;   }   memcpy( out_data, hash, hmac_len );   *out_data_len = hmac_len;   return CKR_OK;}////CK_RVmd2_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[MD2_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_MD2_HMAC_GENERAL)      hmac_len = *(CK_ULONG *)ctx->mech.pParameter;   else      hmac_len = MD2_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__);      return rc;   }   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__);      return rc;   }   if ((len != hmac_len) || (len != sig_len)){      st_err_log(46, __FILE__, __LINE__);      return CKR_SIGNATURE_LEN_RANGE;   }   if (memcmp(hmac, signature, hmac_len) != 0){      st_err_log(47, __FILE__, __LINE__);      return CKR_SIGNATURE_INVALID;   }   return CKR_OK;}//// CKM routines//// MD2 block update operation. Continues an MD2 message-digest//   operation, processing another message block, and updating the//   context.//CK_RVckm_md2_update( MD2_CONTEXT  * context,                CK_BYTE      * input,                CK_ULONG       inputLen ){   CK_ULONG i, index, partLen;   // Update number of bytes mod 16   //   index = context->count;   context->count = (index + inputLen) & 0xf;   partLen = 16 - index;   // Process any complete 16-byte blocks   //   if (inputLen >= partLen)   {      memcpy( (CK_BYTE *)&context->buffer[index], (CK_BYTE *)input, partLen );      ckm_md2_transform( context->state, context->checksum, context->buffer );      for (i = partLen; i + 15 < inputLen; i += 16)         ckm_md2_transform( context->state, context->checksum, &input[i] );      index = 0;   }   else      i = 0;   // Buffer remaining input   //   memcpy( (CK_BYTE *)&context->buffer[index], (CK_BYTE *)&input[i], inputLen-i );   return CKR_OK;}// MD2 finalization. Ends an MD2 message-digest operation, writing the//   message digest and zeroizing the context.//CK_RVckm_md2_final( MD2_CONTEXT  * context,               CK_BYTE      * out_data,               CK_ULONG       out_data_len ){   CK_ULONG index, padLen;   if (!context || !out_data || (out_data_len < MD2_HASH_SIZE)){      st_err_log(4, __FILE__, __LINE__, __FUNCTION__);      return CKR_FUNCTION_FAILED;   }   // Pad input to 16-byte multiple (1 - 16 pad bytes)   //   index = context->count;   padLen = 16 - index;   ckm_md2_update( context, padding[padLen], padLen );   // Add checksum   //   ckm_md2_update( context, context->checksum, 16 );   // Store state in digest   //   memcpy( (CK_BYTE *)out_data, (CK_BYTE *)context->state, 16 );   return CKR_OK;}// MD2 basic transformation. Transforms state and updates checksum//   based on block.//voidckm_md2_transform( CK_BYTE  * state,                   CK_BYTE  * checksum,                   CK_BYTE  * block ){   CK_ULONG i, j, t;   CK_BYTE  x[48];   // Form encryption block from state, block, state ^ block.   //   memcpy( (CK_BYTE *)x,    (CK_BYTE *)state, 16 );   memcpy( (CK_BYTE *)x+16, (CK_BYTE *)block, 16 );   for (i = 0; i < 16; i++)      x[i+32] = state[i] ^ block[i];   // Encrypt block (18 rounds).   //   t = 0;   for (i = 0; i < 18; i++) {      for (j = 0; j < 48; j++)         t = x[j] ^= S[t];      t = (t + i) & 0xff;   }   // Save new state   //   memcpy( (CK_BYTE *)state, (CK_BYTE *)x, 16 );   // Update checksum.   //   t = checksum[15];   for (i = 0; i < 16; i++)      t = checksum[i] ^= S[block[i] ^ t];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -