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