/[smecontribs]/rpms/openssl3/contribs10/0090-signature-Clamp-PSS-salt-len-to-MD-len.patch
ViewVC logotype

Annotation of /rpms/openssl3/contribs10/0090-signature-Clamp-PSS-salt-len-to-MD-len.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Jan 31 17:24:49 2024 UTC (10 months ago) by jpp
Branch: MAIN
CVS Tags: openssl3-3_0_7-5_el7_sme_1, HEAD
Initial import

1 jpp 1.1 From 9cc914ff3e1fda124bdc76d72ebc9349ec19f8ae Mon Sep 17 00:00:00 2001
2     From: Clemens Lang <cllang@redhat.com>
3     Date: Fri, 18 Nov 2022 12:35:33 +0100
4     Subject: [PATCH 3/3] signature: Clamp PSS salt len to MD len
5     MIME-Version: 1.0
6     Content-Type: text/plain; charset=UTF-8
7     Content-Transfer-Encoding: 8bit
8    
9     FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
10     5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
11     salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
12     the hash function output block (in bytes)."
13    
14     Introduce a new option RSA_PSS_SALTLEN_AUTO_DIGEST_MAX and make it the
15     default. The new value will behave like RSA_PSS_SALTLEN_AUTO, but will
16     not use more than the digest legth when signing, so that FIPS 186-4 is
17     not violated. This value has two advantages when compared with
18     RSA_PSS_SALTLEN_DIGEST: (1) It will continue to do auto-detection when
19     verifying signatures for maximum compatibility, where
20     RSA_PSS_SALTLEN_DIGEST would fail for other digest sizes. (2) It will
21     work for combinations where the maximum salt length is smaller than the
22     digest size, which typically happens with large digest sizes (e.g.,
23     SHA-512) and small RSA keys.
24    
25     Signed-off-by: Clemens Lang <cllang@redhat.com>
26     ---
27     crypto/rsa/rsa_ameth.c | 18 ++++++++-
28     crypto/rsa/rsa_pss.c | 26 ++++++++++--
29     doc/man3/EVP_PKEY_CTX_ctrl.pod | 11 ++++-
30     doc/man7/EVP_SIGNATURE-RSA.pod | 5 +++
31     include/openssl/core_names.h | 1 +
32     include/openssl/rsa.h | 3 ++
33     providers/implementations/signature/rsa_sig.c | 40 ++++++++++++++-----
34     test/recipes/25-test_req.t | 2 +-
35     8 files changed, 87 insertions(+), 19 deletions(-)
36    
37     diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
38     index 61ec53d424..e69a98d116 100644
39     --- a/crypto/rsa/rsa_ameth.c
40     +++ b/crypto/rsa/rsa_ameth.c
41     @@ -450,6 +450,7 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
42     const EVP_MD *sigmd, *mgf1md;
43     EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
44     int saltlen;
45     + int saltlenMax = -1;
46    
47     if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
48     return NULL;
49     @@ -457,14 +458,27 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
50     return NULL;
51     if (EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen) <= 0)
52     return NULL;
53     - if (saltlen == -1) {
54     + if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
55     saltlen = EVP_MD_get_size(sigmd);
56     - } else if (saltlen == -2 || saltlen == -3) {
57     + } else if (saltlen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
58     + /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm",
59     + * subsection 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in
60     + * bytes) of the salt (sLen) shall satisfy 0 <= sLen <= hLen, where
61     + * hLen is the length of the hash function output block (in bytes)."
62     + *
63     + * Provide a way to use at most the digest length, so that the default
64     + * does not violate FIPS 186-4. */
65     + saltlen = RSA_PSS_SALTLEN_MAX;
66     + saltlenMax = EVP_MD_get_size(sigmd);
67     + }
68     + if (saltlen == RSA_PSS_SALTLEN_MAX || saltlen == RSA_PSS_SALTLEN_AUTO) {
69     saltlen = EVP_PKEY_get_size(pk) - EVP_MD_get_size(sigmd) - 2;
70     if ((EVP_PKEY_get_bits(pk) & 0x7) == 1)
71     saltlen--;
72     if (saltlen < 0)
73     return NULL;
74     + if (saltlenMax >= 0 && saltlen > saltlenMax)
75     + saltlen = saltlenMax;
76     }
77    
78     return ossl_rsa_pss_params_create(sigmd, mgf1md, saltlen);
79     diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
80     index 33874bfef8..430c36eb2a 100644
81     --- a/crypto/rsa/rsa_pss.c
82     +++ b/crypto/rsa/rsa_pss.c
83     @@ -61,11 +61,12 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
84     * -1 sLen == hLen
85     * -2 salt length is autorecovered from signature
86     * -3 salt length is maximized
87     + * -4 salt length is autorecovered from signature
88     * -N reserved
89     */
90     if (sLen == RSA_PSS_SALTLEN_DIGEST) {
91     sLen = hLen;
92     - } else if (sLen < RSA_PSS_SALTLEN_MAX) {
93     + } else if (sLen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
94     ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED);
95     goto err;
96     }
97     @@ -112,7 +113,9 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
98     ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED);
99     goto err;
100     }
101     - if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) {
102     + if (sLen != RSA_PSS_SALTLEN_AUTO
103     + && sLen != RSA_PSS_SALTLEN_AUTO_DIGEST_MAX
104     + && (maskedDBLen - i) != sLen) {
105     ERR_raise_data(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED,
106     "expected: %d retrieved: %d", sLen,
107     maskedDBLen - i);
108     @@ -160,6 +163,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
109     int hLen, maskedDBLen, MSBits, emLen;
110     unsigned char *H, *salt = NULL, *p;
111     EVP_MD_CTX *ctx = NULL;
112     + int sLenMax = -1;
113    
114     if (mgf1Hash == NULL)
115     mgf1Hash = Hash;
116     @@ -172,13 +176,25 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
117     * -1 sLen == hLen
118     * -2 salt length is maximized
119     * -3 same as above (on signing)
120     + * -4 salt length is min(hLen, maximum salt length)
121     * -N reserved
122     */
123     + /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
124     + * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
125     + * salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
126     + * the hash function output block (in bytes)."
127     + *
128     + * Provide a way to use at most the digest length, so that the default does
129     + * not violate FIPS 186-4. */
130     if (sLen == RSA_PSS_SALTLEN_DIGEST) {
131     sLen = hLen;
132     - } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) {
133     + } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN
134     + || sLen == RSA_PSS_SALTLEN_AUTO) {
135     sLen = RSA_PSS_SALTLEN_MAX;
136     - } else if (sLen < RSA_PSS_SALTLEN_MAX) {
137     + } else if (sLen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
138     + sLen = RSA_PSS_SALTLEN_MAX;
139     + sLenMax = hLen;
140     + } else if (sLen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
141     ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED);
142     goto err;
143     }
144     @@ -195,6 +211,8 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
145     }
146     if (sLen == RSA_PSS_SALTLEN_MAX) {
147     sLen = emLen - hLen - 2;
148     + if (sLenMax >= 0 && sLen > sLenMax)
149     + sLen = sLenMax;
150     } else if (sLen > emLen - hLen - 2) {
151     ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
152     goto err;
153     diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
154     index 3075eaafd6..9b96f42dbc 100644
155     --- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
156     +++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
157     @@ -270,8 +270,8 @@ EVP_PKEY_CTX_get_rsa_padding() gets the RSA padding mode for I<ctx>.
158    
159     EVP_PKEY_CTX_set_rsa_pss_saltlen() sets the RSA PSS salt length to I<saltlen>.
160     As its name implies it is only supported for PSS padding. If this function is
161     -not called then the maximum salt length is used when signing and auto detection
162     -when verifying. Three special values are supported:
163     +not called then the salt length is maximized up to the digest length when
164     +signing and auto detection when verifying. Four special values are supported:
165    
166     =over 4
167    
168     @@ -289,6 +289,13 @@ causes the salt length to be automatically determined based on the
169     B<PSS> block structure when verifying. When signing, it has the same
170     meaning as B<RSA_PSS_SALTLEN_MAX>.
171    
172     +=item B<RSA_PSS_SALTLEN_AUTO_DIGEST_MAX>
173     +
174     +causes the salt length to be automatically determined based on the B<PSS> block
175     +structure when verifying, like B<RSA_PSS_SALTLEN_AUTO>. When signing, the salt
176     +length is maximized up to a maximum of the digest length to comply with FIPS
177     +186-4 section 5.5.
178     +
179     =back
180    
181     EVP_PKEY_CTX_get_rsa_pss_saltlen() gets the RSA PSS salt length for I<ctx>.
182     diff --git a/doc/man7/EVP_SIGNATURE-RSA.pod b/doc/man7/EVP_SIGNATURE-RSA.pod
183     index 1ce32cc443..13d053e262 100644
184     --- a/doc/man7/EVP_SIGNATURE-RSA.pod
185     +++ b/doc/man7/EVP_SIGNATURE-RSA.pod
186     @@ -68,6 +68,11 @@ Use the maximum salt length.
187    
188     Auto detect the salt length.
189    
190     +=item "auto-digestmax" (B<OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX>)
191     +
192     +Auto detect the salt length when verifying. Maximize the salt length up to the
193     +digest size when signing to comply with FIPS 186-4 section 5.5.
194     +
195     =back
196    
197     =back
198     diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
199     index 69c59f0b46..5779f41427 100644
200     --- a/include/openssl/core_names.h
201     +++ b/include/openssl/core_names.h
202     @@ -399,6 +399,7 @@ extern "C" {
203     #define OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST "digest"
204     #define OSSL_PKEY_RSA_PSS_SALT_LEN_MAX "max"
205     #define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO "auto"
206     +#define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX "auto-digestmax"
207    
208     /* Key generation parameters */
209     #define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS
210     diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
211     index a55c9727c6..daf55bc6d4 100644
212     --- a/include/openssl/rsa.h
213     +++ b/include/openssl/rsa.h
214     @@ -137,6 +137,9 @@ int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp);
215     # define RSA_PSS_SALTLEN_AUTO -2
216     /* Set salt length to maximum possible */
217     # define RSA_PSS_SALTLEN_MAX -3
218     +/* Auto-detect on verify, set salt length to min(maximum possible, digest
219     + * length) on sign */
220     +# define RSA_PSS_SALTLEN_AUTO_DIGEST_MAX -4
221     /* Old compatible max salt length for sign only */
222     # define RSA_PSS_SALTLEN_MAX_SIGN -2
223    
224     diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
225     index 0c45008a00..1a787d77db 100644
226     --- a/providers/implementations/signature/rsa_sig.c
227     +++ b/providers/implementations/signature/rsa_sig.c
228     @@ -191,8 +191,8 @@ static void *rsa_newctx(void *provctx, const char *propq)
229     prsactx->libctx = PROV_LIBCTX_OF(provctx);
230     prsactx->flag_allow_md = 1;
231     prsactx->propq = propq_copy;
232     - /* Maximum for sign, auto for verify */
233     - prsactx->saltlen = RSA_PSS_SALTLEN_AUTO;
234     + /* Maximum up to digest length for sign, auto for verify */
235     + prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
236     prsactx->min_saltlen = -1;
237     return prsactx;
238     }
239     @@ -200,13 +200,27 @@ static void *rsa_newctx(void *provctx, const char *propq)
240     static int rsa_pss_compute_saltlen(PROV_RSA_CTX *ctx)
241     {
242     int saltlen = ctx->saltlen;
243     -
244     + int saltlenMax = -1;
245     +
246     + /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
247     + * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
248     + * salt (sLen) shall satisfy 0 <= sLen <= hLen, where hLen is the length of
249     + * the hash function output block (in bytes)."
250     + *
251     + * Provide a way to use at most the digest length, so that the default does
252     + * not violate FIPS 186-4. */
253     if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
254     saltlen = EVP_MD_get_size(ctx->md);
255     - } else if (saltlen == RSA_PSS_SALTLEN_AUTO || saltlen == RSA_PSS_SALTLEN_MAX) {
256     + } else if (saltlen == RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
257     + saltlen = RSA_PSS_SALTLEN_MAX;
258     + saltlenMax = EVP_MD_get_size(ctx->md);
259     + }
260     + if (saltlen == RSA_PSS_SALTLEN_MAX || saltlen == RSA_PSS_SALTLEN_AUTO) {
261     saltlen = RSA_size(ctx->rsa) - EVP_MD_get_size(ctx->md) - 2;
262     if ((RSA_bits(ctx->rsa) & 0x7) == 1)
263     saltlen--;
264     + if (saltlenMax >= 0 && saltlen > saltlenMax)
265     + saltlen = saltlenMax;
266     }
267     if (saltlen < 0) {
268     ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
269     @@ -411,8 +425,8 @@ static int rsa_signverify_init(void *vprsactx, void *vrsa,
270    
271     prsactx->operation = operation;
272    
273     - /* Maximum for sign, auto for verify */
274     - prsactx->saltlen = RSA_PSS_SALTLEN_AUTO;
275     + /* Maximize up to digest length for sign, auto for verify */
276     + prsactx->saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
277     prsactx->min_saltlen = -1;
278    
279     switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) {
280     @@ -1110,6 +1124,9 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
281     case RSA_PSS_SALTLEN_AUTO:
282     value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO;
283     break;
284     + case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
285     + value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX;
286     + break;
287     default:
288     {
289     int len = BIO_snprintf(p->data, p->data_size, "%d",
290     @@ -1297,6 +1314,8 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
291     saltlen = RSA_PSS_SALTLEN_MAX;
292     else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0)
293     saltlen = RSA_PSS_SALTLEN_AUTO;
294     + else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0)
295     + saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX;
296     else
297     saltlen = atoi(p->data);
298     break;
299     @@ -1305,11 +1324,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
300     }
301    
302     /*
303     - * RSA_PSS_SALTLEN_MAX seems curiously named in this check.
304     - * Contrary to what it's name suggests, it's the currently
305     - * lowest saltlen number possible.
306     + * RSA_PSS_SALTLEN_AUTO_DIGEST_MAX seems curiously named in this check.
307     + * Contrary to what it's name suggests, it's the currently lowest
308     + * saltlen number possible.
309     */
310     - if (saltlen < RSA_PSS_SALTLEN_MAX) {
311     + if (saltlen < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) {
312     ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH);
313     return 0;
314     }
315     @@ -1317,6 +1336,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
316     if (rsa_pss_restricted(prsactx)) {
317     switch (saltlen) {
318     case RSA_PSS_SALTLEN_AUTO:
319     + case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX:
320     if (prsactx->operation == EVP_PKEY_OP_VERIFY) {
321     ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH,
322     "Cannot use autodetected salt length");
323     diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t
324     index e615f1b338..35541aed12 100644
325     --- a/test/recipes/25-test_req.t
326     +++ b/test/recipes/25-test_req.t
327     @@ -199,7 +199,7 @@ subtest "generating certificate requests with RSA-PSS" => sub {
328     ok(!run(app(["openssl", "req",
329     "-config", srctop_file("test", "test.cnf"),
330     "-new", "-out", "testreq-rsapss3.pem", "-utf8",
331     - "-sigopt", "rsa_pss_saltlen:-4",
332     + "-sigopt", "rsa_pss_saltlen:-5",
333     "-key", srctop_file("test", "testrsapss.pem")])),
334     "Generating request with expected failure");
335    
336     --
337     2.38.1
338    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed