Skip to content

Commit 79f5048

Browse files
authored
Merge pull request #194 from haydenroche5/rsa_misc
Make more RSA improvements.
2 parents 28ef1af + ee12552 commit 79f5048

File tree

1 file changed

+144
-57
lines changed

1 file changed

+144
-57
lines changed

src/we_rsa.c

Lines changed: 144 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,8 @@ static int we_rsa_add_x931_hash_code(const EVP_MD* md, unsigned char** to,
432432
/**
433433
* Set the public key in a we_Rsa structure.
434434
*
435-
* @param ctx [in] Public key context of operation.
436-
* @param rsa [in] RSA structure to hold public key.
435+
* @param rsaKey [in] Key to use.
436+
* @param engineRsa [out] wolfEngine RSA object to hold key.
437437
* @returns 1 on success and 0 on failure.
438438
*/
439439
static int we_rsa_set_public_key(RSA *rsaKey, we_Rsa *engineRsa)
@@ -481,6 +481,61 @@ static int we_rsa_set_public_key(RSA *rsaKey, we_Rsa *engineRsa)
481481
return ret;
482482
}
483483

484+
/**
485+
* Set the public key from an EVP_PKEY_CTX into a we_Rsa structure.
486+
*
487+
* @param ctx [in] Public key context of operation.
488+
* @param rsa [out] wolfEngine RSA object to hold key.
489+
* @returns 1 on success and 0 on failure.
490+
*/
491+
static int we_rsa_set_public_key_from_ctx(EVP_PKEY_CTX* ctx, we_Rsa* engineRsa)
492+
{
493+
int ret = 1;
494+
int rc;
495+
EVP_PKEY *pkey = NULL;
496+
RSA *rsaKey = NULL;
497+
int keySize = 0;
498+
499+
WOLFENGINE_ENTER(WE_LOG_PK, "we_rsa_set_public_key_from_ctx");
500+
WOLFENGINE_MSG_VERBOSE(WE_LOG_PK, "ARGS [ctx = %p]", ctx);
501+
502+
/* OpenSSL RSA key in EVP PKEY associated with context. */
503+
pkey = EVP_PKEY_CTX_get0_pkey(ctx);
504+
if (pkey == NULL) {
505+
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_PK, "EVP_PKEY_CTX_get0_pkey",
506+
pkey);
507+
ret = 0;
508+
}
509+
if (ret == 1) {
510+
/* Get OpenSSL RSA key containing public key. */
511+
rsaKey = (RSA*)EVP_PKEY_get0_RSA(pkey);
512+
if (rsaKey == NULL) {
513+
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_PK, "EVP_PKEY_get0_RSA",
514+
rsaKey);
515+
ret = 0;
516+
}
517+
}
518+
if (ret == 1) {
519+
keySize = RSA_size(rsaKey) * 8;
520+
rc = we_check_rsa_key_size(keySize, 1);
521+
if (rc != 1) {
522+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_check_rsa_key_size", rc);
523+
ret = 0;
524+
}
525+
}
526+
if (ret == 1) {
527+
/* Set the public key into the internal RSA key. */
528+
ret = we_rsa_set_public_key(rsaKey, engineRsa);
529+
if (ret == 0) {
530+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_rsa_set_public_key", ret);
531+
}
532+
}
533+
534+
WOLFENGINE_LEAVE(WE_LOG_PK, "we_rsa_set_public_key_from_ctx", ret);
535+
536+
return ret;
537+
}
538+
484539
/**
485540
* Set the private key in a we_Rsa structure.
486541
*
@@ -2575,7 +2630,7 @@ static int we_rsa_pkey_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
25752630
/* Only determining signature size this call. */
25762631
len = wc_RsaEncryptSize(&rsa->key);
25772632
if (len <= 0) {
2578-
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_SignatureGetSize", (int)len);
2633+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_RsaEncryptSize", (int)len);
25792634
ret = 0;
25802635
}
25812636
else {
@@ -2658,6 +2713,71 @@ static int we_rsa_pkey_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
26582713
return ret;
26592714
}
26602715

