]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/common/securitycheck.c
Update copyright year
[thirdparty/openssl.git] / providers / common / securitycheck.c
CommitLineData
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 28int 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 55int 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 113int 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 157int 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 190int 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 203int 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}