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, const OSSL_PARAM *p); 73 int ossl_FIPS_IND_set_ctx_param_locate(OSSL_FIPS_IND *ind, int id, 74 const OSSL_PARAM params[], 75 const char *name); 76 int ossl_FIPS_IND_get_ctx_param(const OSSL_FIPS_IND *ind, 77 OSSL_PARAM *p); 78 int ossl_FIPS_IND_get_ctx_param_locate(const OSSL_FIPS_IND *ind, 79 OSSL_PARAM params[]); 80 void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src); 81 82 /* Place this in the algorithm ctx structure */ 83 # define OSSL_FIPS_IND_DECLARE OSSL_FIPS_IND indicator; 84 /* Call this to initialize the indicator */ 85 # define OSSL_FIPS_IND_INIT(ctx) ossl_FIPS_IND_init(&ctx->indicator); 86 /* 87 * Use the copy if an algorithm has a dup function that does not copy the src to 88 * the dst. 89 */ 90 # define OSSL_FIPS_IND_COPY(dst, src) ossl_FIPS_IND_copy(&dst->indicator, &src->indicator); 91 92 /* 93 * Required for reset - since once something becomes unapproved it will remain 94 * unapproved unless this is used. This should be used in the init before 95 * params are set into the ctx & before any FIPS checks are done. 96 */ 97 # define OSSL_FIPS_IND_SET_APPROVED(ctx) ossl_FIPS_IND_set_approved(&ctx->indicator); 98 /* 99 * This should be called if a FIPS check fails, to indicate the operation is not approved 100 * If there is more than 1 strict check flag per algorithm ctx, the id represents 101 * the index. 102 */ 103 # define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, config_check_fn) \ 104 ossl_FIPS_IND_on_unapproved(&ctx->indicator, id, libctx, algname, opname, config_check_fn) 105 106 # define OSSL_FIPS_IND_SETTABLE_CTX_PARAM(name) \ 107 OSSL_PARAM_int(name, NULL), 108 109 /* 110 * The id here must match the one used by OSSL_FIPS_IND_ON_UNAPPROVED 111 * The name must match the param used by OSSL_FIPS_IND_SETTABLE_CTX_PARAM 112 */ 113 # define OSSL_FIPS_IND_SET_CTX_PARAM(ctx, id, params, name) \ 114 ossl_FIPS_IND_set_ctx_param_locate(&((ctx)->indicator), id, params, name) 115 116 # define OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, id, p) \ 117 ossl_FIPS_IND_set_ctx_param(&((ctx)->indicator), id, p) 118 119 # define OSSL_FIPS_IND_GETTABLE_CTX_PARAM() \ 120 OSSL_PARAM_int(OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR, NULL), 121 122 # define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, prms) \ 123 ossl_FIPS_IND_get_ctx_param_locate(&((ctx)->indicator), prms) 124 125 # define OSSL_FIPS_IND_GET_CTX_FROM_PARAM(ctx, p) \ 126 ossl_FIPS_IND_get_ctx_param(&((ctx)->indicator), p) 127 128 # define OSSL_FIPS_IND_GET(ctx) (&((ctx)->indicator)) 129 130 # define OSSL_FIPS_IND_GET_PARAM(ctx, p, settable, id, name) \ 131 *settable = ossl_FIPS_IND_get_settable(&((ctx)->indicator), id); \ 132 if (*settable != OSSL_FIPS_IND_STATE_UNKNOWN) \ 133 *p = OSSL_PARAM_construct_int(name, settable); 134 135 int ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx, 136 const RSA *rsa, const char *desc, int protect); 137 # ifndef OPENSSL_NO_EC 138 int ossl_fips_ind_ec_key_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx, 139 const EC_GROUP *group, const char *desc, 140 int protect); 141 # endif 142 int ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx, 143 const EVP_MD *md, const char *desc); 144 int ossl_fips_ind_digest_sign_check(OSSL_FIPS_IND *ind, int id, 145 OSSL_LIB_CTX *libctx, 146 int nid, int sha1_allowed, 147 const char *desc, 148 OSSL_FIPS_IND_CHECK_CB *config_check_f); 149 150 #else 151 # define OSSL_FIPS_IND_DECLARE 152 # define OSSL_FIPS_IND_INIT(ctx) 153 # define OSSL_FIPS_IND_SET_APPROVED(ctx) 154 # define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, configopt_fn) 155 # define OSSL_FIPS_IND_SETTABLE_CTX_PARAM(name) 156 # define OSSL_FIPS_IND_SET_CTX_PARAM(ctx, id, params, name) 1 157 # define OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, id, p) 1 158 # define OSSL_FIPS_IND_GETTABLE_CTX_PARAM() 159 # define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params) 1 160 # define OSSL_FIPS_IND_GET_CTX_FROM_PARAM(ctx, params) 1 161 # define OSSL_FIPS_IND_COPY(dst, src) 162 163 #endif 164