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