xref: /freebsd/crypto/openssl/providers/fips/include/fips/fipsindicator.h (revision e7be843b4a162e68651d3911f0357ed464915629)
1 /*
2  * Copyright 2023-2024 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 #ifdef FIPS_MODULE
11 
12 # include <openssl/core.h> /* OSSL_CALLBACK, OSSL_LIB_CTX */
13 # include <openssl/indicator.h>
14 # include "crypto/types.h"
15 # include <openssl/ec.h>
16 # include "fipscommon.h"
17 
18 /*
19  * There may be multiple settables associated with an algorithm that allow
20  * overriding the default status.
21  * We associate an id with each of these.
22  */
23 # define OSSL_FIPS_IND_SETTABLE0 0
24 # define OSSL_FIPS_IND_SETTABLE1 1
25 # define OSSL_FIPS_IND_SETTABLE2 2
26 # define OSSL_FIPS_IND_SETTABLE3 3
27 # define OSSL_FIPS_IND_SETTABLE4 4
28 # define OSSL_FIPS_IND_SETTABLE5 5
29 # define OSSL_FIPS_IND_SETTABLE6 6
30 # define OSSL_FIPS_IND_SETTABLE7 7
31 # define OSSL_FIPS_IND_SETTABLE_MAX (1 + OSSL_FIPS_IND_SETTABLE7)
32 
33 /* Each settable is in one of 3 states */
34 #define OSSL_FIPS_IND_STATE_UNKNOWN    -1  /* Initial unknown state */
35 #define OSSL_FIPS_IND_STATE_STRICT      1  /* Strict enforcement */
36 #define OSSL_FIPS_IND_STATE_TOLERANT    0  /* Relaxation of rules */
37 
38 /*
39  * For each algorithm context there may be multiple checks that determine if
40  * the algorithm is approved or not. These checks may be in different stages.
41  * To keep it simple it is assumed that the algorithm is initially approved,
42  * and may be unapproved when each check happens. Once unapproved the operation
43  * will remain unapproved (otherwise we need to maintain state for each check).
44  * The approved state should only be queried after the operation has completed
45  * e.g. A digest final, or a KDF derive.
46  *
47  * If a FIPS approved check fails then we must decide what to do in this case.
48  * In strict mode we would just return an error.
49  * To override strict mode we either need to have a settable variable or have a
50  * fips config flag that overrides strict mode.
51  * If there are multiple checks, each one could possible have a different
52  * configurable item. Each configurable item can be overridden by a different
53  * settable.
54  */
55 typedef struct ossl_fips_ind_st {
56     unsigned char approved;
57     signed char settable[OSSL_FIPS_IND_SETTABLE_MAX]; /* See OSSL_FIPS_IND_STATE */
58 } OSSL_FIPS_IND;
59 
60 typedef int (OSSL_FIPS_IND_CHECK_CB)(OSSL_LIB_CTX *libctx);
61 
62 int ossl_FIPS_IND_callback(OSSL_LIB_CTX *libctx, const char *type,
63                            const char *desc);
64 
65 void ossl_FIPS_IND_init(OSSL_FIPS_IND *ind);
66 void ossl_FIPS_IND_set_approved(OSSL_FIPS_IND *ind);
67 void ossl_FIPS_IND_set_settable(OSSL_FIPS_IND *ind, int id, int enable);
68 int ossl_FIPS_IND_get_settable(const OSSL_FIPS_IND *ind, int id);
69 int ossl_FIPS_IND_on_unapproved(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx,
70                                 const char *algname, const char *opname,
71                                 OSSL_FIPS_IND_CHECK_CB *config_check_fn);
72 int ossl_FIPS_IND_set_ctx_param(OSSL_FIPS_IND *ind, int id,
73                                 const OSSL_PARAM params[], const char *name);
74 int ossl_FIPS_IND_get_ctx_param(const OSSL_FIPS_IND *ind,
75                                       OSSL_PARAM params[]);
76 void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src);
77 
78 /* Place this in the algorithm ctx structure */
79 # define OSSL_FIPS_IND_DECLARE OSSL_FIPS_IND indicator;
80 /* Call this to initialize the indicator */
81 # define OSSL_FIPS_IND_INIT(ctx) ossl_FIPS_IND_init(&ctx->indicator);
82 /*
83  * Use the copy if an algorithm has a dup function that does not copy the src to
84  * the dst.
85  */
86 # define OSSL_FIPS_IND_COPY(dst, src) ossl_FIPS_IND_copy(&dst->indicator, &src->indicator);
87 
88 /*
89  * Required for reset - since once something becomes unapproved it will remain
90  * unapproved unless this is used. This should be used in the init before
91  * params are set into the ctx & before any FIPS checks are done.
92  */
93 # define OSSL_FIPS_IND_SET_APPROVED(ctx) ossl_FIPS_IND_set_approved(&ctx->indicator);
94 /*
95  * This should be called if a FIPS check fails, to indicate the operation is not approved
96  * If there is more than 1 strict check flag per algorithm ctx, the id represents
97  * the index.
98  */
99 # define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, config_check_fn) \
100     ossl_FIPS_IND_on_unapproved(&ctx->indicator, id, libctx, algname, opname, config_check_fn)
101 
102 # define OSSL_FIPS_IND_SETTABLE_CTX_PARAM(name) \
103     OSSL_PARAM_int(name, NULL),
104 
105 /*
106  * The id here must match the one used by OSSL_FIPS_IND_ON_UNAPPROVED
107  * The name must match the param used by OSSL_FIPS_IND_SETTABLE_CTX_PARAM
108  */
109 # define OSSL_FIPS_IND_SET_CTX_PARAM(ctx, id, params, name) \
110     ossl_FIPS_IND_set_ctx_param(&((ctx)->indicator), id, params, name)
111 
112 # define OSSL_FIPS_IND_GETTABLE_CTX_PARAM() \
113     OSSL_PARAM_int(OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR, NULL),
114 
115 # define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, prms) \
116     ossl_FIPS_IND_get_ctx_param(&((ctx)->indicator), prms)
117 
118 # define OSSL_FIPS_IND_GET(ctx) (&((ctx)->indicator))
119 
120 # define OSSL_FIPS_IND_GET_PARAM(ctx, p, settable, id, name)                   \
121     *settable = ossl_FIPS_IND_get_settable(&((ctx)->indicator), id);           \
122     if (*settable != OSSL_FIPS_IND_STATE_UNKNOWN)                              \
123         *p = OSSL_PARAM_construct_int(name, settable);
124 
125 int ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx,
126                                 const RSA *rsa, const char *desc, int protect);
127 # ifndef OPENSSL_NO_EC
128 int ossl_fips_ind_ec_key_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx,
129                                const EC_GROUP *group, const char *desc,
130                                int protect);
131 # endif
132 int ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx,
133                                     const EVP_MD *md, const char *desc);
134 int ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND *ind, int id,
135                                     OSSL_LIB_CTX *libctx,
136                                     int nid, int sha1_allowed,
137                                     const char *desc,
138                                     OSSL_FIPS_IND_CHECK_CB *config_check_f);
139 
140 #else
141 # define OSSL_FIPS_IND_DECLARE
142 # define OSSL_FIPS_IND_INIT(ctx)
143 # define OSSL_FIPS_IND_SET_APPROVED(ctx)
144 # define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, configopt_fn)
145 # define OSSL_FIPS_IND_SETTABLE_CTX_PARAM(name)
146 # define OSSL_FIPS_IND_SET_CTX_PARAM(ctx, id, params, name) 1
147 # define OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
148 # define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params) 1
149 # define OSSL_FIPS_IND_COPY(dst, src)
150 
151 #endif
152