xref: /freebsd/crypto/openssl/providers/implementations/signature/rsa_sig.c (revision 88b8b7f0c4e9948667a2279e78e975a784049cba)
1b077aed3SPierre Pronchery /*
2*88b8b7f0SEnji Cooper  * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
3b077aed3SPierre Pronchery  *
4b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5b077aed3SPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
6b077aed3SPierre Pronchery  * in the file LICENSE in the source distribution or at
7b077aed3SPierre Pronchery  * https://www.openssl.org/source/license.html
8b077aed3SPierre Pronchery  */
9b077aed3SPierre Pronchery 
10b077aed3SPierre Pronchery /*
11b077aed3SPierre Pronchery  * RSA low level APIs are deprecated for public use, but still ok for
12b077aed3SPierre Pronchery  * internal use.
13b077aed3SPierre Pronchery  */
14b077aed3SPierre Pronchery #include "internal/deprecated.h"
15b077aed3SPierre Pronchery 
16b077aed3SPierre Pronchery #include <string.h>
17b077aed3SPierre Pronchery #include <openssl/crypto.h>
18b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
19b077aed3SPierre Pronchery #include <openssl/core_names.h>
20b077aed3SPierre Pronchery #include <openssl/err.h>
21e7be843bSPierre Pronchery #include <openssl/obj_mac.h>
22b077aed3SPierre Pronchery #include <openssl/rsa.h>
23b077aed3SPierre Pronchery #include <openssl/params.h>
24b077aed3SPierre Pronchery #include <openssl/evp.h>
25b077aed3SPierre Pronchery #include <openssl/proverr.h>
26b077aed3SPierre Pronchery #include "internal/cryptlib.h"
27b077aed3SPierre Pronchery #include "internal/nelem.h"
28b077aed3SPierre Pronchery #include "internal/sizes.h"
29b077aed3SPierre Pronchery #include "crypto/rsa.h"
30b077aed3SPierre Pronchery #include "prov/providercommon.h"
31b077aed3SPierre Pronchery #include "prov/implementations.h"
32b077aed3SPierre Pronchery #include "prov/provider_ctx.h"
33b077aed3SPierre Pronchery #include "prov/der_rsa.h"
34b077aed3SPierre Pronchery #include "prov/securitycheck.h"
35b077aed3SPierre Pronchery 
36b077aed3SPierre Pronchery #define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1
37b077aed3SPierre Pronchery 
38b077aed3SPierre Pronchery static OSSL_FUNC_signature_newctx_fn rsa_newctx;
39b077aed3SPierre Pronchery static OSSL_FUNC_signature_sign_init_fn rsa_sign_init;
40b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_init_fn rsa_verify_init;
41b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_recover_init_fn rsa_verify_recover_init;
42b077aed3SPierre Pronchery static OSSL_FUNC_signature_sign_fn rsa_sign;
43e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_update_fn rsa_signverify_message_update;
44e7be843bSPierre Pronchery static OSSL_FUNC_signature_sign_message_final_fn rsa_sign_message_final;
45b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_fn rsa_verify;
46b077aed3SPierre Pronchery static OSSL_FUNC_signature_verify_recover_fn rsa_verify_recover;
47e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_update_fn rsa_signverify_message_update;
48e7be843bSPierre Pronchery static OSSL_FUNC_signature_verify_message_final_fn rsa_verify_message_final;
49b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_init_fn rsa_digest_sign_init;
50e7be843bSPierre Pronchery static OSSL_FUNC_signature_digest_sign_update_fn rsa_digest_sign_update;
51b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_final_fn rsa_digest_sign_final;
52b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_init_fn rsa_digest_verify_init;
53e7be843bSPierre Pronchery static OSSL_FUNC_signature_digest_verify_update_fn rsa_digest_verify_update;
54b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_final_fn rsa_digest_verify_final;
55b077aed3SPierre Pronchery static OSSL_FUNC_signature_freectx_fn rsa_freectx;
56b077aed3SPierre Pronchery static OSSL_FUNC_signature_dupctx_fn rsa_dupctx;
57e7be843bSPierre Pronchery static OSSL_FUNC_signature_query_key_types_fn rsa_sigalg_query_key_types;
58b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_params_fn rsa_get_ctx_params;
59b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_params_fn rsa_gettable_ctx_params;
60b077aed3SPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn rsa_set_ctx_params;
61b077aed3SPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn rsa_settable_ctx_params;
62b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_md_params_fn rsa_get_ctx_md_params;
63b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_md_params_fn rsa_gettable_ctx_md_params;
64b077aed3SPierre Pronchery static OSSL_FUNC_signature_set_ctx_md_params_fn rsa_set_ctx_md_params;
65b077aed3SPierre Pronchery static OSSL_FUNC_signature_settable_ctx_md_params_fn rsa_settable_ctx_md_params;
66e7be843bSPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn rsa_sigalg_set_ctx_params;
67e7be843bSPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn rsa_sigalg_settable_ctx_params;
68b077aed3SPierre Pronchery 
69b077aed3SPierre Pronchery static OSSL_ITEM padding_item[] = {
70b077aed3SPierre Pronchery     { RSA_PKCS1_PADDING,        OSSL_PKEY_RSA_PAD_MODE_PKCSV15 },
71b077aed3SPierre Pronchery     { RSA_NO_PADDING,           OSSL_PKEY_RSA_PAD_MODE_NONE },
72b077aed3SPierre Pronchery     { RSA_X931_PADDING,         OSSL_PKEY_RSA_PAD_MODE_X931 },
73b077aed3SPierre Pronchery     { RSA_PKCS1_PSS_PADDING,    OSSL_PKEY_RSA_PAD_MODE_PSS },
74b077aed3SPierre Pronchery     { 0,                        NULL     }
75b077aed3SPierre Pronchery };
76b077aed3SPierre Pronchery 
77b077aed3SPierre Pronchery /*
78b077aed3SPierre Pronchery  * What's passed as an actual key is defined by the KEYMGMT interface.
79b077aed3SPierre Pronchery  * We happen to know that our KEYMGMT simply passes RSA structures, so
80b077aed3SPierre Pronchery  * we use that here too.
81b077aed3SPierre Pronchery  */
82b077aed3SPierre Pronchery 
83b077aed3SPierre Pronchery typedef struct {
84b077aed3SPierre Pronchery     OSSL_LIB_CTX *libctx;
85b077aed3SPierre Pronchery     char *propq;
86b077aed3SPierre Pronchery     RSA *rsa;
87b077aed3SPierre Pronchery     int operation;
88b077aed3SPierre Pronchery 
89b077aed3SPierre Pronchery     /*
90e7be843bSPierre Pronchery      * Flag to determine if a full sigalg is run (1) or if a composable
91e7be843bSPierre Pronchery      * signature algorithm is run (0).
92e7be843bSPierre Pronchery      *
93e7be843bSPierre Pronchery      * When a full sigalg is run (1), this currently affects the following
94e7be843bSPierre Pronchery      * other flags, which are to remain untouched after their initialization:
95e7be843bSPierre Pronchery      *
96e7be843bSPierre Pronchery      * - flag_allow_md (initialized to 0)
97e7be843bSPierre Pronchery      */
98e7be843bSPierre Pronchery     unsigned int flag_sigalg : 1;
99e7be843bSPierre Pronchery     /*
100b077aed3SPierre Pronchery      * Flag to determine if the hash function can be changed (1) or not (0)
101b077aed3SPierre Pronchery      * Because it's dangerous to change during a DigestSign or DigestVerify
102b077aed3SPierre Pronchery      * operation, this flag is cleared by their Init function, and set again
103b077aed3SPierre Pronchery      * by their Final function.
104e7be843bSPierre Pronchery      * Implementations of full sigalgs (such as RSA-SHA256) hard-code this
105e7be843bSPierre Pronchery      * flag to not allow changes (0).
106b077aed3SPierre Pronchery      */
107b077aed3SPierre Pronchery     unsigned int flag_allow_md : 1;
108b077aed3SPierre Pronchery     unsigned int mgf1_md_set : 1;
109e7be843bSPierre Pronchery     /*
110e7be843bSPierre Pronchery      * Flags to say what are the possible next external calls in what
111e7be843bSPierre Pronchery      * consitutes the life cycle of an algorithm.  The relevant calls are:
112e7be843bSPierre Pronchery      * - init
113e7be843bSPierre Pronchery      * - update
114e7be843bSPierre Pronchery      * - final
115e7be843bSPierre Pronchery      * - oneshot
116e7be843bSPierre Pronchery      * All other external calls are regarded as utilitarian and are allowed
117e7be843bSPierre Pronchery      * at any time (they may be affected by other flags, like flag_allow_md,
118e7be843bSPierre Pronchery      * though).
119e7be843bSPierre Pronchery      */
120e7be843bSPierre Pronchery     unsigned int flag_allow_update : 1;
121e7be843bSPierre Pronchery     unsigned int flag_allow_final : 1;
122e7be843bSPierre Pronchery     unsigned int flag_allow_oneshot : 1;
123b077aed3SPierre Pronchery 
124b077aed3SPierre Pronchery     /* main digest */
125b077aed3SPierre Pronchery     EVP_MD *md;
126b077aed3SPierre Pronchery     EVP_MD_CTX *mdctx;
127b077aed3SPierre Pronchery     int mdnid;
128b077aed3SPierre Pronchery     char mdname[OSSL_MAX_NAME_SIZE]; /* Purely informational */
129b077aed3SPierre Pronchery 
130b077aed3SPierre Pronchery     /* RSA padding mode */
131b077aed3SPierre Pronchery     int pad_mode;
132b077aed3SPierre Pronchery     /* message digest for MGF1 */
133b077aed3SPierre Pronchery     EVP_MD *mgf1_md;
134b077aed3SPierre Pronchery     int mgf1_mdnid;
135b077aed3SPierre Pronchery     char mgf1_mdname[OSSL_MAX_NAME_SIZE]; /* Purely informational */
136b077aed3SPierre Pronchery     /* PSS salt length */
137b077aed3SPierre Pronchery     int saltlen;
138b077aed3SPierre Pronchery     /* Minimum salt length or -1 if no PSS parameter restriction */
139b077aed3SPierre Pronchery     int min_saltlen;
140b077aed3SPierre Pronchery 
141e7be843bSPierre Pronchery     /* Signature, for verification */
142e7be843bSPierre Pronchery     unsigned char *sig;
143e7be843bSPierre Pronchery     size_t siglen;
144e7be843bSPierre Pronchery 
145e7be843bSPierre Pronchery #ifdef FIPS_MODULE
146e7be843bSPierre Pronchery     /*
147e7be843bSPierre Pronchery      * FIPS 140-3 IG 2.4.B mandates that verification based on a digest of a
148e7be843bSPierre Pronchery      * message is not permitted.  However, signing based on a digest is still
149e7be843bSPierre Pronchery      * permitted.
150e7be843bSPierre Pronchery      */
151e7be843bSPierre Pronchery     int verify_message;
152e7be843bSPierre Pronchery #endif
153e7be843bSPierre Pronchery 
154b077aed3SPierre Pronchery     /* Temp buffer */
155b077aed3SPierre Pronchery     unsigned char *tbuf;
156b077aed3SPierre Pronchery 
157e7be843bSPierre Pronchery     OSSL_FIPS_IND_DECLARE
158b077aed3SPierre Pronchery } PROV_RSA_CTX;
159b077aed3SPierre Pronchery 
160b077aed3SPierre Pronchery /* True if PSS parameters are restricted */
161b077aed3SPierre Pronchery #define rsa_pss_restricted(prsactx) (prsactx->min_saltlen != -1)
162b077aed3SPierre Pronchery 
rsa_get_md_size(const PROV_RSA_CTX * prsactx)163b077aed3SPierre Pronchery static size_t rsa_get_md_size(const PROV_RSA_CTX *prsactx)
164b077aed3SPierre Pronchery {
165e7be843bSPierre Pronchery     int md_size;
166e7be843bSPierre Pronchery 
167e7be843bSPierre Pronchery     if (prsactx->md != NULL) {
168e7be843bSPierre Pronchery         md_size = EVP_MD_get_size(prsactx->md);
169e7be843bSPierre Pronchery         if (md_size <= 0)
170e7be843bSPierre Pronchery             return 0;
171e7be843bSPierre Pronchery         return md_size;
172e7be843bSPierre Pronchery     }
173b077aed3SPierre Pronchery     return 0;
174b077aed3SPierre Pronchery }
175b077aed3SPierre Pronchery 
rsa_check_padding(const PROV_RSA_CTX * prsactx,const char * mdname,const char * mgf1_mdname,int mdnid)176b077aed3SPierre Pronchery static int rsa_check_padding(const PROV_RSA_CTX *prsactx,
177b077aed3SPierre Pronchery                              const char *mdname, const char *mgf1_mdname,
178b077aed3SPierre Pronchery                              int mdnid)
179b077aed3SPierre Pronchery {
180b077aed3SPierre Pronchery     switch (prsactx->pad_mode) {
181b077aed3SPierre Pronchery     case RSA_NO_PADDING:
182b077aed3SPierre Pronchery         if (mdname != NULL || mdnid != NID_undef) {
183b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE);
184b077aed3SPierre Pronchery             return 0;
185b077aed3SPierre Pronchery         }
186b077aed3SPierre Pronchery         break;
187b077aed3SPierre Pronchery     case RSA_X931_PADDING:
188b077aed3SPierre Pronchery         if (RSA_X931_hash_id(mdnid) == -1) {
189b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST);
190b077aed3SPierre Pronchery             return 0;
191b077aed3SPierre Pronchery         }
192b077aed3SPierre Pronchery         break;
193b077aed3SPierre Pronchery     case RSA_PKCS1_PSS_PADDING:
194b077aed3SPierre Pronchery         if (rsa_pss_restricted(prsactx))
195b077aed3SPierre Pronchery             if ((mdname != NULL && !EVP_MD_is_a(prsactx->md, mdname))
196b077aed3SPierre Pronchery                 || (mgf1_mdname != NULL
197b077aed3SPierre Pronchery                     && !EVP_MD_is_a(prsactx->mgf1_md, mgf1_mdname))) {
198b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED);
199b077aed3SPierre Pronchery                 return 0;
200b077aed3SPierre Pronchery             }
201b077aed3SPierre Pronchery         break;
202b077aed3SPierre Pronchery     default:
203b077aed3SPierre Pronchery         break;
204b077aed3SPierre Pronchery     }
205b077aed3SPierre Pronchery 
206b077aed3SPierre Pronchery     return 1;
207b077aed3SPierre Pronchery }
208b077aed3SPierre Pronchery 
rsa_check_parameters(PROV_RSA_CTX * prsactx,int min_saltlen)209b077aed3SPierre Pronchery static int rsa_check_parameters(PROV_RSA_CTX *prsactx, int min_saltlen)
210b077aed3SPierre Pronchery {
211b077aed3SPierre Pronchery     if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) {
212b077aed3SPierre Pronchery         int max_saltlen;
213b077aed3SPierre Pronchery 
214b077aed3SPierre Pronchery         /* See if minimum salt length exceeds maximum possible */
215b077aed3SPierre Pronchery         max_saltlen = RSA_size(prsactx->rsa) - EVP_MD_get_size(prsactx->md);
216b077aed3SPierre Pronchery         if ((RSA_bits(prsactx->rsa) & 0x7) == 1)
217b077aed3SPierre Pronchery             max_saltlen--;
218b077aed3SPierre Pronchery         if (min_saltlen < 0 || min_saltlen > max_saltlen) {
219b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
220b077aed3SPierre Pronchery             return 0;
221b077aed3SPierre Pronchery         }
222b077aed3SPierre Pronchery         prsactx->min_saltlen = min_saltlen;
223b077aed3SPierre Pronchery     }
224b077aed3SPierre Pronchery     return 1;
225b077aed3SPierre Pronchery }
226b077aed3SPierre Pronchery 
rsa_newctx(void * provctx,const char * propq)227b077aed3SPierre Pronchery static void *rsa_newctx(void *provctx, const char *propq)
228b077aed3SPierre Pronchery {
229b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = NULL;
230b077aed3SPierre Pronchery     char *propq_copy = NULL;
231b077aed3SPierre Pronchery 
232b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
233b077aed3SPierre Pronchery         return NULL;
234b077aed3SPierre Pronchery 
235b077aed3SPierre Pronchery     if ((prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX))) == NULL
236b077aed3SPierre Pronchery         || (propq != NULL
237b077aed3SPierre Pronchery             && (propq_copy = OPENSSL_strdup(propq)) == NULL)) {
238b077aed3SPierre Pronchery         OPENSSL_free(prsactx);
239b077aed3SPierre Pronchery         return NULL;
240b077aed3SPierre Pronchery     }
241b077aed3SPierre Pronchery 
242e7be843bSPierre Pronchery     OSSL_FIPS_IND_INIT(prsactx)
243b077aed3SPierre Pronchery     prsactx->libctx = PROV_LIBCTX_OF(provctx);
244b077aed3SPierre Pronchery     prsactx->flag_allow_md = 1;
245e7be843bSPierre Pronchery #ifdef FIPS_MODULE
246e7be843bSPierre Pronchery     prsactx->verify_message = 1;
247e7be843bSPierre Pronchery #endif
248b077aed3SPierre Pronchery     prsactx->propq = propq_copy;
249e7be843bSPierre Pronchery     /* Maximum up to digest length for sign, auto for verify */
250e7be843bSPierre Pronchery     prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
251b077aed3SPierre Pronchery     prsactx->min_saltlen = -1;
252b077aed3SPierre Pronchery     return prsactx;
253b077aed3SPierre Pronchery }
254b077aed3SPierre Pronchery 
rsa_pss_compute_saltlen(PROV_RSA_CTX * ctx)255b077aed3SPierre Pronchery static int rsa_pss_compute_saltlen(PROV_RSA_CTX *ctx)
256b077aed3SPierre Pronchery {
257b077aed3SPierre Pronchery     int saltlen = ctx->saltlen;
258e7be843bSPierre Pronchery     int saltlenMax = -1;
259b077aed3SPierre Pronchery 
260e7be843bSPierre Pronchery     /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
261e7be843bSPierre Pronchery      * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
262e7be843bSPierre Pronchery      * salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
263e7be843bSPierre Pronchery      * the hash function output block (in bytes)."
264e7be843bSPierre Pronchery      *
265e7be843bSPierre Pronchery      * Provide a way to use at most the digest length, so that the default does
266e7be843bSPierre Pronchery      * not violate FIPS 186-4. */
267b077aed3SPierre Pronchery     if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
268e7be843bSPierre Pronchery         if ((saltlen = EVP_MD_get_size(ctx->md)) <= 0) {
269e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
270e7be843bSPierre Pronchery             return -1;
271e7be843bSPierre Pronchery         }
272e7be843bSPierre Pronchery     } else if (saltlen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
273e7be843bSPierre Pronchery         saltlen = RSA_PSS_SALTLEN_MAX;
274e7be843bSPierre Pronchery         if ((saltlenMax = EVP_MD_get_size(ctx->md)) <= 0) {
275e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
276e7be843bSPierre Pronchery             return -1;
277e7be843bSPierre Pronchery         }
278e7be843bSPierre Pronchery     }
279e7be843bSPierre Pronchery     if (saltlen == RSA_PSS_SALTLEN_MAX || saltlen == RSA_PSS_SALTLEN_AUTO) {
280e7be843bSPierre Pronchery         int mdsize, rsasize;
281e7be843bSPierre Pronchery 
282e7be843bSPierre Pronchery         if ((mdsize = EVP_MD_get_size(ctx->md)) <= 0) {
283e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
284e7be843bSPierre Pronchery             return -1;
285e7be843bSPierre Pronchery         }
286e7be843bSPierre Pronchery         if ((rsasize = RSA_size(ctx->rsa)) <= 2 || rsasize - 2 < mdsize) {
287e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
288e7be843bSPierre Pronchery             return -1;
289e7be843bSPierre Pronchery         }
290e7be843bSPierre Pronchery         saltlen = rsasize - mdsize - 2;
291b077aed3SPierre Pronchery         if ((RSA_bits(ctx->rsa) & 0x7) == 1)
292b077aed3SPierre Pronchery             saltlen--;
293e7be843bSPierre Pronchery         if (saltlenMax >= 0 && saltlen > saltlenMax)
294e7be843bSPierre Pronchery             saltlen = saltlenMax;
295b077aed3SPierre Pronchery     }
296b077aed3SPierre Pronchery     if (saltlen < 0) {
297b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
298b077aed3SPierre Pronchery         return -1;
299b077aed3SPierre Pronchery     } else if (saltlen < ctx->min_saltlen) {
300b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL,
301b077aed3SPierre Pronchery                        "minimum salt length: %d, actual salt length: %d",
302b077aed3SPierre Pronchery                        ctx->min_saltlen, saltlen);
303b077aed3SPierre Pronchery         return -1;
304b077aed3SPierre Pronchery     }
305b077aed3SPierre Pronchery     return saltlen;
306b077aed3SPierre Pronchery }
307b077aed3SPierre Pronchery 
rsa_generate_signature_aid(PROV_RSA_CTX * ctx,unsigned char * aid_buf,size_t buf_len,size_t * aid_len)308b077aed3SPierre Pronchery static unsigned char *rsa_generate_signature_aid(PROV_RSA_CTX *ctx,
309b077aed3SPierre Pronchery                                                  unsigned char *aid_buf,
310b077aed3SPierre Pronchery                                                  size_t buf_len,
311b077aed3SPierre Pronchery                                                  size_t *aid_len)
312b077aed3SPierre Pronchery {
313b077aed3SPierre Pronchery     WPACKET pkt;
314b077aed3SPierre Pronchery     unsigned char *aid = NULL;
315b077aed3SPierre Pronchery     int saltlen;
316b077aed3SPierre Pronchery     RSA_PSS_PARAMS_30 pss_params;
317b077aed3SPierre Pronchery     int ret;
318b077aed3SPierre Pronchery 
319b077aed3SPierre Pronchery     if (!WPACKET_init_der(&pkt, aid_buf, buf_len)) {
320e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_PROV, ERR_R_CRYPTO_LIB);
321b077aed3SPierre Pronchery         return NULL;
322b077aed3SPierre Pronchery     }
323b077aed3SPierre Pronchery 
324b077aed3SPierre Pronchery     switch (ctx->pad_mode) {
325b077aed3SPierre Pronchery     case RSA_PKCS1_PADDING:
326b077aed3SPierre Pronchery         ret = ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1,
327b077aed3SPierre Pronchery                                                                  ctx->mdnid);
328b077aed3SPierre Pronchery 
329b077aed3SPierre Pronchery         if (ret > 0) {
330b077aed3SPierre Pronchery             break;
331b077aed3SPierre Pronchery         } else if (ret == 0) {
332b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
333b077aed3SPierre Pronchery             goto cleanup;
334b077aed3SPierre Pronchery         }
335b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_PROV, ERR_R_UNSUPPORTED,
336b077aed3SPierre Pronchery                        "Algorithm ID generation - md NID: %d",
337b077aed3SPierre Pronchery                        ctx->mdnid);
338b077aed3SPierre Pronchery         goto cleanup;
339b077aed3SPierre Pronchery     case RSA_PKCS1_PSS_PADDING:
340b077aed3SPierre Pronchery         saltlen = rsa_pss_compute_saltlen(ctx);
341b077aed3SPierre Pronchery         if (saltlen < 0)
342b077aed3SPierre Pronchery             goto cleanup;
343b077aed3SPierre Pronchery         if (!ossl_rsa_pss_params_30_set_defaults(&pss_params)
344b077aed3SPierre Pronchery             || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, ctx->mdnid)
345b077aed3SPierre Pronchery             || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params,
346b077aed3SPierre Pronchery                                                           ctx->mgf1_mdnid)
347b077aed3SPierre Pronchery             || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen)
348b077aed3SPierre Pronchery             || !ossl_DER_w_algorithmIdentifier_RSA_PSS(&pkt, -1,
349b077aed3SPierre Pronchery                                                        RSA_FLAG_TYPE_RSASSAPSS,
350b077aed3SPierre Pronchery                                                        &pss_params)) {
351b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
352b077aed3SPierre Pronchery             goto cleanup;
353b077aed3SPierre Pronchery         }
354b077aed3SPierre Pronchery         break;
355b077aed3SPierre Pronchery     default:
356b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_PROV, ERR_R_UNSUPPORTED,
357b077aed3SPierre Pronchery                        "Algorithm ID generation - pad mode: %d",
358b077aed3SPierre Pronchery                        ctx->pad_mode);
359b077aed3SPierre Pronchery         goto cleanup;
360b077aed3SPierre Pronchery     }
361b077aed3SPierre Pronchery     if (WPACKET_finish(&pkt)) {
362b077aed3SPierre Pronchery         WPACKET_get_total_written(&pkt, aid_len);
363b077aed3SPierre Pronchery         aid = WPACKET_get_curr(&pkt);
364b077aed3SPierre Pronchery     }
365b077aed3SPierre Pronchery  cleanup:
366b077aed3SPierre Pronchery     WPACKET_cleanup(&pkt);
367b077aed3SPierre Pronchery     return aid;
368b077aed3SPierre Pronchery }
369b077aed3SPierre Pronchery 
rsa_setup_md(PROV_RSA_CTX * ctx,const char * mdname,const char * mdprops,const char * desc)370b077aed3SPierre Pronchery static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname,
371e7be843bSPierre Pronchery                         const char *mdprops, const char *desc)
372b077aed3SPierre Pronchery {
373e7be843bSPierre Pronchery     EVP_MD *md = NULL;
374e7be843bSPierre Pronchery 
375b077aed3SPierre Pronchery     if (mdprops == NULL)
376b077aed3SPierre Pronchery         mdprops = ctx->propq;
377b077aed3SPierre Pronchery 
378b077aed3SPierre Pronchery     if (mdname != NULL) {
379e7be843bSPierre Pronchery         int md_nid;
380b077aed3SPierre Pronchery         size_t mdname_len = strlen(mdname);
381b077aed3SPierre Pronchery 
382e7be843bSPierre Pronchery         md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
383e7be843bSPierre Pronchery 
384e7be843bSPierre Pronchery         if (md == NULL) {
385b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
386b077aed3SPierre Pronchery                            "%s could not be fetched", mdname);
387e7be843bSPierre Pronchery             goto err;
388e7be843bSPierre Pronchery         }
389e7be843bSPierre Pronchery         md_nid = ossl_digest_rsa_sign_get_md_nid(md);
390e7be843bSPierre Pronchery         if (md_nid == NID_undef) {
391b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
392b077aed3SPierre Pronchery                            "digest=%s", mdname);
393e7be843bSPierre Pronchery             goto err;
394e7be843bSPierre Pronchery         }
395e7be843bSPierre Pronchery         /*
396e7be843bSPierre Pronchery          * XOF digests are not allowed except for RSA PSS.
397e7be843bSPierre Pronchery          * We don't support XOF digests with RSA PSS (yet), so just fail.
398e7be843bSPierre Pronchery          * When we do support them, uncomment the second clause.
399e7be843bSPierre Pronchery          */
400e7be843bSPierre Pronchery         if (EVP_MD_xof(md)
401e7be843bSPierre Pronchery                 /* && ctx->pad_mode != RSA_PKCS1_PSS_PADDING */) {
402e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
403e7be843bSPierre Pronchery             goto err;
404e7be843bSPierre Pronchery         }
405e7be843bSPierre Pronchery #ifdef FIPS_MODULE
406e7be843bSPierre Pronchery         {
407e7be843bSPierre Pronchery             int sha1_allowed
408e7be843bSPierre Pronchery                 = ((ctx->operation
409e7be843bSPierre Pronchery                     & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG)) == 0);
410e7be843bSPierre Pronchery 
411e7be843bSPierre Pronchery             if (!ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND_GET(ctx),
412e7be843bSPierre Pronchery                                                  OSSL_FIPS_IND_SETTABLE1,
413e7be843bSPierre Pronchery                                                  ctx->libctx,
414*88b8b7f0SEnji Cooper                                                  md_nid, sha1_allowed, 1, desc,
415e7be843bSPierre Pronchery                                                  ossl_fips_config_signature_digest_check))
416e7be843bSPierre Pronchery                 goto err;
417e7be843bSPierre Pronchery         }
418e7be843bSPierre Pronchery #endif
419e7be843bSPierre Pronchery 
420e7be843bSPierre Pronchery         if (!rsa_check_padding(ctx, mdname, NULL, md_nid))
421e7be843bSPierre Pronchery             goto err;
422e7be843bSPierre Pronchery         if (mdname_len >= sizeof(ctx->mdname)) {
423b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
424b077aed3SPierre Pronchery                            "%s exceeds name buffer length", mdname);
425e7be843bSPierre Pronchery             goto err;
426b077aed3SPierre Pronchery         }
427b077aed3SPierre Pronchery 
428b077aed3SPierre Pronchery         if (!ctx->flag_allow_md) {
429b077aed3SPierre Pronchery             if (ctx->mdname[0] != '\0' && !EVP_MD_is_a(md, ctx->mdname)) {
430b077aed3SPierre Pronchery                 ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
431b077aed3SPierre Pronchery                                "digest %s != %s", mdname, ctx->mdname);
432e7be843bSPierre Pronchery                 goto err;
433b077aed3SPierre Pronchery             }
434b077aed3SPierre Pronchery             EVP_MD_free(md);
435b077aed3SPierre Pronchery             return 1;
436b077aed3SPierre Pronchery         }
437b077aed3SPierre Pronchery 
438b077aed3SPierre Pronchery         if (!ctx->mgf1_md_set) {
439b077aed3SPierre Pronchery             if (!EVP_MD_up_ref(md)) {
440e7be843bSPierre Pronchery                 goto err;
441b077aed3SPierre Pronchery             }
442b077aed3SPierre Pronchery             EVP_MD_free(ctx->mgf1_md);
443b077aed3SPierre Pronchery             ctx->mgf1_md = md;
444b077aed3SPierre Pronchery             ctx->mgf1_mdnid = md_nid;
445b077aed3SPierre Pronchery             OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname));
446b077aed3SPierre Pronchery         }
447b077aed3SPierre Pronchery 
448b077aed3SPierre Pronchery         EVP_MD_CTX_free(ctx->mdctx);
449b077aed3SPierre Pronchery         EVP_MD_free(ctx->md);
450b077aed3SPierre Pronchery 
451b077aed3SPierre Pronchery         ctx->mdctx = NULL;
452b077aed3SPierre Pronchery         ctx->md = md;
453b077aed3SPierre Pronchery         ctx->mdnid = md_nid;
454b077aed3SPierre Pronchery         OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));
455b077aed3SPierre Pronchery     }
456b077aed3SPierre Pronchery 
457b077aed3SPierre Pronchery     return 1;
458e7be843bSPierre Pronchery err:
459e7be843bSPierre Pronchery     EVP_MD_free(md);
460e7be843bSPierre Pronchery     return 0;
461b077aed3SPierre Pronchery }
462b077aed3SPierre Pronchery 
rsa_setup_mgf1_md(PROV_RSA_CTX * ctx,const char * mdname,const char * mdprops)463b077aed3SPierre Pronchery static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname,
464b077aed3SPierre Pronchery                              const char *mdprops)
465b077aed3SPierre Pronchery {
466b077aed3SPierre Pronchery     size_t len;
467b077aed3SPierre Pronchery     EVP_MD *md = NULL;
468b077aed3SPierre Pronchery     int mdnid;
469b077aed3SPierre Pronchery 
470b077aed3SPierre Pronchery     if (mdprops == NULL)
471b077aed3SPierre Pronchery         mdprops = ctx->propq;
472b077aed3SPierre Pronchery 
473b077aed3SPierre Pronchery     if ((md = EVP_MD_fetch(ctx->libctx, mdname, mdprops)) == NULL) {
474b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
475b077aed3SPierre Pronchery                        "%s could not be fetched", mdname);
476b077aed3SPierre Pronchery         return 0;
477b077aed3SPierre Pronchery     }
478b077aed3SPierre Pronchery     /* The default for mgf1 is SHA1 - so allow SHA1 */
479e7be843bSPierre Pronchery     if ((mdnid = ossl_digest_rsa_sign_get_md_nid(md)) <= 0
480b077aed3SPierre Pronchery         || !rsa_check_padding(ctx, NULL, mdname, mdnid)) {
481b077aed3SPierre Pronchery         if (mdnid <= 0)
482b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED,
483b077aed3SPierre Pronchery                            "digest=%s", mdname);
484b077aed3SPierre Pronchery         EVP_MD_free(md);
485b077aed3SPierre Pronchery         return 0;
486b077aed3SPierre Pronchery     }
487b077aed3SPierre Pronchery     len = OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname));
488b077aed3SPierre Pronchery     if (len >= sizeof(ctx->mgf1_mdname)) {
489b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
490b077aed3SPierre Pronchery                        "%s exceeds name buffer length", mdname);
491b077aed3SPierre Pronchery         EVP_MD_free(md);
492b077aed3SPierre Pronchery         return 0;
493b077aed3SPierre Pronchery     }
494b077aed3SPierre Pronchery 
495b077aed3SPierre Pronchery     EVP_MD_free(ctx->mgf1_md);
496b077aed3SPierre Pronchery     ctx->mgf1_md = md;
497b077aed3SPierre Pronchery     ctx->mgf1_mdnid = mdnid;
498b077aed3SPierre Pronchery     ctx->mgf1_md_set = 1;
499b077aed3SPierre Pronchery     return 1;
500b077aed3SPierre Pronchery }
501b077aed3SPierre Pronchery 
502e7be843bSPierre Pronchery static int
rsa_signverify_init(PROV_RSA_CTX * prsactx,void * vrsa,OSSL_FUNC_signature_set_ctx_params_fn * set_ctx_params,const OSSL_PARAM params[],int operation,const char * desc)503e7be843bSPierre Pronchery rsa_signverify_init(PROV_RSA_CTX *prsactx, void *vrsa,
504e7be843bSPierre Pronchery                     OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,
505e7be843bSPierre Pronchery                     const OSSL_PARAM params[], int operation,
506e7be843bSPierre Pronchery                     const char *desc)
507b077aed3SPierre Pronchery {
508e7be843bSPierre Pronchery     int protect;
509b077aed3SPierre Pronchery 
510b077aed3SPierre Pronchery     if (!ossl_prov_is_running() || prsactx == NULL)
511b077aed3SPierre Pronchery         return 0;
512b077aed3SPierre Pronchery 
513b077aed3SPierre Pronchery     if (vrsa == NULL && prsactx->rsa == NULL) {
514b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
515b077aed3SPierre Pronchery         return 0;
516b077aed3SPierre Pronchery     }
517b077aed3SPierre Pronchery 
518b077aed3SPierre Pronchery     if (vrsa != NULL) {
519b077aed3SPierre Pronchery         if (!RSA_up_ref(vrsa))
520b077aed3SPierre Pronchery             return 0;
521b077aed3SPierre Pronchery         RSA_free(prsactx->rsa);
522b077aed3SPierre Pronchery         prsactx->rsa = vrsa;
523b077aed3SPierre Pronchery     }
524e7be843bSPierre Pronchery     if (!ossl_rsa_key_op_get_protect(prsactx->rsa, operation, &protect))
525e7be843bSPierre Pronchery         return 0;
526b077aed3SPierre Pronchery 
527b077aed3SPierre Pronchery     prsactx->operation = operation;
528e7be843bSPierre Pronchery     prsactx->flag_allow_update = 1;
529e7be843bSPierre Pronchery     prsactx->flag_allow_final = 1;
530e7be843bSPierre Pronchery     prsactx->flag_allow_oneshot = 1;
531b077aed3SPierre Pronchery 
532e7be843bSPierre Pronchery     /* Maximize up to digest length for sign, auto for verify */
533e7be843bSPierre Pronchery     prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
534b077aed3SPierre Pronchery     prsactx->min_saltlen = -1;
535b077aed3SPierre Pronchery 
536b077aed3SPierre Pronchery     switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) {
537b077aed3SPierre Pronchery     case RSA_FLAG_TYPE_RSA:
538b077aed3SPierre Pronchery         prsactx->pad_mode = RSA_PKCS1_PADDING;
539b077aed3SPierre Pronchery         break;
540b077aed3SPierre Pronchery     case RSA_FLAG_TYPE_RSASSAPSS:
541b077aed3SPierre Pronchery         prsactx->pad_mode = RSA_PKCS1_PSS_PADDING;
542b077aed3SPierre Pronchery 
543b077aed3SPierre Pronchery         {
544b077aed3SPierre Pronchery             const RSA_PSS_PARAMS_30 *pss =
545b077aed3SPierre Pronchery                 ossl_rsa_get0_pss_params_30(prsactx->rsa);
546b077aed3SPierre Pronchery 
547b077aed3SPierre Pronchery             if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) {
548b077aed3SPierre Pronchery                 int md_nid = ossl_rsa_pss_params_30_hashalg(pss);
549b077aed3SPierre Pronchery                 int mgf1md_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss);
550b077aed3SPierre Pronchery                 int min_saltlen = ossl_rsa_pss_params_30_saltlen(pss);
551b077aed3SPierre Pronchery                 const char *mdname, *mgf1mdname;
552b077aed3SPierre Pronchery                 size_t len;
553b077aed3SPierre Pronchery 
554b077aed3SPierre Pronchery                 mdname = ossl_rsa_oaeppss_nid2name(md_nid);
555b077aed3SPierre Pronchery                 mgf1mdname = ossl_rsa_oaeppss_nid2name(mgf1md_nid);
556b077aed3SPierre Pronchery 
557b077aed3SPierre Pronchery                 if (mdname == NULL) {
558b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
559b077aed3SPierre Pronchery                                    "PSS restrictions lack hash algorithm");
560b077aed3SPierre Pronchery                     return 0;
561b077aed3SPierre Pronchery                 }
562b077aed3SPierre Pronchery                 if (mgf1mdname == NULL) {
563b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
564b077aed3SPierre Pronchery                                    "PSS restrictions lack MGF1 hash algorithm");
565b077aed3SPierre Pronchery                     return 0;
566b077aed3SPierre Pronchery                 }
567b077aed3SPierre Pronchery 
568b077aed3SPierre Pronchery                 len = OPENSSL_strlcpy(prsactx->mdname, mdname,
569b077aed3SPierre Pronchery                                       sizeof(prsactx->mdname));
570b077aed3SPierre Pronchery                 if (len >= sizeof(prsactx->mdname)) {
571b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
572b077aed3SPierre Pronchery                                    "hash algorithm name too long");
573b077aed3SPierre Pronchery                     return 0;
574b077aed3SPierre Pronchery                 }
575b077aed3SPierre Pronchery                 len = OPENSSL_strlcpy(prsactx->mgf1_mdname, mgf1mdname,
576b077aed3SPierre Pronchery                                       sizeof(prsactx->mgf1_mdname));
577b077aed3SPierre Pronchery                 if (len >= sizeof(prsactx->mgf1_mdname)) {
578b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
579b077aed3SPierre Pronchery                                    "MGF1 hash algorithm name too long");
580b077aed3SPierre Pronchery                     return 0;
581b077aed3SPierre Pronchery                 }
582b077aed3SPierre Pronchery                 prsactx->saltlen = min_saltlen;
583b077aed3SPierre Pronchery 
584b077aed3SPierre Pronchery                 /* call rsa_setup_mgf1_md before rsa_setup_md to avoid duplication */
585b077aed3SPierre Pronchery                 if (!rsa_setup_mgf1_md(prsactx, mgf1mdname, prsactx->propq)
586e7be843bSPierre Pronchery                     || !rsa_setup_md(prsactx, mdname, prsactx->propq, desc)
587b077aed3SPierre Pronchery                     || !rsa_check_parameters(prsactx, min_saltlen))
588b077aed3SPierre Pronchery                     return 0;
589b077aed3SPierre Pronchery             }
590b077aed3SPierre Pronchery         }
591b077aed3SPierre Pronchery 
592b077aed3SPierre Pronchery         break;
593b077aed3SPierre Pronchery     default:
594b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
595b077aed3SPierre Pronchery         return 0;
596b077aed3SPierre Pronchery     }
597b077aed3SPierre Pronchery 
598e7be843bSPierre Pronchery     OSSL_FIPS_IND_SET_APPROVED(prsactx)
599e7be843bSPierre Pronchery     if (!set_ctx_params(prsactx, params))
600b077aed3SPierre Pronchery         return 0;
601e7be843bSPierre Pronchery #ifdef FIPS_MODULE
602e7be843bSPierre Pronchery     if (!ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND_GET(prsactx),
603e7be843bSPierre Pronchery                                      OSSL_FIPS_IND_SETTABLE0, prsactx->libctx,
604e7be843bSPierre Pronchery                                      prsactx->rsa, desc, protect))
605e7be843bSPierre Pronchery         return 0;
606e7be843bSPierre Pronchery #endif
607b077aed3SPierre Pronchery     return 1;
608b077aed3SPierre Pronchery }
609b077aed3SPierre Pronchery 
setup_tbuf(PROV_RSA_CTX * ctx)610b077aed3SPierre Pronchery static int setup_tbuf(PROV_RSA_CTX *ctx)
611b077aed3SPierre Pronchery {
612b077aed3SPierre Pronchery     if (ctx->tbuf != NULL)
613b077aed3SPierre Pronchery         return 1;
614e7be843bSPierre Pronchery     if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL)
615b077aed3SPierre Pronchery         return 0;
616b077aed3SPierre Pronchery     return 1;
617b077aed3SPierre Pronchery }
618b077aed3SPierre Pronchery 
clean_tbuf(PROV_RSA_CTX * ctx)619b077aed3SPierre Pronchery static void clean_tbuf(PROV_RSA_CTX *ctx)
620b077aed3SPierre Pronchery {
621b077aed3SPierre Pronchery     if (ctx->tbuf != NULL)
622b077aed3SPierre Pronchery         OPENSSL_cleanse(ctx->tbuf, RSA_size(ctx->rsa));
623b077aed3SPierre Pronchery }
624b077aed3SPierre Pronchery 
free_tbuf(PROV_RSA_CTX * ctx)625b077aed3SPierre Pronchery static void free_tbuf(PROV_RSA_CTX *ctx)
626b077aed3SPierre Pronchery {
627b077aed3SPierre Pronchery     clean_tbuf(ctx);
628b077aed3SPierre Pronchery     OPENSSL_free(ctx->tbuf);
629b077aed3SPierre Pronchery     ctx->tbuf = NULL;
630b077aed3SPierre Pronchery }
631b077aed3SPierre Pronchery 
632e7be843bSPierre Pronchery #ifdef FIPS_MODULE
rsa_pss_saltlen_check_passed(PROV_RSA_CTX * ctx,const char * algoname,int saltlen)633e7be843bSPierre Pronchery static int rsa_pss_saltlen_check_passed(PROV_RSA_CTX *ctx, const char *algoname, int saltlen)
634b077aed3SPierre Pronchery {
635e7be843bSPierre Pronchery     int mdsize = rsa_get_md_size(ctx);
636e7be843bSPierre Pronchery     /*
637e7be843bSPierre Pronchery      * Perform the check if the salt length is compliant to FIPS 186-5.
638e7be843bSPierre Pronchery      *
639e7be843bSPierre Pronchery      * According to FIPS 186-5 5.4 (g), the salt length shall be between zero
640e7be843bSPierre Pronchery      * and the output block length of the digest function (inclusive).
641e7be843bSPierre Pronchery      */
642e7be843bSPierre Pronchery     int approved = (saltlen >= 0 && saltlen <= mdsize);
643e7be843bSPierre Pronchery 
644e7be843bSPierre Pronchery     if (!approved) {
645e7be843bSPierre Pronchery         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE3,
646e7be843bSPierre Pronchery                                          ctx->libctx,
647e7be843bSPierre Pronchery                                          algoname, "PSS Salt Length",
648e7be843bSPierre Pronchery                                          ossl_fips_config_rsa_pss_saltlen_check)) {
649e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
650b077aed3SPierre Pronchery             return 0;
651e7be843bSPierre Pronchery         }
652b077aed3SPierre Pronchery     }
653b077aed3SPierre Pronchery 
654e7be843bSPierre Pronchery     return 1;
655e7be843bSPierre Pronchery }
656e7be843bSPierre Pronchery #endif
657e7be843bSPierre Pronchery 
rsa_sign_init(void * vprsactx,void * vrsa,const OSSL_PARAM params[])658e7be843bSPierre Pronchery static int rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[])
659b077aed3SPierre Pronchery {
660b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
661e7be843bSPierre Pronchery 
662e7be843bSPierre Pronchery #ifdef FIPS_MODULE
663e7be843bSPierre Pronchery     if (prsactx != NULL)
664e7be843bSPierre Pronchery         prsactx->verify_message = 1;
665e7be843bSPierre Pronchery #endif
666e7be843bSPierre Pronchery 
667e7be843bSPierre Pronchery     return rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params,
668e7be843bSPierre Pronchery                                EVP_PKEY_OP_SIGN, "RSA Sign Init");
669e7be843bSPierre Pronchery }
670e7be843bSPierre Pronchery 
671e7be843bSPierre Pronchery /*
672e7be843bSPierre Pronchery  * Sign tbs without digesting it first.  This is suitable for "primitive"
673e7be843bSPierre Pronchery  * signing and signing the digest of a message, i.e. should be used with
674e7be843bSPierre Pronchery  * implementations of the keytype related algorithms.
675e7be843bSPierre Pronchery  */
rsa_sign_directly(PROV_RSA_CTX * prsactx,unsigned char * sig,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)676e7be843bSPierre Pronchery static int rsa_sign_directly(PROV_RSA_CTX *prsactx,
677e7be843bSPierre Pronchery                              unsigned char *sig, size_t *siglen, size_t sigsize,
678e7be843bSPierre Pronchery                              const unsigned char *tbs, size_t tbslen)
679e7be843bSPierre Pronchery {
680b077aed3SPierre Pronchery     int ret;
681b077aed3SPierre Pronchery     size_t rsasize = RSA_size(prsactx->rsa);
682b077aed3SPierre Pronchery     size_t mdsize = rsa_get_md_size(prsactx);
683b077aed3SPierre Pronchery 
684b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
685b077aed3SPierre Pronchery         return 0;
686b077aed3SPierre Pronchery 
687b077aed3SPierre Pronchery     if (sig == NULL) {
688b077aed3SPierre Pronchery         *siglen = rsasize;
689b077aed3SPierre Pronchery         return 1;
690b077aed3SPierre Pronchery     }
691b077aed3SPierre Pronchery 
692b077aed3SPierre Pronchery     if (sigsize < rsasize) {
693b077aed3SPierre Pronchery         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE,
694b077aed3SPierre Pronchery                        "is %zu, should be at least %zu", sigsize, rsasize);
695b077aed3SPierre Pronchery         return 0;
696b077aed3SPierre Pronchery     }
697b077aed3SPierre Pronchery 
698b077aed3SPierre Pronchery     if (mdsize != 0) {
699b077aed3SPierre Pronchery         if (tbslen != mdsize) {
700b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
701b077aed3SPierre Pronchery             return 0;
702b077aed3SPierre Pronchery         }
703b077aed3SPierre Pronchery 
704b077aed3SPierre Pronchery #ifndef FIPS_MODULE
705b077aed3SPierre Pronchery         if (EVP_MD_is_a(prsactx->md, OSSL_DIGEST_NAME_MDC2)) {
706b077aed3SPierre Pronchery             unsigned int sltmp;
707b077aed3SPierre Pronchery 
708b077aed3SPierre Pronchery             if (prsactx->pad_mode != RSA_PKCS1_PADDING) {
709b077aed3SPierre Pronchery                 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE,
710b077aed3SPierre Pronchery                                "only PKCS#1 padding supported with MDC2");
711b077aed3SPierre Pronchery                 return 0;
712b077aed3SPierre Pronchery             }
713b077aed3SPierre Pronchery             ret = RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp,
714b077aed3SPierre Pronchery                                              prsactx->rsa);
715b077aed3SPierre Pronchery 
716b077aed3SPierre Pronchery             if (ret <= 0) {
717b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
718b077aed3SPierre Pronchery                 return 0;
719b077aed3SPierre Pronchery             }
720b077aed3SPierre Pronchery             ret = sltmp;
721b077aed3SPierre Pronchery             goto end;
722b077aed3SPierre Pronchery         }
723b077aed3SPierre Pronchery #endif
724b077aed3SPierre Pronchery         switch (prsactx->pad_mode) {
725b077aed3SPierre Pronchery         case RSA_X931_PADDING:
726b077aed3SPierre Pronchery             if ((size_t)RSA_size(prsactx->rsa) < tbslen + 1) {
727b077aed3SPierre Pronchery                 ERR_raise_data(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL,
728b077aed3SPierre Pronchery                                "RSA key size = %d, expected minimum = %d",
729b077aed3SPierre Pronchery                                RSA_size(prsactx->rsa), tbslen + 1);
730b077aed3SPierre Pronchery                 return 0;
731b077aed3SPierre Pronchery             }
732b077aed3SPierre Pronchery             if (!setup_tbuf(prsactx)) {
733e7be843bSPierre Pronchery                 ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB);
734b077aed3SPierre Pronchery                 return 0;
735b077aed3SPierre Pronchery             }
736b077aed3SPierre Pronchery             memcpy(prsactx->tbuf, tbs, tbslen);
737b077aed3SPierre Pronchery             prsactx->tbuf[tbslen] = RSA_X931_hash_id(prsactx->mdnid);
738b077aed3SPierre Pronchery             ret = RSA_private_encrypt(tbslen + 1, prsactx->tbuf,
739b077aed3SPierre Pronchery                                       sig, prsactx->rsa, RSA_X931_PADDING);
740b077aed3SPierre Pronchery             clean_tbuf(prsactx);
741b077aed3SPierre Pronchery             break;
742b077aed3SPierre Pronchery         case RSA_PKCS1_PADDING:
743b077aed3SPierre Pronchery             {
744b077aed3SPierre Pronchery                 unsigned int sltmp;
745b077aed3SPierre Pronchery 
746b077aed3SPierre Pronchery                 ret = RSA_sign(prsactx->mdnid, tbs, tbslen, sig, &sltmp,
747b077aed3SPierre Pronchery                                prsactx->rsa);
748b077aed3SPierre Pronchery                 if (ret <= 0) {
749b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
750b077aed3SPierre Pronchery                     return 0;
751b077aed3SPierre Pronchery                 }
752b077aed3SPierre Pronchery                 ret = sltmp;
753b077aed3SPierre Pronchery             }
754b077aed3SPierre Pronchery             break;
755b077aed3SPierre Pronchery 
756b077aed3SPierre Pronchery         case RSA_PKCS1_PSS_PADDING:
757e7be843bSPierre Pronchery             {
758e7be843bSPierre Pronchery                 int saltlen;
759e7be843bSPierre Pronchery 
760b077aed3SPierre Pronchery                 /* Check PSS restrictions */
761b077aed3SPierre Pronchery                 if (rsa_pss_restricted(prsactx)) {
762b077aed3SPierre Pronchery                     switch (prsactx->saltlen) {
763b077aed3SPierre Pronchery                     case RSA_PSS_SALTLEN_DIGEST:
764b077aed3SPierre Pronchery                         if (prsactx->min_saltlen > EVP_MD_get_size(prsactx->md)) {
765b077aed3SPierre Pronchery                             ERR_raise_data(ERR_LIB_PROV,
766b077aed3SPierre Pronchery                                            PROV_R_PSS_SALTLEN_TOO_SMALL,
767b077aed3SPierre Pronchery                                            "minimum salt length set to %d, "
768b077aed3SPierre Pronchery                                            "but the digest only gives %d",
769b077aed3SPierre Pronchery                                            prsactx->min_saltlen,
770b077aed3SPierre Pronchery                                            EVP_MD_get_size(prsactx->md));
771b077aed3SPierre Pronchery                             return 0;
772b077aed3SPierre Pronchery                         }
773b077aed3SPierre Pronchery                         /* FALLTHRU */
774b077aed3SPierre Pronchery                     default:
775b077aed3SPierre Pronchery                         if (prsactx->saltlen >= 0
776b077aed3SPierre Pronchery                             && prsactx->saltlen < prsactx->min_saltlen) {
777b077aed3SPierre Pronchery                             ERR_raise_data(ERR_LIB_PROV,
778b077aed3SPierre Pronchery                                            PROV_R_PSS_SALTLEN_TOO_SMALL,
779b077aed3SPierre Pronchery                                            "minimum salt length set to %d, but the"
780b077aed3SPierre Pronchery                                            "actual salt length is only set to %d",
781b077aed3SPierre Pronchery                                            prsactx->min_saltlen,
782b077aed3SPierre Pronchery                                            prsactx->saltlen);
783b077aed3SPierre Pronchery                             return 0;
784b077aed3SPierre Pronchery                         }
785b077aed3SPierre Pronchery                         break;
786b077aed3SPierre Pronchery                     }
787b077aed3SPierre Pronchery                 }
788b077aed3SPierre Pronchery                 if (!setup_tbuf(prsactx))
789b077aed3SPierre Pronchery                     return 0;
790e7be843bSPierre Pronchery                 saltlen = prsactx->saltlen;
791e7be843bSPierre Pronchery                 if (!ossl_rsa_padding_add_PKCS1_PSS_mgf1(prsactx->rsa,
792b077aed3SPierre Pronchery                                                          prsactx->tbuf, tbs,
793b077aed3SPierre Pronchery                                                          prsactx->md, prsactx->mgf1_md,
794e7be843bSPierre Pronchery                                                          &saltlen)) {
795b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
796b077aed3SPierre Pronchery                     return 0;
797b077aed3SPierre Pronchery                 }
798e7be843bSPierre Pronchery #ifdef FIPS_MODULE
799e7be843bSPierre Pronchery                 if (!rsa_pss_saltlen_check_passed(prsactx, "RSA Sign", saltlen))
800e7be843bSPierre Pronchery                     return 0;
801e7be843bSPierre Pronchery #endif
802b077aed3SPierre Pronchery                 ret = RSA_private_encrypt(RSA_size(prsactx->rsa), prsactx->tbuf,
803b077aed3SPierre Pronchery                                           sig, prsactx->rsa, RSA_NO_PADDING);
804b077aed3SPierre Pronchery                 clean_tbuf(prsactx);
805e7be843bSPierre Pronchery             }
806b077aed3SPierre Pronchery             break;
807b077aed3SPierre Pronchery 
808b077aed3SPierre Pronchery         default:
809b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE,
810b077aed3SPierre Pronchery                            "Only X.931, PKCS#1 v1.5 or PSS padding allowed");
811b077aed3SPierre Pronchery             return 0;
812b077aed3SPierre Pronchery         }
813b077aed3SPierre Pronchery     } else {
814b077aed3SPierre Pronchery         ret = RSA_private_encrypt(tbslen, tbs, sig, prsactx->rsa,
815b077aed3SPierre Pronchery                                   prsactx->pad_mode);
816b077aed3SPierre Pronchery     }
817b077aed3SPierre Pronchery 
818b077aed3SPierre Pronchery #ifndef FIPS_MODULE
819b077aed3SPierre Pronchery  end:
820b077aed3SPierre Pronchery #endif
821b077aed3SPierre Pronchery     if (ret <= 0) {
822b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
823b077aed3SPierre Pronchery         return 0;
824b077aed3SPierre Pronchery     }
825b077aed3SPierre Pronchery 
826b077aed3SPierre Pronchery     *siglen = ret;
827b077aed3SPierre Pronchery     return 1;
828b077aed3SPierre Pronchery }
829b077aed3SPierre Pronchery 
rsa_signverify_message_update(void * vprsactx,const unsigned char * data,size_t datalen)830e7be843bSPierre Pronchery static int rsa_signverify_message_update(void *vprsactx,
831e7be843bSPierre Pronchery                                          const unsigned char *data,
832e7be843bSPierre Pronchery                                          size_t datalen)
833e7be843bSPierre Pronchery {
834e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
835e7be843bSPierre Pronchery 
836e7be843bSPierre Pronchery     if (prsactx == NULL || prsactx->mdctx == NULL)
837e7be843bSPierre Pronchery         return 0;
838e7be843bSPierre Pronchery 
839e7be843bSPierre Pronchery     if (!prsactx->flag_allow_update) {
840e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER);
841e7be843bSPierre Pronchery         return 0;
842e7be843bSPierre Pronchery     }
843e7be843bSPierre Pronchery     prsactx->flag_allow_oneshot = 0;
844e7be843bSPierre Pronchery 
845e7be843bSPierre Pronchery     return EVP_DigestUpdate(prsactx->mdctx, data, datalen);
846e7be843bSPierre Pronchery }
847e7be843bSPierre Pronchery 
rsa_sign_message_final(void * vprsactx,unsigned char * sig,size_t * siglen,size_t sigsize)848e7be843bSPierre Pronchery static int rsa_sign_message_final(void *vprsactx, unsigned char *sig,
849e7be843bSPierre Pronchery                                   size_t *siglen, size_t sigsize)
850e7be843bSPierre Pronchery {
851e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
852e7be843bSPierre Pronchery     unsigned char digest[EVP_MAX_MD_SIZE];
853e7be843bSPierre Pronchery     unsigned int dlen = 0;
854e7be843bSPierre Pronchery 
855e7be843bSPierre Pronchery     if (!ossl_prov_is_running() || prsactx == NULL)
856e7be843bSPierre Pronchery         return 0;
857e7be843bSPierre Pronchery     if (prsactx->mdctx == NULL)
858e7be843bSPierre Pronchery         return 0;
859e7be843bSPierre Pronchery     if (!prsactx->flag_allow_final) {
860e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER);
861e7be843bSPierre Pronchery         return 0;
862e7be843bSPierre Pronchery     }
863e7be843bSPierre Pronchery 
864e7be843bSPierre Pronchery     /*
865e7be843bSPierre Pronchery      * If sig is NULL then we're just finding out the sig size. Other fields
866e7be843bSPierre Pronchery      * are ignored. Defer to rsa_sign.
867e7be843bSPierre Pronchery      */
868e7be843bSPierre Pronchery     if (sig != NULL) {
869e7be843bSPierre Pronchery         /*
870e7be843bSPierre Pronchery          * The digests used here are all known (see rsa_get_md_nid()), so they
871e7be843bSPierre Pronchery          * should not exceed the internal buffer size of EVP_MAX_MD_SIZE.
872e7be843bSPierre Pronchery          */
873e7be843bSPierre Pronchery         if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen))
874e7be843bSPierre Pronchery             return 0;
875e7be843bSPierre Pronchery 
876e7be843bSPierre Pronchery         prsactx->flag_allow_update = 0;
877e7be843bSPierre Pronchery         prsactx->flag_allow_oneshot = 0;
878e7be843bSPierre Pronchery         prsactx->flag_allow_final = 0;
879e7be843bSPierre Pronchery     }
880e7be843bSPierre Pronchery 
881e7be843bSPierre Pronchery     return rsa_sign_directly(prsactx, sig, siglen, sigsize, digest, dlen);
882e7be843bSPierre Pronchery }
883e7be843bSPierre Pronchery 
884e7be843bSPierre Pronchery /*
885e7be843bSPierre Pronchery  * If signing a message, digest tbs and sign the result.
886e7be843bSPierre Pronchery  * Otherwise, sign tbs directly.
887e7be843bSPierre Pronchery  */
rsa_sign(void * vprsactx,unsigned char * sig,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)888e7be843bSPierre Pronchery static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen,
889e7be843bSPierre Pronchery                     size_t sigsize, const unsigned char *tbs, size_t tbslen)
890e7be843bSPierre Pronchery {
891e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
892e7be843bSPierre Pronchery 
893e7be843bSPierre Pronchery     if (!ossl_prov_is_running() || prsactx == NULL)
894e7be843bSPierre Pronchery         return 0;
895e7be843bSPierre Pronchery     if (!prsactx->flag_allow_oneshot) {
896e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER);
897e7be843bSPierre Pronchery         return 0;
898e7be843bSPierre Pronchery     }
899e7be843bSPierre Pronchery 
900e7be843bSPierre Pronchery     if (prsactx->operation == EVP_PKEY_OP_SIGNMSG) {
901e7be843bSPierre Pronchery         /*
902e7be843bSPierre Pronchery          * If |sig| is NULL, the caller is only looking for the sig length.
903e7be843bSPierre Pronchery          * DO NOT update the input in this case.
904e7be843bSPierre Pronchery          */
905e7be843bSPierre Pronchery         if (sig == NULL)
906e7be843bSPierre Pronchery             return rsa_sign_message_final(prsactx, sig, siglen, sigsize);
907e7be843bSPierre Pronchery 
908e7be843bSPierre Pronchery         return rsa_signverify_message_update(prsactx, tbs, tbslen)
909e7be843bSPierre Pronchery             && rsa_sign_message_final(prsactx, sig, siglen, sigsize);
910e7be843bSPierre Pronchery     }
911e7be843bSPierre Pronchery     return rsa_sign_directly(prsactx, sig, siglen, sigsize, tbs, tbslen);
912e7be843bSPierre Pronchery }
913e7be843bSPierre Pronchery 
rsa_verify_recover_init(void * vprsactx,void * vrsa,const OSSL_PARAM params[])914b077aed3SPierre Pronchery static int rsa_verify_recover_init(void *vprsactx, void *vrsa,
915b077aed3SPierre Pronchery                                    const OSSL_PARAM params[])
916b077aed3SPierre Pronchery {
917e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
918e7be843bSPierre Pronchery 
919e7be843bSPierre Pronchery #ifdef FIPS_MODULE
920e7be843bSPierre Pronchery     if (prsactx != NULL)
921e7be843bSPierre Pronchery         prsactx->verify_message = 0;
922e7be843bSPierre Pronchery #endif
923e7be843bSPierre Pronchery 
924e7be843bSPierre Pronchery     return rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params,
925e7be843bSPierre Pronchery                                EVP_PKEY_OP_VERIFYRECOVER, "RSA VerifyRecover Init");
926b077aed3SPierre Pronchery }
927b077aed3SPierre Pronchery 
928e7be843bSPierre Pronchery /*
929e7be843bSPierre Pronchery  * There is no message variant of verify recover, so no need for
930e7be843bSPierre Pronchery  * 'rsa_verify_recover_directly', just use this function, er, directly.
931e7be843bSPierre Pronchery  */
rsa_verify_recover(void * vprsactx,unsigned char * rout,size_t * routlen,size_t routsize,const unsigned char * sig,size_t siglen)932b077aed3SPierre Pronchery static int rsa_verify_recover(void *vprsactx,
933e7be843bSPierre Pronchery                               unsigned char *rout, size_t *routlen,
934b077aed3SPierre Pronchery                               size_t routsize,
935e7be843bSPierre Pronchery                               const unsigned char *sig, size_t siglen)
936b077aed3SPierre Pronchery {
937b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
938b077aed3SPierre Pronchery     int ret;
939b077aed3SPierre Pronchery 
940b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
941b077aed3SPierre Pronchery         return 0;
942b077aed3SPierre Pronchery 
943b077aed3SPierre Pronchery     if (rout == NULL) {
944b077aed3SPierre Pronchery         *routlen = RSA_size(prsactx->rsa);
945b077aed3SPierre Pronchery         return 1;
946b077aed3SPierre Pronchery     }
947b077aed3SPierre Pronchery 
948b077aed3SPierre Pronchery     if (prsactx->md != NULL) {
949b077aed3SPierre Pronchery         switch (prsactx->pad_mode) {
950b077aed3SPierre Pronchery         case RSA_X931_PADDING:
951b077aed3SPierre Pronchery             if (!setup_tbuf(prsactx))
952b077aed3SPierre Pronchery                 return 0;
953b077aed3SPierre Pronchery             ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa,
954b077aed3SPierre Pronchery                                      RSA_X931_PADDING);
955*88b8b7f0SEnji Cooper             if (ret <= 0) {
956b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
957b077aed3SPierre Pronchery                 return 0;
958b077aed3SPierre Pronchery             }
959b077aed3SPierre Pronchery             ret--;
960b077aed3SPierre Pronchery             if (prsactx->tbuf[ret] != RSA_X931_hash_id(prsactx->mdnid)) {
961b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
962b077aed3SPierre Pronchery                 return 0;
963b077aed3SPierre Pronchery             }
964b077aed3SPierre Pronchery             if (ret != EVP_MD_get_size(prsactx->md)) {
965b077aed3SPierre Pronchery                 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH,
966b077aed3SPierre Pronchery                                "Should be %d, but got %d",
967b077aed3SPierre Pronchery                                EVP_MD_get_size(prsactx->md), ret);
968b077aed3SPierre Pronchery                 return 0;
969b077aed3SPierre Pronchery             }
970b077aed3SPierre Pronchery 
971b077aed3SPierre Pronchery             *routlen = ret;
972b077aed3SPierre Pronchery             if (rout != prsactx->tbuf) {
973b077aed3SPierre Pronchery                 if (routsize < (size_t)ret) {
974b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL,
975b077aed3SPierre Pronchery                                    "buffer size is %d, should be %d",
976b077aed3SPierre Pronchery                                    routsize, ret);
977b077aed3SPierre Pronchery                     return 0;
978b077aed3SPierre Pronchery                 }
979b077aed3SPierre Pronchery                 memcpy(rout, prsactx->tbuf, ret);
980b077aed3SPierre Pronchery             }
981b077aed3SPierre Pronchery             break;
982b077aed3SPierre Pronchery 
983b077aed3SPierre Pronchery         case RSA_PKCS1_PADDING:
984b077aed3SPierre Pronchery             {
985b077aed3SPierre Pronchery                 size_t sltmp;
986b077aed3SPierre Pronchery 
987b077aed3SPierre Pronchery                 ret = ossl_rsa_verify(prsactx->mdnid, NULL, 0, rout, &sltmp,
988b077aed3SPierre Pronchery                                       sig, siglen, prsactx->rsa);
989b077aed3SPierre Pronchery                 if (ret <= 0) {
990b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
991b077aed3SPierre Pronchery                     return 0;
992b077aed3SPierre Pronchery                 }
993b077aed3SPierre Pronchery                 ret = sltmp;
994b077aed3SPierre Pronchery             }
995b077aed3SPierre Pronchery             break;
996b077aed3SPierre Pronchery 
997b077aed3SPierre Pronchery         default:
998b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE,
999b077aed3SPierre Pronchery                            "Only X.931 or PKCS#1 v1.5 padding allowed");
1000b077aed3SPierre Pronchery             return 0;
1001b077aed3SPierre Pronchery         }
1002b077aed3SPierre Pronchery     } else {
1003b077aed3SPierre Pronchery         ret = RSA_public_decrypt(siglen, sig, rout, prsactx->rsa,
1004b077aed3SPierre Pronchery                                  prsactx->pad_mode);
1005*88b8b7f0SEnji Cooper         if (ret <= 0) {
1006b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
1007b077aed3SPierre Pronchery             return 0;
1008b077aed3SPierre Pronchery         }
1009b077aed3SPierre Pronchery     }
1010b077aed3SPierre Pronchery     *routlen = ret;
1011b077aed3SPierre Pronchery     return 1;
1012b077aed3SPierre Pronchery }
1013b077aed3SPierre Pronchery 
rsa_verify_init(void * vprsactx,void * vrsa,const OSSL_PARAM params[])1014b077aed3SPierre Pronchery static int rsa_verify_init(void *vprsactx, void *vrsa,
1015b077aed3SPierre Pronchery                            const OSSL_PARAM params[])
1016b077aed3SPierre Pronchery {
1017e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1018e7be843bSPierre Pronchery 
1019e7be843bSPierre Pronchery #ifdef FIPS_MODULE
1020e7be843bSPierre Pronchery     if (prsactx != NULL)
1021e7be843bSPierre Pronchery         prsactx->verify_message = 0;
1022e7be843bSPierre Pronchery #endif
1023e7be843bSPierre Pronchery 
1024e7be843bSPierre Pronchery     return rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params,
1025e7be843bSPierre Pronchery                                EVP_PKEY_OP_VERIFY, "RSA Verify Init");
1026b077aed3SPierre Pronchery }
1027b077aed3SPierre Pronchery 
rsa_verify_directly(PROV_RSA_CTX * prsactx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)1028e7be843bSPierre Pronchery static int rsa_verify_directly(PROV_RSA_CTX *prsactx,
1029e7be843bSPierre Pronchery                                const unsigned char *sig, size_t siglen,
1030b077aed3SPierre Pronchery                                const unsigned char *tbs, size_t tbslen)
1031b077aed3SPierre Pronchery {
1032b077aed3SPierre Pronchery     size_t rslen;
1033b077aed3SPierre Pronchery 
1034b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
1035b077aed3SPierre Pronchery         return 0;
1036b077aed3SPierre Pronchery     if (prsactx->md != NULL) {
1037b077aed3SPierre Pronchery         switch (prsactx->pad_mode) {
1038b077aed3SPierre Pronchery         case RSA_PKCS1_PADDING:
1039b077aed3SPierre Pronchery             if (!RSA_verify(prsactx->mdnid, tbs, tbslen, sig, siglen,
1040b077aed3SPierre Pronchery                             prsactx->rsa)) {
1041b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
1042b077aed3SPierre Pronchery                 return 0;
1043b077aed3SPierre Pronchery             }
1044b077aed3SPierre Pronchery             return 1;
1045b077aed3SPierre Pronchery         case RSA_X931_PADDING:
1046b077aed3SPierre Pronchery             if (!setup_tbuf(prsactx))
1047b077aed3SPierre Pronchery                 return 0;
1048b077aed3SPierre Pronchery             if (rsa_verify_recover(prsactx, prsactx->tbuf, &rslen, 0,
1049b077aed3SPierre Pronchery                                    sig, siglen) <= 0)
1050b077aed3SPierre Pronchery                 return 0;
1051b077aed3SPierre Pronchery             break;
1052b077aed3SPierre Pronchery         case RSA_PKCS1_PSS_PADDING:
1053b077aed3SPierre Pronchery             {
1054b077aed3SPierre Pronchery                 int ret;
1055e7be843bSPierre Pronchery                 int saltlen;
1056b077aed3SPierre Pronchery                 size_t mdsize;
1057b077aed3SPierre Pronchery 
1058b077aed3SPierre Pronchery                 /*
1059b077aed3SPierre Pronchery                  * We need to check this for the RSA_verify_PKCS1_PSS_mgf1()
1060b077aed3SPierre Pronchery                  * call
1061b077aed3SPierre Pronchery                  */
1062b077aed3SPierre Pronchery                 mdsize = rsa_get_md_size(prsactx);
1063b077aed3SPierre Pronchery                 if (tbslen != mdsize) {
1064b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH,
1065b077aed3SPierre Pronchery                                    "Should be %d, but got %d",
1066b077aed3SPierre Pronchery                                    mdsize, tbslen);
1067b077aed3SPierre Pronchery                     return 0;
1068b077aed3SPierre Pronchery                 }
1069b077aed3SPierre Pronchery 
1070b077aed3SPierre Pronchery                 if (!setup_tbuf(prsactx))
1071b077aed3SPierre Pronchery                     return 0;
1072b077aed3SPierre Pronchery                 ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf,
1073b077aed3SPierre Pronchery                                          prsactx->rsa, RSA_NO_PADDING);
1074b077aed3SPierre Pronchery                 if (ret <= 0) {
1075b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
1076b077aed3SPierre Pronchery                     return 0;
1077b077aed3SPierre Pronchery                 }
1078e7be843bSPierre Pronchery                 saltlen = prsactx->saltlen;
1079e7be843bSPierre Pronchery                 ret = ossl_rsa_verify_PKCS1_PSS_mgf1(prsactx->rsa, tbs,
1080b077aed3SPierre Pronchery                                                      prsactx->md, prsactx->mgf1_md,
1081b077aed3SPierre Pronchery                                                      prsactx->tbuf,
1082e7be843bSPierre Pronchery                                                      &saltlen);
1083b077aed3SPierre Pronchery                 if (ret <= 0) {
1084b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
1085b077aed3SPierre Pronchery                     return 0;
1086b077aed3SPierre Pronchery                 }
1087e7be843bSPierre Pronchery #ifdef FIPS_MODULE
1088e7be843bSPierre Pronchery                 if (!rsa_pss_saltlen_check_passed(prsactx, "RSA Verify", saltlen))
1089e7be843bSPierre Pronchery                     return 0;
1090e7be843bSPierre Pronchery #endif
1091b077aed3SPierre Pronchery                 return 1;
1092b077aed3SPierre Pronchery             }
1093b077aed3SPierre Pronchery         default:
1094b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE,
1095b077aed3SPierre Pronchery                            "Only X.931, PKCS#1 v1.5 or PSS padding allowed");
1096b077aed3SPierre Pronchery             return 0;
1097b077aed3SPierre Pronchery         }
1098b077aed3SPierre Pronchery     } else {
1099b077aed3SPierre Pronchery         int ret;
1100b077aed3SPierre Pronchery 
1101b077aed3SPierre Pronchery         if (!setup_tbuf(prsactx))
1102b077aed3SPierre Pronchery             return 0;
1103b077aed3SPierre Pronchery         ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa,
1104b077aed3SPierre Pronchery                                  prsactx->pad_mode);
1105b077aed3SPierre Pronchery         if (ret <= 0) {
1106b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB);
1107b077aed3SPierre Pronchery             return 0;
1108b077aed3SPierre Pronchery         }
1109b077aed3SPierre Pronchery         rslen = (size_t)ret;
1110b077aed3SPierre Pronchery     }
1111b077aed3SPierre Pronchery 
1112b077aed3SPierre Pronchery     if ((rslen != tbslen) || memcmp(tbs, prsactx->tbuf, rslen))
1113b077aed3SPierre Pronchery         return 0;
1114b077aed3SPierre Pronchery 
1115b077aed3SPierre Pronchery     return 1;
1116b077aed3SPierre Pronchery }
1117b077aed3SPierre Pronchery 
rsa_verify_set_sig(void * vprsactx,const unsigned char * sig,size_t siglen)1118e7be843bSPierre Pronchery static int rsa_verify_set_sig(void *vprsactx,
1119e7be843bSPierre Pronchery                               const unsigned char *sig, size_t siglen)
1120e7be843bSPierre Pronchery {
1121e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1122e7be843bSPierre Pronchery     OSSL_PARAM params[2];
1123e7be843bSPierre Pronchery 
1124e7be843bSPierre Pronchery     params[0] =
1125e7be843bSPierre Pronchery         OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE,
1126e7be843bSPierre Pronchery                                           (unsigned char *)sig, siglen);
1127e7be843bSPierre Pronchery     params[1] = OSSL_PARAM_construct_end();
1128e7be843bSPierre Pronchery     return rsa_sigalg_set_ctx_params(prsactx, params);
1129e7be843bSPierre Pronchery }
1130e7be843bSPierre Pronchery 
rsa_verify_message_final(void * vprsactx)1131e7be843bSPierre Pronchery static int rsa_verify_message_final(void *vprsactx)
1132e7be843bSPierre Pronchery {
1133e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1134e7be843bSPierre Pronchery     unsigned char digest[EVP_MAX_MD_SIZE];
1135e7be843bSPierre Pronchery     unsigned int dlen = 0;
1136e7be843bSPierre Pronchery 
1137e7be843bSPierre Pronchery     if (!ossl_prov_is_running() || prsactx == NULL)
1138e7be843bSPierre Pronchery         return 0;
1139e7be843bSPierre Pronchery     if (prsactx->mdctx == NULL)
1140e7be843bSPierre Pronchery         return 0;
1141e7be843bSPierre Pronchery     if (!prsactx->flag_allow_final) {
1142e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER);
1143e7be843bSPierre Pronchery         return 0;
1144e7be843bSPierre Pronchery     }
1145e7be843bSPierre Pronchery 
1146e7be843bSPierre Pronchery     /*
1147e7be843bSPierre Pronchery      * The digests used here are all known (see rsa_get_md_nid()), so they
1148e7be843bSPierre Pronchery      * should not exceed the internal buffer size of EVP_MAX_MD_SIZE.
1149e7be843bSPierre Pronchery      */
1150e7be843bSPierre Pronchery     if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen))
1151e7be843bSPierre Pronchery         return 0;
1152e7be843bSPierre Pronchery 
1153e7be843bSPierre Pronchery     prsactx->flag_allow_update = 0;
1154e7be843bSPierre Pronchery     prsactx->flag_allow_final = 0;
1155e7be843bSPierre Pronchery     prsactx->flag_allow_oneshot = 0;
1156e7be843bSPierre Pronchery 
1157e7be843bSPierre Pronchery     return rsa_verify_directly(prsactx, prsactx->sig, prsactx->siglen,
1158e7be843bSPierre Pronchery                                digest, dlen);
1159e7be843bSPierre Pronchery }
1160e7be843bSPierre Pronchery 
1161e7be843bSPierre Pronchery /*
1162e7be843bSPierre Pronchery  * If verifying a message, digest tbs and verify the result.
1163e7be843bSPierre Pronchery  * Otherwise, verify tbs directly.
1164e7be843bSPierre Pronchery  */
rsa_verify(void * vprsactx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)1165e7be843bSPierre Pronchery static int rsa_verify(void *vprsactx,
1166e7be843bSPierre Pronchery                       const unsigned char *sig, size_t siglen,
1167e7be843bSPierre Pronchery                       const unsigned char *tbs, size_t tbslen)
1168b077aed3SPierre Pronchery {
1169b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1170b077aed3SPierre Pronchery 
1171e7be843bSPierre Pronchery     if (!ossl_prov_is_running() || prsactx == NULL)
1172b077aed3SPierre Pronchery         return 0;
1173e7be843bSPierre Pronchery     if (!prsactx->flag_allow_oneshot) {
1174e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER);
1175e7be843bSPierre Pronchery         return 0;
1176e7be843bSPierre Pronchery     }
1177b077aed3SPierre Pronchery 
1178e7be843bSPierre Pronchery     if (prsactx->operation == EVP_PKEY_OP_VERIFYMSG)
1179e7be843bSPierre Pronchery         return rsa_verify_set_sig(prsactx, sig, siglen)
1180e7be843bSPierre Pronchery             && rsa_signverify_message_update(prsactx, tbs, tbslen)
1181e7be843bSPierre Pronchery             && rsa_verify_message_final(prsactx);
1182e7be843bSPierre Pronchery     return rsa_verify_directly(prsactx, sig, siglen, tbs, tbslen);
1183e7be843bSPierre Pronchery }
1184e7be843bSPierre Pronchery 
1185e7be843bSPierre Pronchery /* DigestSign/DigestVerify wrappers */
1186e7be843bSPierre Pronchery 
rsa_digest_signverify_init(void * vprsactx,const char * mdname,void * vrsa,const OSSL_PARAM params[],int operation,const char * desc)1187e7be843bSPierre Pronchery static int rsa_digest_signverify_init(void *vprsactx, const char *mdname,
1188e7be843bSPierre Pronchery                                       void *vrsa, const OSSL_PARAM params[],
1189e7be843bSPierre Pronchery                                       int operation, const char *desc)
1190e7be843bSPierre Pronchery {
1191e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1192e7be843bSPierre Pronchery 
1193e7be843bSPierre Pronchery #ifdef FIPS_MODULE
1194e7be843bSPierre Pronchery     if (prsactx != NULL)
1195e7be843bSPierre Pronchery         prsactx->verify_message = 1;
1196e7be843bSPierre Pronchery #endif
1197e7be843bSPierre Pronchery 
1198e7be843bSPierre Pronchery     if (!rsa_signverify_init(prsactx, vrsa, rsa_set_ctx_params, params,
1199e7be843bSPierre Pronchery                              operation, desc))
1200b077aed3SPierre Pronchery         return 0;
1201b077aed3SPierre Pronchery 
1202b077aed3SPierre Pronchery     if (mdname != NULL
1203b077aed3SPierre Pronchery         /* was rsa_setup_md already called in rsa_signverify_init()? */
1204b077aed3SPierre Pronchery         && (mdname[0] == '\0' || OPENSSL_strcasecmp(prsactx->mdname, mdname) != 0)
1205e7be843bSPierre Pronchery         && !rsa_setup_md(prsactx, mdname, prsactx->propq, desc))
1206b077aed3SPierre Pronchery         return 0;
1207b077aed3SPierre Pronchery 
1208b077aed3SPierre Pronchery     prsactx->flag_allow_md = 0;
1209b077aed3SPierre Pronchery 
1210b077aed3SPierre Pronchery     if (prsactx->mdctx == NULL) {
1211b077aed3SPierre Pronchery         prsactx->mdctx = EVP_MD_CTX_new();
1212b077aed3SPierre Pronchery         if (prsactx->mdctx == NULL)
1213b077aed3SPierre Pronchery             goto error;
1214b077aed3SPierre Pronchery     }
1215b077aed3SPierre Pronchery 
1216b077aed3SPierre Pronchery     if (!EVP_DigestInit_ex2(prsactx->mdctx, prsactx->md, params))
1217b077aed3SPierre Pronchery         goto error;
1218b077aed3SPierre Pronchery 
1219b077aed3SPierre Pronchery     return 1;
1220b077aed3SPierre Pronchery 
1221b077aed3SPierre Pronchery  error:
1222b077aed3SPierre Pronchery     EVP_MD_CTX_free(prsactx->mdctx);
1223b077aed3SPierre Pronchery     prsactx->mdctx = NULL;
1224b077aed3SPierre Pronchery     return 0;
1225b077aed3SPierre Pronchery }
1226b077aed3SPierre Pronchery 
rsa_digest_sign_init(void * vprsactx,const char * mdname,void * vrsa,const OSSL_PARAM params[])1227b077aed3SPierre Pronchery static int rsa_digest_sign_init(void *vprsactx, const char *mdname,
1228b077aed3SPierre Pronchery                                 void *vrsa, const OSSL_PARAM params[])
1229b077aed3SPierre Pronchery {
1230b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
1231b077aed3SPierre Pronchery         return 0;
1232b077aed3SPierre Pronchery     return rsa_digest_signverify_init(vprsactx, mdname, vrsa,
1233e7be843bSPierre Pronchery                                       params, EVP_PKEY_OP_SIGNMSG,
1234e7be843bSPierre Pronchery                                       "RSA Digest Sign Init");
1235e7be843bSPierre Pronchery }
1236e7be843bSPierre Pronchery 
rsa_digest_sign_update(void * vprsactx,const unsigned char * data,size_t datalen)1237e7be843bSPierre Pronchery static int rsa_digest_sign_update(void *vprsactx, const unsigned char *data,
1238e7be843bSPierre Pronchery                                   size_t datalen)
1239e7be843bSPierre Pronchery {
1240e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1241e7be843bSPierre Pronchery 
1242e7be843bSPierre Pronchery     if (prsactx == NULL)
1243e7be843bSPierre Pronchery         return 0;
1244e7be843bSPierre Pronchery     /* Sigalg implementations shouldn't do digest_sign */
1245e7be843bSPierre Pronchery     if (prsactx->flag_sigalg)
1246e7be843bSPierre Pronchery         return 0;
1247e7be843bSPierre Pronchery 
1248e7be843bSPierre Pronchery     return rsa_signverify_message_update(prsactx, data, datalen);
1249b077aed3SPierre Pronchery }
1250b077aed3SPierre Pronchery 
rsa_digest_sign_final(void * vprsactx,unsigned char * sig,size_t * siglen,size_t sigsize)1251b077aed3SPierre Pronchery static int rsa_digest_sign_final(void *vprsactx, unsigned char *sig,
1252b077aed3SPierre Pronchery                                  size_t *siglen, size_t sigsize)
1253b077aed3SPierre Pronchery {
1254b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1255e7be843bSPierre Pronchery     int ok = 0;
1256b077aed3SPierre Pronchery 
1257e7be843bSPierre Pronchery     if (prsactx == NULL)
1258b077aed3SPierre Pronchery         return 0;
1259e7be843bSPierre Pronchery     /* Sigalg implementations shouldn't do digest_sign */
1260e7be843bSPierre Pronchery     if (prsactx->flag_sigalg)
1261e7be843bSPierre Pronchery         return 0;
1262e7be843bSPierre Pronchery 
1263e7be843bSPierre Pronchery     if (rsa_sign_message_final(prsactx, sig, siglen, sigsize))
1264e7be843bSPierre Pronchery         ok = 1;
1265e7be843bSPierre Pronchery 
1266b077aed3SPierre Pronchery     prsactx->flag_allow_md = 1;
1267b077aed3SPierre Pronchery 
1268e7be843bSPierre Pronchery     return ok;
1269b077aed3SPierre Pronchery }
1270b077aed3SPierre Pronchery 
rsa_digest_verify_init(void * vprsactx,const char * mdname,void * vrsa,const OSSL_PARAM params[])1271b077aed3SPierre Pronchery static int rsa_digest_verify_init(void *vprsactx, const char *mdname,
1272b077aed3SPierre Pronchery                                   void *vrsa, const OSSL_PARAM params[])
1273b077aed3SPierre Pronchery {
1274b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
1275b077aed3SPierre Pronchery         return 0;
1276b077aed3SPierre Pronchery     return rsa_digest_signverify_init(vprsactx, mdname, vrsa,
1277e7be843bSPierre Pronchery                                       params, EVP_PKEY_OP_VERIFYMSG,
1278e7be843bSPierre Pronchery                                       "RSA Digest Verify Init");
1279e7be843bSPierre Pronchery }
1280e7be843bSPierre Pronchery 
rsa_digest_verify_update(void * vprsactx,const unsigned char * data,size_t datalen)1281e7be843bSPierre Pronchery static int rsa_digest_verify_update(void *vprsactx, const unsigned char *data,
1282e7be843bSPierre Pronchery                                     size_t datalen)
1283e7be843bSPierre Pronchery {
1284e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1285e7be843bSPierre Pronchery 
1286e7be843bSPierre Pronchery     if (prsactx == NULL)
1287e7be843bSPierre Pronchery         return 0;
1288e7be843bSPierre Pronchery     /* Sigalg implementations shouldn't do digest_sign */
1289e7be843bSPierre Pronchery     if (prsactx->flag_sigalg)
1290e7be843bSPierre Pronchery         return 0;
1291e7be843bSPierre Pronchery 
1292e7be843bSPierre Pronchery     return rsa_signverify_message_update(prsactx, data, datalen);
1293b077aed3SPierre Pronchery }
1294b077aed3SPierre Pronchery 
rsa_digest_verify_final(void * vprsactx,const unsigned char * sig,size_t siglen)1295b077aed3SPierre Pronchery int rsa_digest_verify_final(void *vprsactx, const unsigned char *sig,
1296b077aed3SPierre Pronchery                             size_t siglen)
1297b077aed3SPierre Pronchery {
1298b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1299e7be843bSPierre Pronchery     int ok = 0;
1300b077aed3SPierre Pronchery 
1301b077aed3SPierre Pronchery     if (prsactx == NULL)
1302b077aed3SPierre Pronchery         return 0;
1303e7be843bSPierre Pronchery     /* Sigalg implementations shouldn't do digest_verify */
1304e7be843bSPierre Pronchery     if (prsactx->flag_sigalg)
1305e7be843bSPierre Pronchery         return 0;
1306e7be843bSPierre Pronchery 
1307e7be843bSPierre Pronchery     if (rsa_verify_set_sig(prsactx, sig, siglen)
1308e7be843bSPierre Pronchery         && rsa_verify_message_final(vprsactx))
1309e7be843bSPierre Pronchery         ok = 1;
1310e7be843bSPierre Pronchery 
1311b077aed3SPierre Pronchery     prsactx->flag_allow_md = 1;
1312b077aed3SPierre Pronchery 
1313e7be843bSPierre Pronchery     return ok;
1314b077aed3SPierre Pronchery }
1315b077aed3SPierre Pronchery 
rsa_freectx(void * vprsactx)1316b077aed3SPierre Pronchery static void rsa_freectx(void *vprsactx)
1317b077aed3SPierre Pronchery {
1318b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1319b077aed3SPierre Pronchery 
1320b077aed3SPierre Pronchery     if (prsactx == NULL)
1321b077aed3SPierre Pronchery         return;
1322b077aed3SPierre Pronchery 
1323b077aed3SPierre Pronchery     EVP_MD_CTX_free(prsactx->mdctx);
1324b077aed3SPierre Pronchery     EVP_MD_free(prsactx->md);
1325b077aed3SPierre Pronchery     EVP_MD_free(prsactx->mgf1_md);
1326e7be843bSPierre Pronchery     OPENSSL_free(prsactx->sig);
1327b077aed3SPierre Pronchery     OPENSSL_free(prsactx->propq);
1328b077aed3SPierre Pronchery     free_tbuf(prsactx);
1329b077aed3SPierre Pronchery     RSA_free(prsactx->rsa);
1330b077aed3SPierre Pronchery 
1331b077aed3SPierre Pronchery     OPENSSL_clear_free(prsactx, sizeof(*prsactx));
1332b077aed3SPierre Pronchery }
1333b077aed3SPierre Pronchery 
rsa_dupctx(void * vprsactx)1334b077aed3SPierre Pronchery static void *rsa_dupctx(void *vprsactx)
1335b077aed3SPierre Pronchery {
1336b077aed3SPierre Pronchery     PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx;
1337b077aed3SPierre Pronchery     PROV_RSA_CTX *dstctx;
1338b077aed3SPierre Pronchery 
1339b077aed3SPierre Pronchery     if (!ossl_prov_is_running())
1340b077aed3SPierre Pronchery         return NULL;
1341b077aed3SPierre Pronchery 
1342b077aed3SPierre Pronchery     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
1343e7be843bSPierre Pronchery     if (dstctx == NULL)
1344b077aed3SPierre Pronchery         return NULL;
1345b077aed3SPierre Pronchery 
1346b077aed3SPierre Pronchery     *dstctx = *srcctx;
1347b077aed3SPierre Pronchery     dstctx->rsa = NULL;
1348b077aed3SPierre Pronchery     dstctx->md = NULL;
1349e0c4386eSCy Schubert     dstctx->mgf1_md = NULL;
1350b077aed3SPierre Pronchery     dstctx->mdctx = NULL;
1351b077aed3SPierre Pronchery     dstctx->tbuf = NULL;
1352b077aed3SPierre Pronchery     dstctx->propq = NULL;
1353b077aed3SPierre Pronchery 
1354b077aed3SPierre Pronchery     if (srcctx->rsa != NULL && !RSA_up_ref(srcctx->rsa))
1355b077aed3SPierre Pronchery         goto err;
1356b077aed3SPierre Pronchery     dstctx->rsa = srcctx->rsa;
1357b077aed3SPierre Pronchery 
1358b077aed3SPierre Pronchery     if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
1359b077aed3SPierre Pronchery         goto err;
1360b077aed3SPierre Pronchery     dstctx->md = srcctx->md;
1361b077aed3SPierre Pronchery 
1362b077aed3SPierre Pronchery     if (srcctx->mgf1_md != NULL && !EVP_MD_up_ref(srcctx->mgf1_md))
1363b077aed3SPierre Pronchery         goto err;
1364b077aed3SPierre Pronchery     dstctx->mgf1_md = srcctx->mgf1_md;
1365b077aed3SPierre Pronchery 
1366b077aed3SPierre Pronchery     if (srcctx->mdctx != NULL) {
1367b077aed3SPierre Pronchery         dstctx->mdctx = EVP_MD_CTX_new();
1368b077aed3SPierre Pronchery         if (dstctx->mdctx == NULL
1369b077aed3SPierre Pronchery                 || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
1370b077aed3SPierre Pronchery             goto err;
1371b077aed3SPierre Pronchery     }
1372b077aed3SPierre Pronchery 
1373b077aed3SPierre Pronchery     if (srcctx->propq != NULL) {
1374b077aed3SPierre Pronchery         dstctx->propq = OPENSSL_strdup(srcctx->propq);
1375b077aed3SPierre Pronchery         if (dstctx->propq == NULL)
1376b077aed3SPierre Pronchery             goto err;
1377b077aed3SPierre Pronchery     }
1378b077aed3SPierre Pronchery 
1379b077aed3SPierre Pronchery     return dstctx;
1380b077aed3SPierre Pronchery  err:
1381b077aed3SPierre Pronchery     rsa_freectx(dstctx);
1382b077aed3SPierre Pronchery     return NULL;
1383b077aed3SPierre Pronchery }
1384b077aed3SPierre Pronchery 
rsa_get_ctx_params(void * vprsactx,OSSL_PARAM * params)1385b077aed3SPierre Pronchery static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
1386b077aed3SPierre Pronchery {
1387b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1388b077aed3SPierre Pronchery     OSSL_PARAM *p;
1389b077aed3SPierre Pronchery 
1390b077aed3SPierre Pronchery     if (prsactx == NULL)
1391b077aed3SPierre Pronchery         return 0;
1392b077aed3SPierre Pronchery 
1393b077aed3SPierre Pronchery     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
1394b077aed3SPierre Pronchery     if (p != NULL) {
1395b077aed3SPierre Pronchery         /* The Algorithm Identifier of the combined signature algorithm */
1396b077aed3SPierre Pronchery         unsigned char aid_buf[128];
1397b077aed3SPierre Pronchery         unsigned char *aid;
1398b077aed3SPierre Pronchery         size_t  aid_len;
1399b077aed3SPierre Pronchery 
1400b077aed3SPierre Pronchery         aid = rsa_generate_signature_aid(prsactx, aid_buf,
1401b077aed3SPierre Pronchery                                          sizeof(aid_buf), &aid_len);
1402b077aed3SPierre Pronchery         if (aid == NULL || !OSSL_PARAM_set_octet_string(p, aid, aid_len))
1403b077aed3SPierre Pronchery             return 0;
1404b077aed3SPierre Pronchery     }
1405b077aed3SPierre Pronchery 
1406b077aed3SPierre Pronchery     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PAD_MODE);
1407b077aed3SPierre Pronchery     if (p != NULL)
1408b077aed3SPierre Pronchery         switch (p->data_type) {
1409b077aed3SPierre Pronchery         case OSSL_PARAM_INTEGER:
1410b077aed3SPierre Pronchery             if (!OSSL_PARAM_set_int(p, prsactx->pad_mode))
1411b077aed3SPierre Pronchery                 return 0;
1412b077aed3SPierre Pronchery             break;
1413b077aed3SPierre Pronchery         case OSSL_PARAM_UTF8_STRING:
1414b077aed3SPierre Pronchery             {
1415b077aed3SPierre Pronchery                 int i;
1416b077aed3SPierre Pronchery                 const char *word = NULL;
1417b077aed3SPierre Pronchery 
1418b077aed3SPierre Pronchery                 for (i = 0; padding_item[i].id != 0; i++) {
1419b077aed3SPierre Pronchery                     if (prsactx->pad_mode == (int)padding_item[i].id) {
1420b077aed3SPierre Pronchery                         word = padding_item[i].ptr;
1421b077aed3SPierre Pronchery                         break;
1422b077aed3SPierre Pronchery                     }
1423b077aed3SPierre Pronchery                 }
1424b077aed3SPierre Pronchery 
1425b077aed3SPierre Pronchery                 if (word != NULL) {
1426b077aed3SPierre Pronchery                     if (!OSSL_PARAM_set_utf8_string(p, word))
1427b077aed3SPierre Pronchery                         return 0;
1428b077aed3SPierre Pronchery                 } else {
1429b077aed3SPierre Pronchery                     ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
1430b077aed3SPierre Pronchery                 }
1431b077aed3SPierre Pronchery             }
1432b077aed3SPierre Pronchery             break;
1433b077aed3SPierre Pronchery         default:
1434b077aed3SPierre Pronchery             return 0;
1435b077aed3SPierre Pronchery         }
1436b077aed3SPierre Pronchery 
1437b077aed3SPierre Pronchery     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
1438b077aed3SPierre Pronchery     if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->mdname))
1439b077aed3SPierre Pronchery         return 0;
1440b077aed3SPierre Pronchery 
1441b077aed3SPierre Pronchery     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST);
1442b077aed3SPierre Pronchery     if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->mgf1_mdname))
1443b077aed3SPierre Pronchery         return 0;
1444b077aed3SPierre Pronchery 
1445b077aed3SPierre Pronchery     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN);
1446b077aed3SPierre Pronchery     if (p != NULL) {
1447b077aed3SPierre Pronchery         if (p->data_type == OSSL_PARAM_INTEGER) {
1448b077aed3SPierre Pronchery             if (!OSSL_PARAM_set_int(p, prsactx->saltlen))
1449b077aed3SPierre Pronchery                 return 0;
1450b077aed3SPierre Pronchery         } else if (p->data_type == OSSL_PARAM_UTF8_STRING) {
1451b077aed3SPierre Pronchery             const char *value = NULL;
1452b077aed3SPierre Pronchery 
1453b077aed3SPierre Pronchery             switch (prsactx->saltlen) {
1454b077aed3SPierre Pronchery             case RSA_PSS_SALTLEN_DIGEST:
1455b077aed3SPierre Pronchery                 value = OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST;
1456b077aed3SPierre Pronchery                 break;
1457b077aed3SPierre Pronchery             case RSA_PSS_SALTLEN_MAX:
1458b077aed3SPierre Pronchery                 value = OSSL_PKEY_RSA_PSS_SALT_LEN_MAX;
1459b077aed3SPierre Pronchery                 break;
1460b077aed3SPierre Pronchery             case RSA_PSS_SALTLEN_AUTO:
1461b077aed3SPierre Pronchery                 value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO;
1462b077aed3SPierre Pronchery                 break;
1463e7be843bSPierre Pronchery             case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
1464e7be843bSPierre Pronchery                 value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX;
1465e7be843bSPierre Pronchery                 break;
1466b077aed3SPierre Pronchery             default:
1467b077aed3SPierre Pronchery                 {
1468b077aed3SPierre Pronchery                     int len = BIO_snprintf(p->data, p->data_size, "%d",
1469b077aed3SPierre Pronchery                                            prsactx->saltlen);
1470b077aed3SPierre Pronchery 
1471b077aed3SPierre Pronchery                     if (len <= 0)
1472b077aed3SPierre Pronchery                         return 0;
1473b077aed3SPierre Pronchery                     p->return_size = len;
1474b077aed3SPierre Pronchery                     break;
1475b077aed3SPierre Pronchery                 }
1476b077aed3SPierre Pronchery             }
1477b077aed3SPierre Pronchery             if (value != NULL
1478b077aed3SPierre Pronchery                 && !OSSL_PARAM_set_utf8_string(p, value))
1479b077aed3SPierre Pronchery                 return 0;
1480b077aed3SPierre Pronchery         }
1481b077aed3SPierre Pronchery     }
1482b077aed3SPierre Pronchery 
1483e7be843bSPierre Pronchery #ifdef FIPS_MODULE
1484e7be843bSPierre Pronchery     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE);
1485e7be843bSPierre Pronchery     if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->verify_message))
1486e7be843bSPierre Pronchery         return 0;
1487e7be843bSPierre Pronchery #endif
1488e7be843bSPierre Pronchery 
1489e7be843bSPierre Pronchery     if (!OSSL_FIPS_IND_GET_CTX_PARAM(prsactx, params))
1490e7be843bSPierre Pronchery         return 0;
1491b077aed3SPierre Pronchery     return 1;
1492b077aed3SPierre Pronchery }
1493b077aed3SPierre Pronchery 
1494b077aed3SPierre Pronchery static const OSSL_PARAM known_gettable_ctx_params[] = {
1495b077aed3SPierre Pronchery     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
1496b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0),
1497b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
1498b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0),
1499b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
1500e7be843bSPierre Pronchery #ifdef FIPS_MODULE
1501e7be843bSPierre Pronchery     OSSL_PARAM_uint(OSSL_SIGNATURE_PARAM_FIPS_VERIFY_MESSAGE, NULL),
1502e7be843bSPierre Pronchery #endif
1503e7be843bSPierre Pronchery     OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
1504b077aed3SPierre Pronchery     OSSL_PARAM_END
1505b077aed3SPierre Pronchery };
1506b077aed3SPierre Pronchery 
rsa_gettable_ctx_params(ossl_unused void * vprsactx,ossl_unused void * provctx)1507b077aed3SPierre Pronchery static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx,
1508b077aed3SPierre Pronchery                                                  ossl_unused void *provctx)
1509b077aed3SPierre Pronchery {
1510b077aed3SPierre Pronchery     return known_gettable_ctx_params;
1511b077aed3SPierre Pronchery }
1512b077aed3SPierre Pronchery 
1513e7be843bSPierre Pronchery #ifdef FIPS_MODULE
rsa_x931_padding_allowed(PROV_RSA_CTX * ctx)1514e7be843bSPierre Pronchery static int rsa_x931_padding_allowed(PROV_RSA_CTX *ctx)
1515e7be843bSPierre Pronchery {
1516e7be843bSPierre Pronchery     int approved = ((ctx->operation & EVP_PKEY_OP_SIGN) == 0);
1517e7be843bSPierre Pronchery 
1518e7be843bSPierre Pronchery     if (!approved) {
1519e7be843bSPierre Pronchery         if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
1520e7be843bSPierre Pronchery                                          ctx->libctx,
1521e7be843bSPierre Pronchery                                          "RSA Sign set ctx", "X931 Padding",
1522e7be843bSPierre Pronchery                                          ossl_fips_config_rsa_sign_x931_disallowed)) {
1523e7be843bSPierre Pronchery             ERR_raise(ERR_LIB_PROV,
1524e7be843bSPierre Pronchery                       PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
1525e7be843bSPierre Pronchery             return 0;
1526e7be843bSPierre Pronchery         }
1527e7be843bSPierre Pronchery     }
1528e7be843bSPierre Pronchery     return 1;
1529e7be843bSPierre Pronchery }
1530e7be843bSPierre Pronchery #endif
1531e7be843bSPierre Pronchery 
rsa_set_ctx_params(void * vprsactx,const OSSL_PARAM params[])1532b077aed3SPierre Pronchery static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
1533b077aed3SPierre Pronchery {
1534b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1535b077aed3SPierre Pronchery     const OSSL_PARAM *p;
1536b077aed3SPierre Pronchery     int pad_mode;
1537b077aed3SPierre Pronchery     int saltlen;
1538b077aed3SPierre Pronchery     char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = NULL;
1539b077aed3SPierre Pronchery     char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = NULL;
1540b077aed3SPierre Pronchery     char mgf1mdname[OSSL_MAX_NAME_SIZE] = "", *pmgf1mdname = NULL;
1541b077aed3SPierre Pronchery     char mgf1mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmgf1mdprops = NULL;
1542b077aed3SPierre Pronchery 
1543b077aed3SPierre Pronchery     if (prsactx == NULL)
1544b077aed3SPierre Pronchery         return 0;
1545e7be843bSPierre Pronchery     if (ossl_param_is_empty(params))
1546b077aed3SPierre Pronchery         return 1;
1547b077aed3SPierre Pronchery 
1548e7be843bSPierre Pronchery     if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE0, params,
1549e7be843bSPierre Pronchery                                      OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK))
1550e7be843bSPierre Pronchery         return 0;
1551e7be843bSPierre Pronchery 
1552e7be843bSPierre Pronchery     if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE1, params,
1553e7be843bSPierre Pronchery                                      OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK))
1554e7be843bSPierre Pronchery         return 0;
1555e7be843bSPierre Pronchery 
1556e7be843bSPierre Pronchery     if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE2, params,
1557e7be843bSPierre Pronchery                                      OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK))
1558e7be843bSPierre Pronchery         return 0;
1559e7be843bSPierre Pronchery 
1560e7be843bSPierre Pronchery     if (!OSSL_FIPS_IND_SET_CTX_PARAM(prsactx, OSSL_FIPS_IND_SETTABLE3, params,
1561e7be843bSPierre Pronchery                                      OSSL_SIGNATURE_PARAM_FIPS_RSA_PSS_SALTLEN_CHECK))
1562e7be843bSPierre Pronchery         return 0;
1563e7be843bSPierre Pronchery 
1564b077aed3SPierre Pronchery     pad_mode = prsactx->pad_mode;
1565b077aed3SPierre Pronchery     saltlen = prsactx->saltlen;
1566b077aed3SPierre Pronchery 
1567b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
1568b077aed3SPierre Pronchery     if (p != NULL) {
1569b077aed3SPierre Pronchery         const OSSL_PARAM *propsp =
1570b077aed3SPierre Pronchery             OSSL_PARAM_locate_const(params,
1571b077aed3SPierre Pronchery                                     OSSL_SIGNATURE_PARAM_PROPERTIES);
1572b077aed3SPierre Pronchery 
1573b077aed3SPierre Pronchery         pmdname = mdname;
1574b077aed3SPierre Pronchery         if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))
1575b077aed3SPierre Pronchery             return 0;
1576b077aed3SPierre Pronchery 
1577b077aed3SPierre Pronchery         if (propsp != NULL) {
1578b077aed3SPierre Pronchery             pmdprops = mdprops;
1579b077aed3SPierre Pronchery             if (!OSSL_PARAM_get_utf8_string(propsp,
1580b077aed3SPierre Pronchery                                             &pmdprops, sizeof(mdprops)))
1581b077aed3SPierre Pronchery                 return 0;
1582b077aed3SPierre Pronchery         }
1583b077aed3SPierre Pronchery     }
1584b077aed3SPierre Pronchery 
1585b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE);
1586b077aed3SPierre Pronchery     if (p != NULL) {
1587b077aed3SPierre Pronchery         const char *err_extra_text = NULL;
1588b077aed3SPierre Pronchery 
1589b077aed3SPierre Pronchery         switch (p->data_type) {
1590b077aed3SPierre Pronchery         case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */
1591b077aed3SPierre Pronchery             if (!OSSL_PARAM_get_int(p, &pad_mode))
1592b077aed3SPierre Pronchery                 return 0;
1593b077aed3SPierre Pronchery             break;
1594b077aed3SPierre Pronchery         case OSSL_PARAM_UTF8_STRING:
1595b077aed3SPierre Pronchery             {
1596b077aed3SPierre Pronchery                 int i;
1597b077aed3SPierre Pronchery 
1598b077aed3SPierre Pronchery                 if (p->data == NULL)
1599b077aed3SPierre Pronchery                     return 0;
1600b077aed3SPierre Pronchery 
1601b077aed3SPierre Pronchery                 for (i = 0; padding_item[i].id != 0; i++) {
1602b077aed3SPierre Pronchery                     if (strcmp(p->data, padding_item[i].ptr) == 0) {
1603b077aed3SPierre Pronchery                         pad_mode = padding_item[i].id;
1604b077aed3SPierre Pronchery                         break;
1605b077aed3SPierre Pronchery                     }
1606b077aed3SPierre Pronchery                 }
1607b077aed3SPierre Pronchery             }
1608b077aed3SPierre Pronchery             break;
1609b077aed3SPierre Pronchery         default:
1610b077aed3SPierre Pronchery             return 0;
1611b077aed3SPierre Pronchery         }
1612b077aed3SPierre Pronchery 
1613b077aed3SPierre Pronchery         switch (pad_mode) {
1614b077aed3SPierre Pronchery         case RSA_PKCS1_OAEP_PADDING:
1615b077aed3SPierre Pronchery             /*
1616b077aed3SPierre Pronchery              * OAEP padding is for asymmetric cipher only so is not compatible
1617b077aed3SPierre Pronchery              * with signature use.
1618b077aed3SPierre Pronchery              */
1619b077aed3SPierre Pronchery             err_extra_text = "OAEP padding not allowed for signing / verifying";
1620b077aed3SPierre Pronchery             goto bad_pad;
1621b077aed3SPierre Pronchery         case RSA_PKCS1_PSS_PADDING:
1622b077aed3SPierre Pronchery             if ((prsactx->operation
1623e7be843bSPierre Pronchery                  & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_SIGNMSG
1624e7be843bSPierre Pronchery                     | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYMSG)) == 0) {
1625b077aed3SPierre Pronchery                 err_extra_text =
1626b077aed3SPierre Pronchery                     "PSS padding only allowed for sign and verify operations";
1627b077aed3SPierre Pronchery                 goto bad_pad;
1628b077aed3SPierre Pronchery             }
1629b077aed3SPierre Pronchery             break;
1630b077aed3SPierre Pronchery         case RSA_PKCS1_PADDING:
1631b077aed3SPierre Pronchery             err_extra_text = "PKCS#1 padding not allowed with RSA-PSS";
1632b077aed3SPierre Pronchery             goto cont;
1633b077aed3SPierre Pronchery         case RSA_NO_PADDING:
1634b077aed3SPierre Pronchery             err_extra_text = "No padding not allowed with RSA-PSS";
1635b077aed3SPierre Pronchery             goto cont;
1636b077aed3SPierre Pronchery         case RSA_X931_PADDING:
1637e7be843bSPierre Pronchery #ifdef FIPS_MODULE
1638e7be843bSPierre Pronchery             /* X9.31 only allows sizes of 1024 + 256 * s (bits) */
1639e7be843bSPierre Pronchery             if ((RSA_bits(prsactx->rsa) & 0xFF) != 0) {
1640e7be843bSPierre Pronchery                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
1641e7be843bSPierre Pronchery                 return 0;
1642e7be843bSPierre Pronchery             }
1643e7be843bSPierre Pronchery             /* RSA Signing with X9.31 padding is not allowed in FIPS 140-3 */
1644e7be843bSPierre Pronchery             if (!rsa_x931_padding_allowed(prsactx))
1645e7be843bSPierre Pronchery                 return 0;
1646e7be843bSPierre Pronchery #endif
1647b077aed3SPierre Pronchery             err_extra_text = "X.931 padding not allowed with RSA-PSS";
1648b077aed3SPierre Pronchery         cont:
1649b077aed3SPierre Pronchery             if (RSA_test_flags(prsactx->rsa,
1650b077aed3SPierre Pronchery                                RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSA)
1651b077aed3SPierre Pronchery                 break;
1652b077aed3SPierre Pronchery             /* FALLTHRU */
1653b077aed3SPierre Pronchery         default:
1654b077aed3SPierre Pronchery         bad_pad:
1655b077aed3SPierre Pronchery             if (err_extra_text == NULL)
1656b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PROV,
1657b077aed3SPierre Pronchery                           PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
1658b077aed3SPierre Pronchery             else
1659b077aed3SPierre Pronchery                 ERR_raise_data(ERR_LIB_PROV,
1660b077aed3SPierre Pronchery                                PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE,
1661b077aed3SPierre Pronchery                                err_extra_text);
1662b077aed3SPierre Pronchery             return 0;
1663b077aed3SPierre Pronchery         }
1664b077aed3SPierre Pronchery     }
1665b077aed3SPierre Pronchery 
1666b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN);
1667b077aed3SPierre Pronchery     if (p != NULL) {
1668b077aed3SPierre Pronchery         if (pad_mode != RSA_PKCS1_PSS_PADDING) {
1669b077aed3SPierre Pronchery             ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED,
1670b077aed3SPierre Pronchery                            "PSS saltlen can only be specified if "
1671b077aed3SPierre Pronchery                            "PSS padding has been specified first");
1672b077aed3SPierre Pronchery             return 0;
1673b077aed3SPierre Pronchery         }
1674b077aed3SPierre Pronchery 
1675b077aed3SPierre Pronchery         switch (p->data_type) {
1676b077aed3SPierre Pronchery         case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */
1677b077aed3SPierre Pronchery             if (!OSSL_PARAM_get_int(p, &saltlen))
1678b077aed3SPierre Pronchery                 return 0;
1679b077aed3SPierre Pronchery             break;
1680b077aed3SPierre Pronchery         case OSSL_PARAM_UTF8_STRING:
1681b077aed3SPierre Pronchery             if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST) == 0)
1682b077aed3SPierre Pronchery                 saltlen = RSA_PSS_SALTLEN_DIGEST;
1683b077aed3SPierre Pronchery             else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_MAX) == 0)
1684b077aed3SPierre Pronchery                 saltlen = RSA_PSS_SALTLEN_MAX;
1685b077aed3SPierre Pronchery             else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
1686b077aed3SPierre Pronchery                 saltlen = RSA_PSS_SALTLEN_AUTO;
1687e7be843bSPierre Pronchery             else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
1688e7be843bSPierre Pronchery                 saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
1689b077aed3SPierre Pronchery             else
1690b077aed3SPierre Pronchery                 saltlen = atoi(p->data);
1691b077aed3SPierre Pronchery             break;
1692b077aed3SPierre Pronchery         default:
1693b077aed3SPierre Pronchery             return 0;
1694b077aed3SPierre Pronchery         }
1695b077aed3SPierre Pronchery 
1696b077aed3SPierre Pronchery         /*
1697e7be843bSPierre Pronchery          * RSA_PSS_SALTLEN_AUTO_DIGEST_MAX seems curiously named in this check.
1698e7be843bSPierre Pronchery          * Contrary to what it's name suggests, it's the currently lowest
1699e7be843bSPierre Pronchery          * saltlen number possible.
1700b077aed3SPierre Pronchery          */
1701e7be843bSPierre Pronchery         if (saltlen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
1702b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
1703b077aed3SPierre Pronchery             return 0;
1704b077aed3SPierre Pronchery         }
1705b077aed3SPierre Pronchery 
1706b077aed3SPierre Pronchery         if (rsa_pss_restricted(prsactx)) {
1707b077aed3SPierre Pronchery             switch (saltlen) {
1708b077aed3SPierre Pronchery             case RSA_PSS_SALTLEN_AUTO:
1709e7be843bSPierre Pronchery             case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
1710e7be843bSPierre Pronchery                 if ((prsactx->operation
1711e7be843bSPierre Pronchery                      & (EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYMSG)) == 0) {
1712b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH,
1713b077aed3SPierre Pronchery                                    "Cannot use autodetected salt length");
1714b077aed3SPierre Pronchery                     return 0;
1715b077aed3SPierre Pronchery                 }
1716b077aed3SPierre Pronchery                 break;
1717b077aed3SPierre Pronchery             case RSA_PSS_SALTLEN_DIGEST:
1718b077aed3SPierre Pronchery                 if (prsactx->min_saltlen > EVP_MD_get_size(prsactx->md)) {
1719b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV,
1720b077aed3SPierre Pronchery                                    PROV_R_PSS_SALTLEN_TOO_SMALL,
1721b077aed3SPierre Pronchery                                    "Should be more than %d, but would be "
1722b077aed3SPierre Pronchery                                    "set to match digest size (%d)",
1723b077aed3SPierre Pronchery                                    prsactx->min_saltlen,
1724b077aed3SPierre Pronchery                                    EVP_MD_get_size(prsactx->md));
1725b077aed3SPierre Pronchery                     return 0;
1726b077aed3SPierre Pronchery                 }
1727b077aed3SPierre Pronchery                 break;
1728b077aed3SPierre Pronchery             default:
1729b077aed3SPierre Pronchery                 if (saltlen >= 0 && saltlen < prsactx->min_saltlen) {
1730b077aed3SPierre Pronchery                     ERR_raise_data(ERR_LIB_PROV,
1731b077aed3SPierre Pronchery                                    PROV_R_PSS_SALTLEN_TOO_SMALL,
1732b077aed3SPierre Pronchery                                    "Should be more than %d, "
1733b077aed3SPierre Pronchery                                    "but would be set to %d",
1734b077aed3SPierre Pronchery                                    prsactx->min_saltlen, saltlen);
1735b077aed3SPierre Pronchery                     return 0;
1736b077aed3SPierre Pronchery                 }
1737b077aed3SPierre Pronchery             }
1738b077aed3SPierre Pronchery         }
1739b077aed3SPierre Pronchery     }
1740b077aed3SPierre Pronchery 
1741b077aed3SPierre Pronchery     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST);
1742b077aed3SPierre Pronchery     if (p != NULL) {
1743b077aed3SPierre Pronchery         const OSSL_PARAM *propsp =
1744b077aed3SPierre Pronchery             OSSL_PARAM_locate_const(params,
1745b077aed3SPierre Pronchery                                     OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES);
1746b077aed3SPierre Pronchery 
1747b077aed3SPierre Pronchery         pmgf1mdname = mgf1mdname;
1748b077aed3SPierre Pronchery         if (!OSSL_PARAM_get_utf8_string(p, &pmgf1mdname, sizeof(mgf1mdname)))
1749b077aed3SPierre Pronchery             return 0;
1750b077aed3SPierre Pronchery 
1751b077aed3SPierre Pronchery         if (propsp != NULL) {
1752b077aed3SPierre Pronchery             pmgf1mdprops = mgf1mdprops;
1753b077aed3SPierre Pronchery             if (!OSSL_PARAM_get_utf8_string(propsp,
1754b077aed3SPierre Pronchery                                             &pmgf1mdprops, sizeof(mgf1mdprops)))
1755b077aed3SPierre Pronchery                 return 0;
1756b077aed3SPierre Pronchery         }
1757b077aed3SPierre Pronchery 
1758b077aed3SPierre Pronchery         if (pad_mode != RSA_PKCS1_PSS_PADDING) {
1759b077aed3SPierre Pronchery             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MGF1_MD);
1760b077aed3SPierre Pronchery             return  0;
1761b077aed3SPierre Pronchery         }
1762b077aed3SPierre Pronchery     }
1763b077aed3SPierre Pronchery 
1764b077aed3SPierre Pronchery     prsactx->saltlen = saltlen;
1765b077aed3SPierre Pronchery     prsactx->pad_mode = pad_mode;
1766b077aed3SPierre Pronchery 
1767b077aed3SPierre Pronchery     if (prsactx->md == NULL && pmdname == NULL
1768b077aed3SPierre Pronchery         && pad_mode == RSA_PKCS1_PSS_PADDING)
1769b077aed3SPierre Pronchery         pmdname = RSA_DEFAULT_DIGEST_NAME;
1770b077aed3SPierre Pronchery 
1771b077aed3SPierre Pronchery     if (pmgf1mdname != NULL
1772b077aed3SPierre Pronchery         && !rsa_setup_mgf1_md(prsactx, pmgf1mdname, pmgf1mdprops))
1773b077aed3SPierre Pronchery         return 0;
1774b077aed3SPierre Pronchery 
1775b077aed3SPierre Pronchery     if (pmdname != NULL) {
1776e7be843bSPierre Pronchery         if (!rsa_setup_md(prsactx, pmdname, pmdprops, "RSA Sign Set Ctx"))
1777b077aed3SPierre Pronchery             return 0;
1778b077aed3SPierre Pronchery     } else {
1779b077aed3SPierre Pronchery         if (!rsa_check_padding(prsactx, NULL, NULL, prsactx->mdnid))
1780b077aed3SPierre Pronchery             return 0;
1781b077aed3SPierre Pronchery     }
1782b077aed3SPierre Pronchery     return 1;
1783b077aed3SPierre Pronchery }
1784b077aed3SPierre Pronchery 
1785b077aed3SPierre Pronchery static const OSSL_PARAM settable_ctx_params[] = {
1786b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
1787b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),
1788b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0),
1789b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0),
1790b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0),
1791b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
1792e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)
1793e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)
1794e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_RSA_PSS_SALTLEN_CHECK)
1795e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK)
1796b077aed3SPierre Pronchery     OSSL_PARAM_END
1797b077aed3SPierre Pronchery };
1798b077aed3SPierre Pronchery 
1799b077aed3SPierre Pronchery static const OSSL_PARAM settable_ctx_params_no_digest[] = {
1800b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0),
1801b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0),
1802b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0),
1803b077aed3SPierre Pronchery     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
1804e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_KEY_CHECK)
1805e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_DIGEST_CHECK)
1806e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_RSA_PSS_SALTLEN_CHECK)
1807e7be843bSPierre Pronchery     OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_SIGNATURE_PARAM_FIPS_SIGN_X931_PAD_CHECK)
1808b077aed3SPierre Pronchery     OSSL_PARAM_END
1809b077aed3SPierre Pronchery };
1810b077aed3SPierre Pronchery 
rsa_settable_ctx_params(void * vprsactx,ossl_unused void * provctx)1811b077aed3SPierre Pronchery static const OSSL_PARAM *rsa_settable_ctx_params(void *vprsactx,
1812b077aed3SPierre Pronchery                                                  ossl_unused void *provctx)
1813b077aed3SPierre Pronchery {
1814b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1815b077aed3SPierre Pronchery 
1816b077aed3SPierre Pronchery     if (prsactx != NULL && !prsactx->flag_allow_md)
1817b077aed3SPierre Pronchery         return settable_ctx_params_no_digest;
1818b077aed3SPierre Pronchery     return settable_ctx_params;
1819b077aed3SPierre Pronchery }
1820b077aed3SPierre Pronchery 
rsa_get_ctx_md_params(void * vprsactx,OSSL_PARAM * params)1821b077aed3SPierre Pronchery static int rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params)
1822b077aed3SPierre Pronchery {
1823b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1824b077aed3SPierre Pronchery 
1825b077aed3SPierre Pronchery     if (prsactx->mdctx == NULL)
1826b077aed3SPierre Pronchery         return 0;
1827b077aed3SPierre Pronchery 
1828b077aed3SPierre Pronchery     return EVP_MD_CTX_get_params(prsactx->mdctx, params);
1829b077aed3SPierre Pronchery }
1830b077aed3SPierre Pronchery 
rsa_gettable_ctx_md_params(void * vprsactx)1831b077aed3SPierre Pronchery static const OSSL_PARAM *rsa_gettable_ctx_md_params(void *vprsactx)
1832b077aed3SPierre Pronchery {
1833b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1834b077aed3SPierre Pronchery 
1835b077aed3SPierre Pronchery     if (prsactx->md == NULL)
1836b077aed3SPierre Pronchery         return 0;
1837b077aed3SPierre Pronchery 
1838b077aed3SPierre Pronchery     return EVP_MD_gettable_ctx_params(prsactx->md);
1839b077aed3SPierre Pronchery }
1840b077aed3SPierre Pronchery 
rsa_set_ctx_md_params(void * vprsactx,const OSSL_PARAM params[])1841b077aed3SPierre Pronchery static int rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[])
1842b077aed3SPierre Pronchery {
1843b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1844b077aed3SPierre Pronchery 
1845b077aed3SPierre Pronchery     if (prsactx->mdctx == NULL)
1846b077aed3SPierre Pronchery         return 0;
1847b077aed3SPierre Pronchery 
1848b077aed3SPierre Pronchery     return EVP_MD_CTX_set_params(prsactx->mdctx, params);
1849b077aed3SPierre Pronchery }
1850b077aed3SPierre Pronchery 
rsa_settable_ctx_md_params(void * vprsactx)1851b077aed3SPierre Pronchery static const OSSL_PARAM *rsa_settable_ctx_md_params(void *vprsactx)
1852b077aed3SPierre Pronchery {
1853b077aed3SPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1854b077aed3SPierre Pronchery 
1855b077aed3SPierre Pronchery     if (prsactx->md == NULL)
1856b077aed3SPierre Pronchery         return 0;
1857b077aed3SPierre Pronchery 
1858b077aed3SPierre Pronchery     return EVP_MD_settable_ctx_params(prsactx->md);
1859b077aed3SPierre Pronchery }
1860b077aed3SPierre Pronchery 
1861b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_rsa_signature_functions[] = {
1862b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx },
1863b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))rsa_sign_init },
1864b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))rsa_sign },
1865b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))rsa_verify_init },
1866b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))rsa_verify },
1867b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT,
1868b077aed3SPierre Pronchery       (void (*)(void))rsa_verify_recover_init },
1869b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER,
1870b077aed3SPierre Pronchery       (void (*)(void))rsa_verify_recover },
1871b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
1872b077aed3SPierre Pronchery       (void (*)(void))rsa_digest_sign_init },
1873b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
1874e7be843bSPierre Pronchery       (void (*)(void))rsa_digest_sign_update },
1875b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
1876b077aed3SPierre Pronchery       (void (*)(void))rsa_digest_sign_final },
1877b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
1878b077aed3SPierre Pronchery       (void (*)(void))rsa_digest_verify_init },
1879b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
1880e7be843bSPierre Pronchery       (void (*)(void))rsa_digest_verify_update },
1881b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
1882b077aed3SPierre Pronchery       (void (*)(void))rsa_digest_verify_final },
1883b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))rsa_freectx },
1884b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))rsa_dupctx },
1885b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))rsa_get_ctx_params },
1886b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
1887b077aed3SPierre Pronchery       (void (*)(void))rsa_gettable_ctx_params },
1888b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))rsa_set_ctx_params },
1889b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
1890b077aed3SPierre Pronchery       (void (*)(void))rsa_settable_ctx_params },
1891b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
1892b077aed3SPierre Pronchery       (void (*)(void))rsa_get_ctx_md_params },
1893b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
1894b077aed3SPierre Pronchery       (void (*)(void))rsa_gettable_ctx_md_params },
1895b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
1896b077aed3SPierre Pronchery       (void (*)(void))rsa_set_ctx_md_params },
1897b077aed3SPierre Pronchery     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
1898b077aed3SPierre Pronchery       (void (*)(void))rsa_settable_ctx_md_params },
1899e7be843bSPierre Pronchery     OSSL_DISPATCH_END
1900b077aed3SPierre Pronchery };
1901e7be843bSPierre Pronchery 
1902e7be843bSPierre Pronchery /* ------------------------------------------------------------------ */
1903e7be843bSPierre Pronchery 
1904e7be843bSPierre Pronchery /*
1905e7be843bSPierre Pronchery  * So called sigalgs (composite RSA+hash) implemented below.  They
1906e7be843bSPierre Pronchery  * are pretty much hard coded, and rely on the hash implementation
1907e7be843bSPierre Pronchery  * being available as per what OPENSSL_NO_ macros allow.
1908e7be843bSPierre Pronchery  */
1909e7be843bSPierre Pronchery 
1910e7be843bSPierre Pronchery static OSSL_FUNC_signature_query_key_types_fn rsa_sigalg_query_key_types;
1911e7be843bSPierre Pronchery static OSSL_FUNC_signature_settable_ctx_params_fn rsa_sigalg_settable_ctx_params;
1912e7be843bSPierre Pronchery static OSSL_FUNC_signature_set_ctx_params_fn rsa_sigalg_set_ctx_params;
1913e7be843bSPierre Pronchery 
1914e7be843bSPierre Pronchery /*
1915e7be843bSPierre Pronchery  * rsa_sigalg_signverify_init() is almost like rsa_digest_signverify_init(),
1916e7be843bSPierre Pronchery  * just doesn't allow fetching an MD from whatever the user chooses.
1917e7be843bSPierre Pronchery  */
rsa_sigalg_signverify_init(void * vprsactx,void * vrsa,OSSL_FUNC_signature_set_ctx_params_fn * set_ctx_params,const OSSL_PARAM params[],const char * mdname,int operation,int pad_mode,const char * desc)1918e7be843bSPierre Pronchery static int rsa_sigalg_signverify_init(void *vprsactx, void *vrsa,
1919e7be843bSPierre Pronchery                                       OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params,
1920e7be843bSPierre Pronchery                                       const OSSL_PARAM params[],
1921e7be843bSPierre Pronchery                                       const char *mdname,
1922e7be843bSPierre Pronchery                                       int operation, int pad_mode,
1923e7be843bSPierre Pronchery                                       const char *desc)
1924e7be843bSPierre Pronchery {
1925e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1926e7be843bSPierre Pronchery 
1927e7be843bSPierre Pronchery     if (!ossl_prov_is_running())
1928e7be843bSPierre Pronchery         return 0;
1929e7be843bSPierre Pronchery 
1930e7be843bSPierre Pronchery     if (!rsa_signverify_init(prsactx, vrsa, set_ctx_params, params, operation,
1931e7be843bSPierre Pronchery                              desc))
1932e7be843bSPierre Pronchery         return 0;
1933e7be843bSPierre Pronchery 
1934e7be843bSPierre Pronchery     /* PSS is currently not supported as a sigalg */
1935e7be843bSPierre Pronchery     if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) {
1936e7be843bSPierre Pronchery         ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
1937e7be843bSPierre Pronchery         return 0;
1938e7be843bSPierre Pronchery     }
1939e7be843bSPierre Pronchery 
1940e7be843bSPierre Pronchery     if (!rsa_setup_md(prsactx, mdname, NULL, desc))
1941e7be843bSPierre Pronchery         return 0;
1942e7be843bSPierre Pronchery 
1943e7be843bSPierre Pronchery     prsactx->pad_mode = pad_mode;
1944e7be843bSPierre Pronchery     prsactx->flag_sigalg = 1;
1945e7be843bSPierre Pronchery     prsactx->flag_allow_md = 0;
1946e7be843bSPierre Pronchery 
1947e7be843bSPierre Pronchery     if (prsactx->mdctx == NULL) {
1948e7be843bSPierre Pronchery         prsactx->mdctx = EVP_MD_CTX_new();
1949e7be843bSPierre Pronchery         if (prsactx->mdctx == NULL)
1950e7be843bSPierre Pronchery             goto error;
1951e7be843bSPierre Pronchery     }
1952e7be843bSPierre Pronchery 
1953e7be843bSPierre Pronchery     if (!EVP_DigestInit_ex2(prsactx->mdctx, prsactx->md, params))
1954e7be843bSPierre Pronchery         goto error;
1955e7be843bSPierre Pronchery 
1956e7be843bSPierre Pronchery     return 1;
1957e7be843bSPierre Pronchery 
1958e7be843bSPierre Pronchery  error:
1959e7be843bSPierre Pronchery     EVP_MD_CTX_free(prsactx->mdctx);
1960e7be843bSPierre Pronchery     prsactx->mdctx = NULL;
1961e7be843bSPierre Pronchery     return 0;
1962e7be843bSPierre Pronchery }
1963e7be843bSPierre Pronchery 
rsa_sigalg_query_key_types(void)1964e7be843bSPierre Pronchery static const char **rsa_sigalg_query_key_types(void)
1965e7be843bSPierre Pronchery {
1966e7be843bSPierre Pronchery     static const char *keytypes[] = { "RSA", NULL };
1967e7be843bSPierre Pronchery 
1968e7be843bSPierre Pronchery     return keytypes;
1969e7be843bSPierre Pronchery }
1970e7be843bSPierre Pronchery 
1971e7be843bSPierre Pronchery static const OSSL_PARAM settable_sigalg_ctx_params[] = {
1972e7be843bSPierre Pronchery     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0),
1973e7be843bSPierre Pronchery     OSSL_PARAM_END
1974e7be843bSPierre Pronchery };
1975e7be843bSPierre Pronchery 
rsa_sigalg_settable_ctx_params(void * vprsactx,ossl_unused void * provctx)1976e7be843bSPierre Pronchery static const OSSL_PARAM *rsa_sigalg_settable_ctx_params(void *vprsactx,
1977e7be843bSPierre Pronchery                                                         ossl_unused void *provctx)
1978e7be843bSPierre Pronchery {
1979e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1980e7be843bSPierre Pronchery 
1981e7be843bSPierre Pronchery     if (prsactx != NULL && prsactx->operation == EVP_PKEY_OP_VERIFYMSG)
1982e7be843bSPierre Pronchery         return settable_sigalg_ctx_params;
1983e7be843bSPierre Pronchery     return NULL;
1984e7be843bSPierre Pronchery }
1985e7be843bSPierre Pronchery 
rsa_sigalg_set_ctx_params(void * vprsactx,const OSSL_PARAM params[])1986e7be843bSPierre Pronchery static int rsa_sigalg_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
1987e7be843bSPierre Pronchery {
1988e7be843bSPierre Pronchery     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
1989e7be843bSPierre Pronchery     const OSSL_PARAM *p;
1990e7be843bSPierre Pronchery 
1991e7be843bSPierre Pronchery     if (prsactx == NULL)
1992e7be843bSPierre Pronchery         return 0;
1993e7be843bSPierre Pronchery     if (ossl_param_is_empty(params))
1994e7be843bSPierre Pronchery         return 1;
1995e7be843bSPierre Pronchery 
1996e7be843bSPierre Pronchery     if (prsactx->operation == EVP_PKEY_OP_VERIFYMSG) {
1997e7be843bSPierre Pronchery         p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE);
1998e7be843bSPierre Pronchery         if (p != NULL) {
1999e7be843bSPierre Pronchery             OPENSSL_free(prsactx->sig);
2000e7be843bSPierre Pronchery             prsactx->sig = NULL;
2001e7be843bSPierre Pronchery             prsactx->siglen = 0;
2002e7be843bSPierre Pronchery             if (!OSSL_PARAM_get_octet_string(p, (void **)&prsactx->sig,
2003e7be843bSPierre Pronchery                                              0, &prsactx->siglen))
2004e7be843bSPierre Pronchery                 return 0;
2005e7be843bSPierre Pronchery         }
2006e7be843bSPierre Pronchery     }
2007e7be843bSPierre Pronchery     return 1;
2008e7be843bSPierre Pronchery }
2009e7be843bSPierre Pronchery 
2010e7be843bSPierre Pronchery #define IMPL_RSA_SIGALG(md, MD)                                         \
2011e7be843bSPierre Pronchery     static OSSL_FUNC_signature_sign_init_fn rsa_##md##_sign_init;       \
2012e7be843bSPierre Pronchery     static OSSL_FUNC_signature_sign_message_init_fn                     \
2013e7be843bSPierre Pronchery         rsa_##md##_sign_message_init;                                   \
2014e7be843bSPierre Pronchery     static OSSL_FUNC_signature_verify_init_fn rsa_##md##_verify_init;   \
2015e7be843bSPierre Pronchery     static OSSL_FUNC_signature_verify_message_init_fn                   \
2016e7be843bSPierre Pronchery         rsa_##md##_verify_message_init;                                 \
2017e7be843bSPierre Pronchery                                                                         \
2018e7be843bSPierre Pronchery     static int                                                          \
2019e7be843bSPierre Pronchery     rsa_##md##_sign_init(void *vprsactx, void *vrsa,                    \
2020e7be843bSPierre Pronchery                          const OSSL_PARAM params[])                     \
2021e7be843bSPierre Pronchery     {                                                                   \
2022e7be843bSPierre Pronchery         static const char desc[] = "RSA Sigalg Sign Init";              \
2023e7be843bSPierre Pronchery                                                                         \
2024e7be843bSPierre Pronchery         return rsa_sigalg_signverify_init(vprsactx, vrsa,               \
2025e7be843bSPierre Pronchery                                           rsa_sigalg_set_ctx_params,    \
2026e7be843bSPierre Pronchery                                           params, #MD,                  \
2027e7be843bSPierre Pronchery                                           EVP_PKEY_OP_SIGN,             \
2028e7be843bSPierre Pronchery                                           RSA_PKCS1_PADDING,            \
2029e7be843bSPierre Pronchery                                           desc);                        \
2030e7be843bSPierre Pronchery     }                                                                   \
2031e7be843bSPierre Pronchery                                                                         \
2032e7be843bSPierre Pronchery     static int                                                          \
2033e7be843bSPierre Pronchery     rsa_##md##_sign_message_init(void *vprsactx, void *vrsa,            \
2034e7be843bSPierre Pronchery                                  const OSSL_PARAM params[])             \
2035e7be843bSPierre Pronchery     {                                                                   \
2036e7be843bSPierre Pronchery         static const char desc[] = "RSA Sigalg Sign Message Init";      \
2037e7be843bSPierre Pronchery                                                                         \
2038e7be843bSPierre Pronchery         return rsa_sigalg_signverify_init(vprsactx, vrsa,               \
2039e7be843bSPierre Pronchery                                           rsa_sigalg_set_ctx_params,    \
2040e7be843bSPierre Pronchery                                           params, #MD,                  \
2041e7be843bSPierre Pronchery                                           EVP_PKEY_OP_SIGNMSG,          \
2042e7be843bSPierre Pronchery                                           RSA_PKCS1_PADDING,            \
2043e7be843bSPierre Pronchery                                           desc);                        \
2044e7be843bSPierre Pronchery     }                                                                   \
2045e7be843bSPierre Pronchery                                                                         \
2046e7be843bSPierre Pronchery     static int                                                          \
2047e7be843bSPierre Pronchery     rsa_##md##_verify_init(void *vprsactx, void *vrsa,                  \
2048e7be843bSPierre Pronchery                            const OSSL_PARAM params[])                   \
2049e7be843bSPierre Pronchery     {                                                                   \
2050e7be843bSPierre Pronchery         static const char desc[] = "RSA Sigalg Verify Init";            \
2051e7be843bSPierre Pronchery                                                                         \
2052e7be843bSPierre Pronchery         return rsa_sigalg_signverify_init(vprsactx, vrsa,               \
2053e7be843bSPierre Pronchery                                           rsa_sigalg_set_ctx_params,    \
2054e7be843bSPierre Pronchery                                           params, #MD,                  \
2055e7be843bSPierre Pronchery                                           EVP_PKEY_OP_VERIFY,           \
2056e7be843bSPierre Pronchery                                           RSA_PKCS1_PADDING,            \
2057e7be843bSPierre Pronchery                                           desc);                        \
2058e7be843bSPierre Pronchery     }                                                                   \
2059e7be843bSPierre Pronchery                                                                         \
2060e7be843bSPierre Pronchery     static int                                                          \
2061e7be843bSPierre Pronchery     rsa_##md##_verify_recover_init(void *vprsactx, void *vrsa,          \
2062e7be843bSPierre Pronchery                                    const OSSL_PARAM params[])           \
2063e7be843bSPierre Pronchery     {                                                                   \
2064e7be843bSPierre Pronchery         static const char desc[] = "RSA Sigalg Verify Recover Init";    \
2065e7be843bSPierre Pronchery                                                                         \
2066e7be843bSPierre Pronchery         return rsa_sigalg_signverify_init(vprsactx, vrsa,               \
2067e7be843bSPierre Pronchery                                           rsa_sigalg_set_ctx_params,    \
2068e7be843bSPierre Pronchery                                           params, #MD,                  \
2069e7be843bSPierre Pronchery                                           EVP_PKEY_OP_VERIFYRECOVER,    \
2070e7be843bSPierre Pronchery                                           RSA_PKCS1_PADDING,            \
2071e7be843bSPierre Pronchery                                           desc);                        \
2072e7be843bSPierre Pronchery     }                                                                   \
2073e7be843bSPierre Pronchery                                                                         \
2074e7be843bSPierre Pronchery     static int                                                          \
2075e7be843bSPierre Pronchery     rsa_##md##_verify_message_init(void *vprsactx, void *vrsa,          \
2076e7be843bSPierre Pronchery                                    const OSSL_PARAM params[])           \
2077e7be843bSPierre Pronchery     {                                                                   \
2078e7be843bSPierre Pronchery         static const char desc[] = "RSA Sigalg Verify Message Init";    \
2079e7be843bSPierre Pronchery                                                                         \
2080e7be843bSPierre Pronchery         return rsa_sigalg_signverify_init(vprsactx, vrsa,               \
2081e7be843bSPierre Pronchery                                           rsa_sigalg_set_ctx_params,    \
2082e7be843bSPierre Pronchery                                           params, #MD,                  \
2083e7be843bSPierre Pronchery                                           EVP_PKEY_OP_VERIFYMSG,        \
2084e7be843bSPierre Pronchery                                           RSA_PKCS1_PADDING,            \
2085e7be843bSPierre Pronchery                                           desc);                        \
2086e7be843bSPierre Pronchery     }                                                                   \
2087e7be843bSPierre Pronchery                                                                         \
2088e7be843bSPierre Pronchery     const OSSL_DISPATCH ossl_rsa_##md##_signature_functions[] = {       \
2089e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx },     \
2090e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SIGN_INIT,                                \
2091e7be843bSPierre Pronchery           (void (*)(void))rsa_##md##_sign_init },                       \
2092e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))rsa_sign },         \
2093e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT,                        \
2094e7be843bSPierre Pronchery           (void (*)(void))rsa_##md##_sign_message_init },               \
2095e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE,                      \
2096e7be843bSPierre Pronchery           (void (*)(void))rsa_signverify_message_update },              \
2097e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL,                       \
2098e7be843bSPierre Pronchery           (void (*)(void))rsa_sign_message_final },                     \
2099e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY_INIT,                              \
2100e7be843bSPierre Pronchery           (void (*)(void))rsa_##md##_verify_init },                     \
2101e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY,                                   \
2102e7be843bSPierre Pronchery           (void (*)(void))rsa_verify },                                 \
2103e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT,                      \
2104e7be843bSPierre Pronchery           (void (*)(void))rsa_##md##_verify_message_init },             \
2105e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE,                    \
2106e7be843bSPierre Pronchery           (void (*)(void))rsa_signverify_message_update },              \
2107e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL,                     \
2108e7be843bSPierre Pronchery           (void (*)(void))rsa_verify_message_final },                   \
2109e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT,                      \
2110e7be843bSPierre Pronchery           (void (*)(void))rsa_##md##_verify_recover_init },             \
2111e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER,                           \
2112e7be843bSPierre Pronchery           (void (*)(void))rsa_verify_recover },                         \
2113e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))rsa_freectx },   \
2114e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))rsa_dupctx },     \
2115e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES,                          \
2116e7be843bSPierre Pronchery           (void (*)(void))rsa_sigalg_query_key_types },                 \
2117e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS,                           \
2118e7be843bSPierre Pronchery           (void (*)(void))rsa_get_ctx_params },                         \
2119e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,                      \
2120e7be843bSPierre Pronchery           (void (*)(void))rsa_gettable_ctx_params },                    \
2121e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS,                           \
2122e7be843bSPierre Pronchery           (void (*)(void))rsa_sigalg_set_ctx_params },                  \
2123e7be843bSPierre Pronchery         { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                      \
2124e7be843bSPierre Pronchery           (void (*)(void))rsa_sigalg_settable_ctx_params },             \
2125e7be843bSPierre Pronchery         OSSL_DISPATCH_END                                               \
2126e7be843bSPierre Pronchery     }
2127e7be843bSPierre Pronchery 
2128e7be843bSPierre Pronchery #if !defined(OPENSSL_NO_RMD160) && !defined(FIPS_MODULE)
2129e7be843bSPierre Pronchery IMPL_RSA_SIGALG(ripemd160, RIPEMD160);
2130e7be843bSPierre Pronchery #endif
2131e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha1, SHA1);
2132e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha224, SHA2-224);
2133e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha256, SHA2-256);
2134e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha384, SHA2-384);
2135e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha512, SHA2-512);
2136e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha512_224, SHA2-512/224);
2137e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha512_256, SHA2-512/256);
2138e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha3_224, SHA3-224);
2139e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha3_256, SHA3-256);
2140e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha3_384, SHA3-384);
2141e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sha3_512, SHA3-512);
2142e7be843bSPierre Pronchery #if !defined(OPENSSL_NO_SM3) && !defined(FIPS_MODULE)
2143e7be843bSPierre Pronchery IMPL_RSA_SIGALG(sm3, SM3);
2144e7be843bSPierre Pronchery #endif
2145