Home | History | Annotate | Line # | Download | only in fips
fipsindicator.c revision 1.1.1.2
      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