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 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 25 void ossl_FIPS_IND_set_approved(OSSL_FIPS_IND *ind) 26 { 27 ind->approved = 1; 28 } 29 30 void ossl_FIPS_IND_copy(OSSL_FIPS_IND *dst, const OSSL_FIPS_IND *src) 31 { 32 *dst = *src; 33 } 34 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 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 */ 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 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 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 */ 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