/*
 * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/self_test.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include "internal/cryptlib.h"
#include "crypto/context.h"

typedef struct self_test_cb_st
{
    OSSL_CALLBACK *cb;
    void *cbarg;
} SELF_TEST_CB;

struct ossl_self_test_st
{
    /* local state variables */
    const char *phase;
    const char *type;
    const char *desc;
    OSSL_CALLBACK *cb;

    /* callback related variables used to pass the state back to the user */
    OSSL_PARAM params[4];
    void *cb_arg;
};

#ifndef FIPS_MODULE
void *ossl_self_test_set_callback_new(OSSL_LIB_CTX *ctx)
{
    SELF_TEST_CB *stcb;

    stcb = OPENSSL_zalloc(sizeof(*stcb));
    return stcb;
}

void ossl_self_test_set_callback_free(void *stcb)
{
    OPENSSL_free(stcb);
}

static SELF_TEST_CB *get_self_test_callback(OSSL_LIB_CTX *libctx)
{
    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SELF_TEST_CB_INDEX);
}

void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb,
                                 void *cbarg)
{
    SELF_TEST_CB *stcb = get_self_test_callback(libctx);

    if (stcb != NULL) {
        stcb->cb = cb;
        stcb->cbarg = cbarg;
    }
}

void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb,
                                 void **cbarg)
{
    SELF_TEST_CB *stcb = get_self_test_callback(libctx);

    if (cb != NULL)
        *cb = (stcb != NULL ? stcb->cb : NULL);
    if (cbarg != NULL)
        *cbarg = (stcb != NULL ? stcb->cbarg : NULL);
}
#endif /* FIPS_MODULE */

static void self_test_setparams(OSSL_SELF_TEST *st)
{
    size_t n = 0;

    if (st->cb != NULL) {
        st->params[n++] =
            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE,
                                             (char *)st->phase, 0);
        st->params[n++] =
            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE,
                                             (char *)st->type, 0);
        st->params[n++] =
            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC,
                                             (char *)st->desc, 0);
    }
    st->params[n++] = OSSL_PARAM_construct_end();
}

OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg)
{
    OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret));

    if (ret == NULL)
        return NULL;

    ret->cb = cb;
    ret->cb_arg = cbarg;
    ret->phase = "";
    ret->type = "";
    ret->desc = "";
    self_test_setparams(ret);
    return ret;
}

void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st)
{
    OPENSSL_free(st);
}

/* Can be used during application testing to log that a test has started. */
void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
                            const char *desc)
{
    if (st != NULL && st->cb != NULL) {
        st->phase = OSSL_SELF_TEST_PHASE_START;
        st->type = type;
        st->desc = desc;
        self_test_setparams(st);
        (void)st->cb(st->params, st->cb_arg);
    }
}

/*
 * Can be used during application testing to log that a test has either
 * passed or failed.
 */
void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret)
{
    if (st != NULL && st->cb != NULL) {
        st->phase =
            (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL);
        self_test_setparams(st);
        (void)st->cb(st->params, st->cb_arg);

        st->phase = OSSL_SELF_TEST_PHASE_NONE;
        st->type = OSSL_SELF_TEST_TYPE_NONE;
        st->desc = OSSL_SELF_TEST_DESC_NONE;
    }
}

/*
 * Used for failure testing.
 *
 * Call the applications SELF_TEST_cb() if it exists.
 * If the application callback decides to return 0 then the first byte of 'bytes'
 * is modified (corrupted). This is used to modify output signatures or
 * ciphertext before they are verified or decrypted.
 */
int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes)
{
    if (st != NULL && st->cb != NULL) {
        st->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
        self_test_setparams(st);
        if (!st->cb(st->params, st->cb_arg)) {
            bytes[0] ^= 1;
            return 1;
        }
    }
    return 0;
}
