📄 mech_rsa.c
字号:
// Although X.509 prepads with zeros, we don't strip it after // decryption (PKCS #11 specifies that X.509 decryption is supposed // to produce K bytes of cleartext where K is the modulus length) // if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } rc = ckm_rsa_decrypt( in_data, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { memcpy( out_data, out, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(133, __FILE__, __LINE__); // ckm_rsa_operation is used for all RSA operations so we need to adjust // the return code accordingly // if (rc == CKR_DATA_LEN_RANGE){ st_err_log(112, __FILE__, __LINE__); return CKR_ENCRYPTED_DATA_LEN_RANGE; } return rc;}////CK_RVrsa_x509_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 data[256], sig[256]; // max size: 256 bytes == 2048 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; }#if 0 flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE) return CKR_FUNCTION_FAILED; else modulus_bytes = attr->ulValueLen;#else modulus_bytes = rsa_get_key_len(key_obj);#endif // check input data length restrictions // if (in_data_len > modulus_bytes){ st_err_log(109, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } memset( data, 0x0, modulus_bytes - in_data_len ); memcpy( &data[modulus_bytes - in_data_len], in_data, in_data_len ); // signing is a private key operation --> decrypt // rc = ckm_rsa_decrypt( data, modulus_bytes, sig, key_obj ); if (rc == CKR_OK) { memcpy( out_data, sig, modulus_bytes ); *out_data_len = modulus_bytes; } else st_err_log(133, __FILE__, __LINE__); return rc;}////CK_RVrsa_x509_verify( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG sig_len ){ OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[256]; // 2048 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { CK_ULONG pos1, pos2, len; // it should be noted that in_data_len is not necessarily // the same as the modulus length // for (pos1=0; pos1 < in_data_len; pos1++) if (in_data[pos1] != 0) break; for (pos2=0; pos2 < modulus_bytes; pos2++) if (out[pos2] != 0) break; // at this point, pos1 and pos2 point to the first non-zero bytes // in the input data and the decrypted signature (the recovered data), // respectively. // if ((in_data_len - pos1) != (modulus_bytes - pos2)){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } len = in_data_len - pos1; if (memcmp(&in_data[pos1], &out[pos2], len) != 0){ st_err_log(47, __FILE__, __LINE__); return CKR_SIGNATURE_INVALID; } return CKR_OK; } else st_err_log(132, __FILE__, __LINE__); return rc;}////CK_RVrsa_x509_verify_recover( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * signature, CK_ULONG sig_len, CK_BYTE * out_data, CK_ULONG * out_data_len ){ OBJECT *key_obj = NULL; CK_ATTRIBUTE *attr = NULL; CK_BYTE out[256]; // 2048 bits CK_ULONG modulus_bytes; CK_BBOOL flag; CK_RV rc; if (!sess || !ctx || !out_data_len){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } rc = object_mgr_find_in_map1( ctx->key, &key_obj ); if (rc != CKR_OK){ st_err_log(110, __FILE__, __LINE__); return rc; } flag = template_attribute_find( key_obj->template, CKA_MODULUS, &attr ); if (flag == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else modulus_bytes = attr->ulValueLen; // check input data length restrictions // if (sig_len != modulus_bytes){ st_err_log(46, __FILE__, __LINE__); return CKR_SIGNATURE_LEN_RANGE; } if (length_only == TRUE) { *out_data_len = modulus_bytes; return CKR_OK; } // we perform no stripping of prepended zero bytes here // if (*out_data_len < modulus_bytes) { *out_data_len = modulus_bytes; st_err_log(111, __FILE__, __LINE__); return CKR_BUFFER_TOO_SMALL; } // verify is a public key operation --> encrypt // rc = ckm_rsa_encrypt( signature, modulus_bytes, out, key_obj ); if (rc == CKR_OK) { memcpy( out_data, out, modulus_bytes ); *out_data_len = modulus_bytes; return CKR_OK; } else st_err_log(132, __FILE__, __LINE__); return rc;}////CK_RVrsa_hash_pkcs_sign( SESSION * sess, CK_BBOOL length_only, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE * signature, CK_ULONG * sig_len ){ CK_BYTE * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; // big enough for SHA1, MD5 or MD2 DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT sign_ctx; CK_MECHANISM digest_mech; CK_MECHANISM sign_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &sign_ctx, 0x0, sizeof(sign_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_md2WithRSAEncryption; oid_len = ber_md2WithRSAEncryptionLen; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_md5WithRSAEncryption; oid_len = ber_md5WithRSAEncryptionLen; } else { digest_mech.mechanism = CKM_SHA_1; oid = ber_sha1WithRSAEncryption; oid_len = ber_sha1WithRSAEncryptionLen; } 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__); goto error; } hash_len = sizeof(hash); rc = digest_mgr_digest( sess, length_only, &digest_ctx, in_data, in_data_len, hash, &hash_len ); if (rc != CKR_OK){ st_err_log(124, __FILE__, __LINE__); goto error; } // build the BER-encodings rc = ber_encode_OCTET_STRING( FALSE, &octet_str, &octet_str_len, hash, hash_len ); if (rc != CKR_OK){ st_err_log(77, __FILE__, __LINE__); goto error; } tmp = (CK_BYTE *)buf1; memcpy( tmp, oid, oid_len ); memcpy( tmp + oid_len, octet_str, octet_str_len); rc = ber_encode_SEQUENCE( FALSE, &ber_data, &ber_data_len, tmp, (oid_len + octet_str_len) ); if (rc != CKR_OK){ st_err_log(78, __FILE__, __LINE__); goto error; } // sign the BER-encoded data block sign_mech.mechanism = CKM_RSA_PKCS; sign_mech.ulParameterLen = 0; sign_mech.pParameter = NULL; rc = sign_mgr_init( sess, &sign_ctx, &sign_mech, FALSE, ctx->key ); if (rc != CKR_OK){ st_err_log(127, __FILE__, __LINE__); goto error; } //rc = sign_mgr_sign( sess, length_only, &sign_ctx, hash, hash_len, signature, sig_len ); rc = sign_mgr_sign( sess, length_only, &sign_ctx, ber_data, ber_data_len, signature, sig_len ); if (rc != CKR_OK) st_err_log(128, __FILE__, __LINE__);error: if (octet_str) free( octet_str ); if (ber_data) free( ber_data ); digest_mgr_cleanup( &digest_ctx ); sign_mgr_cleanup( &sign_ctx ); return rc;}////CK_RVrsa_hash_pkcs_sign_update( SESSION * sess, SIGN_VERIFY_CONTEXT * ctx, CK_BYTE * in_data, CK_ULONG in_data_len ){ RSA_DIGEST_CONTEXT * context = NULL; CK_MECHANISM digest_mech; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } context = (RSA_DIGEST_CONTEXT *)ctx->context; if (context->flag == FALSE) { if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) digest_mech.mechanism = CKM_MD2; else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) digest_mech.mechanism = CKM_MD5; else digest_mech.mechanism = CKM_SHA_1; digest_mech.ulParameterLen = 0; digest_mech.pParameter = NULL; rc = digest_mgr_init( sess, &context->hash_context, &digest_mech ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } context->flag = TRUE; } rc = digest_mgr_digest_update( sess, &context->hash_context, in_data, in_data_len ); if (rc != CKR_OK){ st_err_log(123, __FILE__, __LINE__); goto error; } return CKR_OK;error: digest_mgr_cleanup( &context->hash_context ); return rc;}////CK_RVrsa_hash_pkcs_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 * ber_data = NULL; CK_BYTE * octet_str = NULL; CK_BYTE * oid = NULL; CK_BYTE * tmp = NULL; CK_ULONG buf1[16]; // 64 bytes is more than enough CK_BYTE hash[SHA1_HASH_SIZE]; DIGEST_CONTEXT digest_ctx; SIGN_VERIFY_CONTEXT verify_ctx; CK_MECHANISM digest_mech; CK_MECHANISM verify_mech; CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; CK_RV rc; if (!sess || !ctx || !in_data){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } memset( &digest_ctx, 0x0, sizeof(digest_ctx) ); memset( &verify_ctx, 0x0, sizeof(verify_ctx) ); if (ctx->mech.mechanism == CKM_MD2_RSA_PKCS) { digest_mech.mechanism = CKM_MD2; oid = ber_md2WithRSAEncryption; oid_len = ber_md2WithRSAEncryptionLen; } else if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { digest_mech.mechanism = CKM_MD5; oid = ber_md5WithRSAEncryption;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -