]>
Commit | Line | Data |
---|---|---|
7a810fac | 1 | /* |
da1c088f | 2 | * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. |
7a810fac SL |
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> | |
0cfbc828 | 16 | #include <openssl/evp.h> |
7a810fac | 17 | #include <openssl/err.h> |
2741128e | 18 | #include <openssl/proverr.h> |
7a810fac SL |
19 | #include <openssl/core_names.h> |
20 | #include <openssl/obj_mac.h> | |
21 | #include "prov/securitycheck.h" | |
7a810fac SL |
22 | |
23 | /* | |
24 | * FIPS requires a minimum security strength of 112 bits (for encryption or | |
25 | * signing), and for legacy purposes 80 bits (for decryption or verifying). | |
26 | * Set protect = 1 for encryption or signing operations, or 0 otherwise. See | |
27 | * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf. | |
28 | */ | |
6ce58488 | 29 | int ossl_rsa_check_key(OSSL_LIB_CTX *ctx, const RSA *rsa, int operation) |
7a810fac | 30 | { |
0cfbc828 TM |
31 | int protect = 0; |
32 | ||
33 | switch (operation) { | |
34 | case EVP_PKEY_OP_SIGN: | |
35 | protect = 1; | |
36 | /* fallthrough */ | |
37 | case EVP_PKEY_OP_VERIFY: | |
38 | break; | |
39 | case EVP_PKEY_OP_ENCAPSULATE: | |
40 | case EVP_PKEY_OP_ENCRYPT: | |
41 | protect = 1; | |
42 | /* fallthrough */ | |
43 | case EVP_PKEY_OP_VERIFYRECOVER: | |
44 | case EVP_PKEY_OP_DECAPSULATE: | |
45 | case EVP_PKEY_OP_DECRYPT: | |
46 | if (RSA_test_flags(rsa, | |
47 | RSA_FLAG_TYPE_MASK) == RSA_FLAG_TYPE_RSASSAPSS) { | |
48 | ERR_raise_data(ERR_LIB_PROV, | |
49 | PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE, | |
50 | "operation: %d", operation); | |
51 | return 0; | |
52 | } | |
53 | break; | |
54 | default: | |
55 | ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR, | |
56 | "invalid operation: %d", operation); | |
57 | return 0; | |
58 | } | |
59 | ||
7a810fac | 60 | #if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) |
6ce58488 | 61 | if (ossl_securitycheck_enabled(ctx)) { |
7a810fac SL |
62 | int sz = RSA_bits(rsa); |
63 | ||
0cfbc828 TM |
64 | if (protect ? (sz < 2048) : (sz < 1024)) { |
65 | ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH, | |
66 | "operation: %d", operation); | |
67 | return 0; | |
68 | } | |
7a810fac | 69 | } |
0cfbc828 TM |
70 | #else |
71 | /* make protect used */ | |
72 | (void)protect; | |
7a810fac SL |
73 | #endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ |
74 | return 1; | |
75 | } | |
76 | ||
77 | #ifndef OPENSSL_NO_EC | |
78 | /* | |
79 | * In FIPS mode: | |
80 | * protect should be 1 for any operations that need 112 bits of security | |
81 | * strength (such as signing, and key exchange), or 0 for operations that allow | |
82 | * a lower security strength (such as verify). | |
83 | * | |
84 | * For ECDH key agreement refer to SP800-56A | |
85 | * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf | |
86 | * "Appendix D" | |
87 | * | |
88 | * For ECDSA signatures refer to | |
89 | * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf | |
90 | * "Table 2" | |
91 | */ | |
6ce58488 | 92 | int ossl_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect) |
7a810fac SL |
93 | { |
94 | # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) | |
6ce58488 | 95 | if (ossl_securitycheck_enabled(ctx)) { |
7a810fac SL |
96 | int nid, strength; |
97 | const char *curve_name; | |
98 | const EC_GROUP *group = EC_KEY_get0_group(ec); | |
99 | ||
100 | if (group == NULL) { | |
101 | ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group"); | |
102 | return 0; | |
103 | } | |
104 | nid = EC_GROUP_get_curve_name(group); | |
105 | if (nid == NID_undef) { | |
106 | ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, | |
107 | "Explicit curves are not allowed in fips mode"); | |
108 | return 0; | |
109 | } | |
110 | ||
111 | curve_name = EC_curve_nid2nist(nid); | |
112 | if (curve_name == NULL) { | |
113 | ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, | |
114 | "Curve %s is not approved in FIPS mode", curve_name); | |
115 | return 0; | |
116 | } | |
117 | ||
118 | /* | |
119 | * For EC the security strength is the (order_bits / 2) | |
120 | * e.g. P-224 is 112 bits. | |
121 | */ | |
122 | strength = EC_GROUP_order_bits(group) / 2; | |
123 | /* The min security strength allowed for legacy verification is 80 bits */ | |
124 | if (strength < 80) { | |
125 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); | |
126 | return 0; | |
127 | } | |
128 | ||
129 | /* | |
130 | * For signing or key agreement only allow curves with at least 112 bits of | |
131 | * security strength | |
132 | */ | |
133 | if (protect && strength < 112) { | |
134 | ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, | |
135 | "Curve %s cannot be used for signing", curve_name); | |
136 | return 0; | |
137 | } | |
138 | } | |
139 | # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ | |
140 | return 1; | |
141 | } | |
142 | #endif /* OPENSSL_NO_EC */ | |
143 | ||
144 | #ifndef OPENSSL_NO_DSA | |
145 | /* | |
146 | * Check for valid key sizes if fips mode. Refer to | |
147 | * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf | |
148 | * "Table 2" | |
149 | */ | |
6ce58488 | 150 | int ossl_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign) |
7a810fac SL |
151 | { |
152 | # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) | |
6ce58488 | 153 | if (ossl_securitycheck_enabled(ctx)) { |
7a810fac SL |
154 | size_t L, N; |
155 | const BIGNUM *p, *q; | |
156 | ||
157 | if (dsa == NULL) | |
158 | return 0; | |
159 | ||
160 | p = DSA_get0_p(dsa); | |
161 | q = DSA_get0_q(dsa); | |
162 | if (p == NULL || q == NULL) | |
163 | return 0; | |
164 | ||
165 | L = BN_num_bits(p); | |
166 | N = BN_num_bits(q); | |
167 | ||
168 | /* | |
4605c5ab | 169 | * For Digital signature verification DSA keys with < 112 bits of |
71cf587e P |
170 | * security strength, are still allowed for legacy |
171 | * use. The bounds given in SP 800-131Ar2 - Table 2 are | |
172 | * (512 <= L < 2048 or 160 <= N < 224). | |
173 | * | |
174 | * We are a little stricter and insist that both minimums are met. | |
175 | * For example a L = 256, N = 160 key *would* be allowed by SP 800-131Ar2 | |
176 | * but we don't. | |
7a810fac | 177 | */ |
71cf587e P |
178 | if (!sign) { |
179 | if (L < 512 || N < 160) | |
180 | return 0; | |
181 | if (L < 2048 || N < 224) | |
182 | return 1; | |
183 | } | |
7a810fac SL |
184 | |
185 | /* Valid sizes for both sign and verify */ | |
71cf587e | 186 | if (L == 2048 && (N == 224 || N == 256)) /* 112 bits */ |
7a810fac | 187 | return 1; |
71cf587e | 188 | return (L == 3072 && N == 256); /* 128 bits */ |
7a810fac SL |
189 | } |
190 | # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ | |
191 | return 1; | |
192 | } | |
193 | #endif /* OPENSSL_NO_DSA */ | |
194 | ||
195 | #ifndef OPENSSL_NO_DH | |
196 | /* | |
197 | * For DH key agreement refer to SP800-56A | |
198 | * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf | |
199 | * "Section 5.5.1.1FFC Domain Parameter Selection/Generation" and | |
200 | * "Appendix D" FFC Safe-prime Groups | |
201 | */ | |
6ce58488 | 202 | int ossl_dh_check_key(OSSL_LIB_CTX *ctx, const DH *dh) |
7a810fac SL |
203 | { |
204 | # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) | |
6ce58488 | 205 | if (ossl_securitycheck_enabled(ctx)) { |
7a810fac SL |
206 | size_t L, N; |
207 | const BIGNUM *p, *q; | |
208 | ||
209 | if (dh == NULL) | |
210 | return 0; | |
211 | ||
212 | p = DH_get0_p(dh); | |
213 | q = DH_get0_q(dh); | |
214 | if (p == NULL || q == NULL) | |
215 | return 0; | |
216 | ||
217 | L = BN_num_bits(p); | |
218 | if (L < 2048) | |
219 | return 0; | |
220 | ||
221 | /* If it is a safe prime group then it is ok */ | |
222 | if (DH_get_nid(dh)) | |
223 | return 1; | |
224 | ||
225 | /* If not then it must be FFC, which only allows certain sizes. */ | |
226 | N = BN_num_bits(q); | |
227 | ||
228 | return (L == 2048 && (N == 224 || N == 256)); | |
229 | } | |
230 | # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ | |
231 | return 1; | |
232 | } | |
233 | #endif /* OPENSSL_NO_DH */ | |
234 | ||
6ce58488 MC |
235 | int ossl_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md, |
236 | int sha1_allowed) | |
7a810fac | 237 | { |
7b676cc8 | 238 | int mdnid = ossl_digest_get_approved_nid(md); |
7a810fac SL |
239 | |
240 | # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) | |
6ce58488 | 241 | if (ossl_securitycheck_enabled(ctx)) { |
6a2ab4a9 TM |
242 | if (mdnid == NID_undef || (mdnid == NID_sha1 && !sha1_allowed)) |
243 | mdnid = -1; /* disallowed by security checks */ | |
7a810fac SL |
244 | } |
245 | # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ | |
246 | return mdnid; | |
247 | } | |
248 | ||
6ce58488 | 249 | int ossl_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md) |
7a810fac SL |
250 | { |
251 | # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) | |
6ce58488 | 252 | if (ossl_securitycheck_enabled(ctx)) |
7b676cc8 | 253 | return ossl_digest_get_approved_nid(md) != NID_undef; |
7a810fac SL |
254 | # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ |
255 | return 1; | |
256 | } |