@@ -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 */
439439static 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