Home | History | Annotate | Line # | Download | only in fips
      1 /*
      2  * Copyright 2023-2025 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     int sha512_trunc_allowed,
    138     const char *desc,
    139     OSSL_FIPS_IND_CHECK_CB *config_check_f);
    140 
    141 #else
    142 #define OSSL_FIPS_IND_DECLARE
    143 #define OSSL_FIPS_IND_INIT(ctx)
    144 #define OSSL_FIPS_IND_SET_APPROVED(ctx)
    145 #define OSSL_FIPS_IND_ON_UNAPPROVED(ctx, id, libctx, algname, opname, configopt_fn)
    146 #define OSSL_FIPS_IND_SETTABLE_CTX_PARAM(name)
    147 #define OSSL_FIPS_IND_SET_CTX_PARAM(ctx, id, params, name) 1
    148 #define OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
    149 #define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params) 1
    150 #define OSSL_FIPS_IND_COPY(dst, src)
    151 
    152 #endif
    153