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