xref: /freebsd/crypto/openssl/providers/common/securitycheck.c (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*
2  * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include "internal/deprecated.h"
11 
12 #include <openssl/rsa.h>
13 #include <openssl/dsa.h>
14 #include <openssl/dh.h>
15 #include <openssl/ec.h>
16 #include <openssl/evp.h>
17 #include <openssl/err.h>
18 #include <openssl/proverr.h>
19 #include <openssl/core_names.h>
20 #include <openssl/obj_mac.h>
21 #include "prov/securitycheck.h"
22 
23 #define OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS 112
24 
ossl_rsa_key_op_get_protect(const RSA * rsa,int operation,int * outprotect)25 int ossl_rsa_key_op_get_protect(const RSA *rsa, int operation, int *outprotect)
26 {
27     int protect = 0;
28 
29     switch (operation) {
30     case EVP_PKEY_OP_SIGN:
31     case EVP_PKEY_OP_SIGNMSG:
32         protect = 1;
33         /* fallthrough */
34     case EVP_PKEY_OP_VERIFY:
35     case EVP_PKEY_OP_VERIFYMSG:
36         break;
37     case EVP_PKEY_OP_ENCAPSULATE:
38     case EVP_PKEY_OP_ENCRYPT:
39         protect = 1;
40         /* fallthrough */
41     case EVP_PKEY_OP_VERIFYRECOVER:
42     case EVP_PKEY_OP_DECAPSULATE:
43     case EVP_PKEY_OP_DECRYPT:
44         if (RSA_test_flags(rsa,
45                            RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSASSAPSS) {
46             ERR_raise_data(ERR_LIB_PROV,
47                            PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE,
48                            "operation: %d", operation);
49             return 0;
50         }
51         break;
52     default:
53         ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR,
54                        "invalid operation: %d", operation);
55         return 0;
56     }
57     *outprotect = protect;
58     return 1;
59 }
60 
61 /*
62  * FIPS requires a minimum security strength of 112 bits (for encryption or
63  * signing), and for legacy purposes 80 bits (for decryption or verifying).
64  * Set protect = 1 for encryption or signing operations, or 0 otherwise. See
65  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf.
66  */
ossl_rsa_check_key_size(const RSA * rsa,int protect)67 int ossl_rsa_check_key_size(const RSA *rsa, int protect)
68 {
69     int sz = RSA_bits(rsa);
70 
71     if (protect ? (sz < 2048) : (sz < 1024))
72         return 0;
73     return 1;
74 }
75 
76 /*
77  * FIPS requires a minimum security strength of 112 bits for key-derivation key.
78  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf.
79  */
ossl_kdf_check_key_size(size_t keylen)80 int ossl_kdf_check_key_size(size_t keylen)
81 {
82     return (keylen * 8) >= OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS;
83 }
84 
ossl_mac_check_key_size(size_t keylen)85 int ossl_mac_check_key_size(size_t keylen)
86 {
87     return ossl_kdf_check_key_size(keylen);
88 }
89 
90 #ifndef OPENSSL_NO_EC
91 
ossl_ec_check_curve_allowed(const EC_GROUP * group)92 int ossl_ec_check_curve_allowed(const EC_GROUP *group)
93 {
94     const char *curve_name;
95     int nid = EC_GROUP_get_curve_name(group);
96 
97     /* Explicit curves are not FIPS approved */
98     if (nid == NID_undef)
99         return 0;
100     /* Only NIST curves are FIPS approved */
101     curve_name = EC_curve_nid2nist(nid);
102     if (curve_name == NULL)
103         return 0;
104     return 1;
105 }
106 
107 /*
108  * In FIPS mode:
109  * protect should be 1 for any operations that need 112 bits of security
110  * strength (such as signing, and key exchange), or 0 for operations that allow
111  * a lower security strength (such as verify).
112  *
113  * For ECDH key agreement refer to SP800-56A
114  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf
115  * "Appendix D"
116  *
117  * For ECDSA signatures refer to
118  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf
119  * "Table 2"
120  */
ossl_ec_check_security_strength(const EC_GROUP * group,int protect)121 int ossl_ec_check_security_strength(const EC_GROUP *group, int protect)
122 {
123     /*
124      * For EC the security strength is the (order_bits / 2)
125      * e.g. P-224 is 112 bits.
126      */
127     int strength = EC_GROUP_order_bits(group) / 2;
128     /* The min security strength allowed for legacy verification is 80 bits */
129     if (strength < 80)
130         return 0;
131     /*
132      * For signing or key agreement only allow curves with at least 112 bits of
133      * security strength
134      */
135     if (protect && strength < OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS)
136         return 0;
137     return 1;
138 }
139 
140 #endif /* OPENSSL_NO_EC */
141 
142 #ifndef OPENSSL_NO_DSA
143 /*
144  * Check for valid key sizes if fips mode. Refer to
145  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf
146  * "Table 2"
147  */
ossl_dsa_check_key(const DSA * dsa,int sign)148 int ossl_dsa_check_key(const DSA *dsa, int sign)
149 {
150     size_t L, N;
151     const BIGNUM *p, *q;
152 
153     if (dsa == NULL)
154         return 0;
155 
156     p = DSA_get0_p(dsa);
157     q = DSA_get0_q(dsa);
158     if (p == NULL || q == NULL)
159         return 0;
160 
161     L = BN_num_bits(p);
162     N = BN_num_bits(q);
163 
164     /*
165      * For Digital signature verification DSA keys with < 112 bits of
166      * security strength, are still allowed for legacy
167      * use. The bounds given in SP 800-131Ar2 - Table 2 are
168      * (512 <= L < 2048 or 160 <= N < 224).
169      *
170      * We are a little stricter and insist that both minimums are met.
171      * For example a L = 256, N = 160 key *would* be allowed by SP 800-131Ar2
172      * but we don't.
173      */
174     if (!sign) {
175         if (L < 512 || N < 160)
176             return 0;
177         if (L < 2048 || N < 224)
178             return 1;
179     }
180 
181      /* Valid sizes for both sign and verify */
182     if (L == 2048 && (N == 224 || N == 256))    /* 112 bits */
183         return 1;
184     return (L == 3072 && N == 256);             /* 128 bits */
185 }
186 #endif /* OPENSSL_NO_DSA */
187 
188 #ifndef OPENSSL_NO_DH
189 /*
190  * For DH key agreement refer to SP800-56A
191  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf
192  * "Section 5.5.1.1FFC Domain Parameter Selection/Generation" and
193  * "Appendix D" FFC Safe-prime Groups
194  */
ossl_dh_check_key(const DH * dh)195 int ossl_dh_check_key(const DH *dh)
196 {
197     size_t L, N;
198     const BIGNUM *p, *q;
199 
200     if (dh == NULL)
201         return 0;
202 
203     p = DH_get0_p(dh);
204     q = DH_get0_q(dh);
205     if (p == NULL || q == NULL)
206         return 0;
207 
208     L = BN_num_bits(p);
209     if (L < 2048)
210         return 0;
211 
212     /* If it is a safe prime group then it is ok */
213     if (DH_get_nid(dh))
214         return 1;
215 
216     /* If not then it must be FFC, which only allows certain sizes. */
217     N = BN_num_bits(q);
218 
219     return (L == 2048 && (N == 224 || N == 256));
220 }
221 #endif /* OPENSSL_NO_DH */
222