2716+
/**
2717+
* Recover (decrypt) the plaintext from a signature, but don't check the
2718+
* validity.
2719+
*
2720+
* @param ctx [in] Public key context of operation.
2721+
* @param out [out] Buffer to place recovered (decrypted) plaintext in.
2722+
* @param outSz [in/out] Size of out on input, actual length on output. If
2723+
* out is NULL, the maximum possible output size will
2724+
* be written to outSz.
2725+
* @param in [in] Ciphertext (signature) input.
2726+
* @param inSz [in] Length of in buffer.
2727+
* @returns 1 on success and 0 on failure.
2728+
*/
2729+
static int we_rsa_pkey_verify_recover(EVP_PKEY_CTX *ctx, unsigned char* out,
2730+
size_t* outSz, const unsigned char* in,
2731+
size_t inSz)
2732+
{
2733+
int ret = 1;
2734+
int rc;
2735+
we_Rsa *rsa = NULL;
2736+
2737+
WOLFENGINE_ENTER(WE_LOG_PK, "we_rsa_pkey_verify_recover");
2738+
WOLFENGINE_MSG_VERBOSE(WE_LOG_PK, "ARGS [ctx = %p, out = %p, outSz = %p, "
2739+
"in = %p, inSz = %zu]", ctx, out, outSz, in, inSz);
2740+
2741+
/* Get the internal RSA object. */
2742+
rsa = (we_Rsa *)EVP_PKEY_CTX_get_data(ctx);
2743+
if (rsa == NULL) {
2744+
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_PK, "EVP_PKEY_CTX_get_data", rsa);
2745+
ret = 0;
2746+
}
2747+
2748+
/* Set up public key */
2749+
if ((ret == 1) && (!rsa->pubKeySet)) {
2750+
ret = we_rsa_set_public_key_from_ctx(ctx, rsa);
2751+
}
2752+
if (ret == 1) {
2753+
if (out == NULL) {
2754+
rc = wc_RsaEncryptSize(&rsa->key);
2755+
if (rc <= 0) {
2756+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_RsaEncryptSize", rc);
2757+
ret = 0;
2758+
}
2759+
else {
2760+
*outSz = rc;
2761+
}
2762+
}
2763+
else {
2764+
/* Unpad and public decrypt. */
2765+
rc = we_rsa_pub_dec_int(inSz, in, *outSz, out, rsa);
2766+
if (rc < 0) {
2767+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_rsa_pub_dec_int", rc);
2768+
ret = 0;
2769+
}
2770+
else {
2771+
*outSz = rc;
2772+
}
2773+
}
2774+
}
2775+
2776+
WOLFENGINE_LEAVE(WE_LOG_PK, "we_rsa_pkey_verify_recover", ret);
2777+
2778+
return ret;
2779+
}
2780+
26612781
/**
26622782
* Verify data with a public RSA key.
26632783
*
@@ -2675,17 +2795,15 @@ static int we_rsa_pkey_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
26752795
int ret = 1;
26762796
int rc = 0;
26772797
we_Rsa *rsa = NULL;
2678-
EVP_PKEY *pkey = NULL;
2679-
RSA *rsaKey = NULL;
26802798
unsigned char *decryptedSig = NULL;
26812799
unsigned char *encodedDigest = NULL;
26822800
int encodedDigestLen = 0;
2683-
int keySize = 0;
26842801
#ifdef WE_HAVE_RSA_X931
26852802
int nid;
26862803
unsigned char hashCode;
26872804
char errBuff[WOLFENGINE_MAX_LOG_WIDTH];
26882805
#endif
2806+
size_t decLen = sigLen;
26892807

26902808
WOLFENGINE_ENTER(WE_LOG_PK, "we_rsa_pkey_verify");
26912809
WOLFENGINE_MSG_VERBOSE(WE_LOG_PK, "ARGS [ctx = %p, sig = %p, sigLen = %zu, "
@@ -2698,42 +2816,6 @@ static int we_rsa_pkey_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
26982816
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_PK, "EVP_PKEY_CTX_get_data", rsa);
26992817
ret = 0;
27002818
}
2701-
2702-
/* Set up public key */
2703-
if ((ret == 1) && (!rsa->pubKeySet)) {
2704-
/* OpenSSL RSA key in EVP PKEY associated with context. */
2705-
pkey = EVP_PKEY_CTX_get0_pkey(ctx);
2706-
if (pkey == NULL) {
2707-
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_PK, "EVP_PKEY_CTX_get0_pkey",
2708-
pkey);
2709-
ret = 0;
2710-
}
2711-
if (ret == 1) {
2712-
/* Get OpenSSL RSA key containing public key. */
2713-
rsaKey = (RSA*)EVP_PKEY_get0_RSA(pkey);
2714-
if (rsaKey == NULL) {
2715-
WOLFENGINE_ERROR_FUNC_NULL(WE_LOG_PK, "EVP_PKEY_get0_RSA",
2716-
rsaKey);
2717-
ret = 0;
2718-
}
2719-
}
2720-
if (ret == 1) {
2721-
keySize = RSA_size(rsaKey) * 8;
2722-
rc = we_check_rsa_key_size(keySize, 1);
2723-
if (rc != 1) {
2724-
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_check_rsa_key_size", rc);
2725-
ret = 0;
2726-
}
2727-
}
2728-
if (ret == 1) {
2729-
/* Set the public key into the internal RSA key. */
2730-
ret = we_rsa_set_public_key(rsaKey, rsa);
2731-
if (ret == 0) {
2732-
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_rsa_set_public_key", ret);
2733-
}
2734-
}
2735-
}
2736-
27372819
if (ret == 1) {
27382820
/* Decrypted signature will same size or smaller than the signature. */
27392821
decryptedSig = (unsigned char *)OPENSSL_malloc(sigLen);
@@ -2744,29 +2826,28 @@ static int we_rsa_pkey_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
27442826
}
27452827
}
27462828
if ((ret == 1) && (rsa->md != NULL) &&
2747-
(rsa->padMode == RSA_PKCS1_PADDING) &&
2748-
((size_t)EVP_MD_size(rsa->md) != tbsLen)) {
2829+
(rsa->padMode == RSA_PKCS1_PADDING) &&
2830+
((size_t)EVP_MD_size(rsa->md) != tbsLen)) {
27492831
WOLFENGINE_ERROR_MSG(WE_LOG_PK, "Digest length invalid");
27502832
ret = -1;
27512833
}
2752-
27532834
if (ret == 1) {
2754-
/* Unpad and public decrypt. */
2755-
rc = we_rsa_pub_dec_int(sigLen, sig, sigLen, decryptedSig, rsa);
2756-
if (rc == -1) {
2757-
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_rsa_pub_dec_int", rc);
2835+
rc = we_rsa_pkey_verify_recover(ctx, decryptedSig, &decLen, sig,
2836+
sigLen);
2837+
if (rc <= 0) {
2838+
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "we_rsa_pkey_verify_recover", rc);
27582839
ret = 0;
27592840
}
27602841
}
2761-
27622842
if ((ret == 1) && (rsa->padMode == RSA_PKCS1_PSS_PADDING)) {
27632843
/* Convert salt length into wolfCrypt value. */
27642844
int wc_saltLen = we_pss_salt_len_to_wc(rsa->saltLen, rsa->md,
27652845
&rsa->key, 0);
27662846
/* Verify call in we_rsa_pub_dec_int only decrypts - this actually
27672847
checks padding. */
2768-
rc = wc_RsaPSS_CheckPadding_ex(tbs, (word32)tbsLen, decryptedSig, rc,
2769-
we_nid_to_wc_hash_type(EVP_MD_type(rsa->md)), wc_saltLen, 0);
2848+
rc = wc_RsaPSS_CheckPadding_ex(tbs, (word32)tbsLen, decryptedSig,
2849+
(word32)decLen, we_nid_to_wc_hash_type(EVP_MD_type(rsa->md)),
2850+
wc_saltLen, 0);
27702851
if (rc != 0) {
27712852
WOLFENGINE_ERROR_FUNC(WE_LOG_PK, "wc_RsaPSS_CheckPadding_ex", rc);
27722853
ret = 0;
@@ -2807,26 +2888,30 @@ static int we_rsa_pkey_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
28072888
ret = 0;
28082889
}
28092890
else {
2810-
if (hashCode != decryptedSig[rc-1]) {
2891+
if (hashCode != decryptedSig[decLen-1]) {
28112892
XSNPRINTF(errBuff, sizeof(errBuff), "Expected hash code"
28122893
": 0x%02X but got 0x%02X.", hashCode,
2813-
decryptedSig[rc-1]);
2894+
decryptedSig[decLen-1]);
28142895
WOLFENGINE_ERROR_MSG(WE_LOG_PK, errBuff);
28152896
ret = 0;
28162897
}
2817-
else if (EVP_MD_size(rsa->md) != (rc - 1)) {
2898+
else if (EVP_MD_size(rsa->md) != (int)(decLen - 1)) {
28182899
WOLFENGINE_ERROR_MSG(WE_LOG_PK, "Actual Digest size "
28192900
"doesn't match digest size implied by hash code.");
28202901
ret = 0;
28212902
}
28222903
else {
2823-
--rc;
2904+
/*
2905+
* Reduce decrypted length by 1 byte to account for hash
2906+
* code.
2907+
*/
2908+
--decLen;
28242909
}
28252910
}
28262911
}
28272912
}
28282913
#endif
2829-
if ((ret == 1) && (tbsLen != (size_t)rc)) {
2914+
if ((ret == 1) && (tbsLen != decLen)) {
28302915
WOLFENGINE_ERROR_MSG(WE_LOG_PK, "Encoding different size");
28312916
ret = 0;
28322917
}
@@ -3065,6 +3150,8 @@ int we_init_rsa_pkey_meth(void)
30653150
EVP_PKEY_meth_set_init(we_rsa_pkey_method, we_rsa_pkey_init);
30663151
EVP_PKEY_meth_set_sign(we_rsa_pkey_method, NULL, we_rsa_pkey_sign);
30673152
EVP_PKEY_meth_set_verify(we_rsa_pkey_method, NULL, we_rsa_pkey_verify);
3153+
EVP_PKEY_meth_set_verify_recover(we_rsa_pkey_method, NULL,
3154+
we_rsa_pkey_verify_recover);
30683155
EVP_PKEY_meth_set_encrypt(we_rsa_pkey_method, NULL,
30693156
we_rsa_pkey_encrypt);
30703157
EVP_PKEY_meth_set_decrypt(we_rsa_pkey_method, NULL,

0 commit comments

Comments
 (0)