1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h>
11e1051a39Sopenharmony_ci#include "prov/seeding.h"
12e1051a39Sopenharmony_ci
13e1051a39Sopenharmony_cistatic OSSL_FUNC_get_entropy_fn *c_get_entropy = NULL;
14e1051a39Sopenharmony_cistatic OSSL_FUNC_cleanup_entropy_fn *c_cleanup_entropy = NULL;
15e1051a39Sopenharmony_cistatic OSSL_FUNC_get_nonce_fn *c_get_nonce = NULL;
16e1051a39Sopenharmony_cistatic OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL;
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ciint ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns)
19e1051a39Sopenharmony_ci{
20e1051a39Sopenharmony_ci    for (; fns->function_id != 0; fns++) {
21e1051a39Sopenharmony_ci        /*
22e1051a39Sopenharmony_ci         * We do not support the scenario of an application linked against
23e1051a39Sopenharmony_ci         * multiple versions of libcrypto (e.g. one static and one dynamic), but
24e1051a39Sopenharmony_ci         * sharing a single fips.so. We do a simple sanity check here.
25e1051a39Sopenharmony_ci         */
26e1051a39Sopenharmony_ci#define set_func(c, f) \
27e1051a39Sopenharmony_ci    do { if (c == NULL) c = f; else if (c != f) return 0; } while (0)
28e1051a39Sopenharmony_ci        switch (fns->function_id) {
29e1051a39Sopenharmony_ci        case OSSL_FUNC_GET_ENTROPY:
30e1051a39Sopenharmony_ci            set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns));
31e1051a39Sopenharmony_ci            break;
32e1051a39Sopenharmony_ci        case OSSL_FUNC_CLEANUP_ENTROPY:
33e1051a39Sopenharmony_ci            set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns));
34e1051a39Sopenharmony_ci            break;
35e1051a39Sopenharmony_ci        case OSSL_FUNC_GET_NONCE:
36e1051a39Sopenharmony_ci            set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns));
37e1051a39Sopenharmony_ci            break;
38e1051a39Sopenharmony_ci        case OSSL_FUNC_CLEANUP_NONCE:
39e1051a39Sopenharmony_ci            set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns));
40e1051a39Sopenharmony_ci            break;
41e1051a39Sopenharmony_ci        }
42e1051a39Sopenharmony_ci#undef set_func
43e1051a39Sopenharmony_ci    }
44e1051a39Sopenharmony_ci    return 1;
45e1051a39Sopenharmony_ci}
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_cisize_t ossl_prov_get_entropy(PROV_CTX *prov_ctx, unsigned char **pout,
48e1051a39Sopenharmony_ci                             int entropy, size_t min_len, size_t max_len)
49e1051a39Sopenharmony_ci{
50e1051a39Sopenharmony_ci    if (c_get_entropy == NULL)
51e1051a39Sopenharmony_ci        return 0;
52e1051a39Sopenharmony_ci    return c_get_entropy(ossl_prov_ctx_get0_handle(prov_ctx),
53e1051a39Sopenharmony_ci                         pout, entropy, min_len, max_len);
54e1051a39Sopenharmony_ci}
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_civoid ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf,
57e1051a39Sopenharmony_ci                               size_t len)
58e1051a39Sopenharmony_ci{
59e1051a39Sopenharmony_ci    if (c_cleanup_entropy != NULL)
60e1051a39Sopenharmony_ci        c_cleanup_entropy(ossl_prov_ctx_get0_handle(prov_ctx), buf, len);
61e1051a39Sopenharmony_ci}
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_cisize_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout,
64e1051a39Sopenharmony_ci                           size_t min_len, size_t max_len,
65e1051a39Sopenharmony_ci                           const void *salt,size_t salt_len)
66e1051a39Sopenharmony_ci{
67e1051a39Sopenharmony_ci    if (c_get_nonce == NULL)
68e1051a39Sopenharmony_ci        return 0;
69e1051a39Sopenharmony_ci    return c_get_nonce(ossl_prov_ctx_get0_handle(prov_ctx), pout,
70e1051a39Sopenharmony_ci                       min_len, max_len, salt, salt_len);
71e1051a39Sopenharmony_ci}
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_civoid ossl_prov_cleanup_nonce(PROV_CTX *prov_ctx, unsigned char *buf, size_t len)
74e1051a39Sopenharmony_ci{
75e1051a39Sopenharmony_ci    if (c_cleanup_nonce != NULL)
76e1051a39Sopenharmony_ci        c_cleanup_nonce(ossl_prov_ctx_get0_handle(prov_ctx), buf, len);
77e1051a39Sopenharmony_ci}
78