1 /*
2 * Copyright 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 #include <openssl/indicator.h>
11 #include <openssl/params.h>
12 #include <openssl/core_names.h>
13 #include "internal/common.h" /* for ossl_assert() */
14 #include "fips/fipsindicator.h"
15
ossl_FIPS_IND_init(OSSL_FIPS_IND * ind)16 void ossl_FIPS_IND_init(OSSL_FIPS_IND *ind)
17 {
18 int i;
19
20 ossl_FIPS_IND_set_approved(ind); /* Assume we are approved by default */
21 for (i = 0; i < OSSL_FIPS_IND_SETTABLE_MAX; i++)
22 ind->settable[i] = OSSL_FIPS_IND_STATE_UNKNOWN;
23 }
24
ossl_FIPS_IND_set_approved(OSSL_FIPS_IND * ind)25 void ossl_FIPS_IND_set_approved(OSSL_FIPS_IND *ind)
26 {
27 ind->approved = 1;
28 }
29
ossl_FIPS_IND_copy(OSSL_FIPS_IND * dst,const OSSL_FIPS_IND * src)30 void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src)
31 {
32 *dst = *src;
33 }
34
ossl_FIPS_IND_set_settable(OSSL_FIPS_IND * ind,int id,int state)35 void ossl_FIPS_IND_set_settable(OSSL_FIPS_IND *ind, int id, int state)
36 {
37 if (!ossl_assert(id < OSSL_FIPS_IND_SETTABLE_MAX))
38 return;
39 if (!ossl_assert(state == OSSL_FIPS_IND_STATE_STRICT
40 || state == OSSL_FIPS_IND_STATE_TOLERANT))
41 return;
42 ind->settable[id] = state;
43 }
44
ossl_FIPS_IND_get_settable(const OSSL_FIPS_IND * ind,int id)45 int ossl_FIPS_IND_get_settable(const OSSL_FIPS_IND *ind, int id)
46 {
47 if (!ossl_assert(id < OSSL_FIPS_IND_SETTABLE_MAX))
48 return OSSL_FIPS_IND_STATE_UNKNOWN;
49 return ind->settable[id];
50 }
51
52 /*
53 * This should only be called when a strict FIPS algorithm check fails.
54 * It assumes that we are in strict mode by default.
55 * If the logic here is not sufficient for all cases, then additional
56 * ossl_FIPS_IND_on_unapproved() functions may be required.
57 */
ossl_FIPS_IND_on_unapproved(OSSL_FIPS_IND * ind,int id,OSSL_LIB_CTX * libctx,const char * algname,const char * opname,OSSL_FIPS_IND_CHECK_CB * config_check_fn)58 int ossl_FIPS_IND_on_unapproved(OSSL_FIPS_IND *ind, int id,
59 OSSL_LIB_CTX *libctx,
60 const char *algname, const char *opname,
61 OSSL_FIPS_IND_CHECK_CB *config_check_fn)
62 {
63 /* Set to unapproved. Once unapproved mode is set this will not be reset */
64 ind->approved = 0;
65
66 /*
67 * We only trigger the indicator callback if the ctx variable is cleared OR
68 * the configurable item is cleared. If the values are unknown they are
69 * assumed to be strict.
70 */
71 if (ossl_FIPS_IND_get_settable(ind, id) == OSSL_FIPS_IND_STATE_TOLERANT
72 || (config_check_fn != NULL
73 && config_check_fn(libctx) == OSSL_FIPS_IND_STATE_TOLERANT)) {
74 return ossl_FIPS_IND_callback(libctx, algname, opname);
75 }
76 /* Strict mode gets here: This returns an error */
77 return 0;
78 }
79
ossl_FIPS_IND_set_ctx_param(OSSL_FIPS_IND * ind,int id,const OSSL_PARAM params[],const char * name)80 int ossl_FIPS_IND_set_ctx_param(OSSL_FIPS_IND *ind, int id,
81 const OSSL_PARAM params[], const char *name)
82 {
83 int in = 0;
84 const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name);
85
86 if (p != NULL) {
87 if (!OSSL_PARAM_get_int(p, &in))
88 return 0;
89 ossl_FIPS_IND_set_settable(ind, id, in);
90 }
91 return 1;
92 }
93
ossl_FIPS_IND_get_ctx_param(const OSSL_FIPS_IND * ind,OSSL_PARAM params[])94 int ossl_FIPS_IND_get_ctx_param(const OSSL_FIPS_IND *ind, OSSL_PARAM params[])
95 {
96 OSSL_PARAM *p = OSSL_PARAM_locate(params, OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR);
97
98 return p == NULL || OSSL_PARAM_set_int(p, ind->approved);
99 }
100
101 /*
102 * Can be used during application testing to log that an indicator was
103 * triggered. The callback will return 1 if the application wants an error
104 * to occur based on the indicator type and description.
105 */
ossl_FIPS_IND_callback(OSSL_LIB_CTX * libctx,const char * type,const char * desc)106 int ossl_FIPS_IND_callback(OSSL_LIB_CTX *libctx, const char *type,
107 const char *desc)
108 {
109 OSSL_INDICATOR_CALLBACK *cb = NULL;
110
111 OSSL_INDICATOR_get_callback(libctx, &cb);
112 if (cb == NULL)
113 return 1;
114
115 return cb(type, desc, NULL);
116 }
117