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