1a8e1175bSopenharmony_ci/** \file psa_crypto_random_impl.h
2a8e1175bSopenharmony_ci *
3a8e1175bSopenharmony_ci * \brief PSA crypto random generator implementation abstraction.
4a8e1175bSopenharmony_ci */
5a8e1175bSopenharmony_ci/*
6a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
7a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8a8e1175bSopenharmony_ci */
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci#ifndef PSA_CRYPTO_RANDOM_IMPL_H
11a8e1175bSopenharmony_ci#define PSA_CRYPTO_RANDOM_IMPL_H
12a8e1175bSopenharmony_ci
13a8e1175bSopenharmony_ci#include "psa_util_internal.h"
14a8e1175bSopenharmony_ci
15a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
16a8e1175bSopenharmony_ci
17a8e1175bSopenharmony_citypedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
18a8e1175bSopenharmony_ci
19a8e1175bSopenharmony_ci#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
20a8e1175bSopenharmony_ci
21a8e1175bSopenharmony_ci#include "mbedtls/entropy.h"
22a8e1175bSopenharmony_ci
23a8e1175bSopenharmony_ci/* Choose a DRBG based on configuration and availability */
24a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
25a8e1175bSopenharmony_ci
26a8e1175bSopenharmony_ci#include "mbedtls/hmac_drbg.h"
27a8e1175bSopenharmony_ci
28a8e1175bSopenharmony_ci#elif defined(MBEDTLS_CTR_DRBG_C)
29a8e1175bSopenharmony_ci
30a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h"
31a8e1175bSopenharmony_ci
32a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
33a8e1175bSopenharmony_ci
34a8e1175bSopenharmony_ci#include "mbedtls/hmac_drbg.h"
35a8e1175bSopenharmony_ci#if defined(MBEDTLS_MD_CAN_SHA512) && defined(MBEDTLS_MD_CAN_SHA256)
36a8e1175bSopenharmony_ci#include <limits.h>
37a8e1175bSopenharmony_ci#if SIZE_MAX > 0xffffffff
38a8e1175bSopenharmony_ci/* Looks like a 64-bit system, so prefer SHA-512. */
39a8e1175bSopenharmony_ci#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
40a8e1175bSopenharmony_ci#else
41a8e1175bSopenharmony_ci/* Looks like a 32-bit system, so prefer SHA-256. */
42a8e1175bSopenharmony_ci#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
43a8e1175bSopenharmony_ci#endif
44a8e1175bSopenharmony_ci#elif defined(MBEDTLS_MD_CAN_SHA512)
45a8e1175bSopenharmony_ci#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
46a8e1175bSopenharmony_ci#elif defined(MBEDTLS_MD_CAN_SHA256)
47a8e1175bSopenharmony_ci#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
48a8e1175bSopenharmony_ci#else
49a8e1175bSopenharmony_ci#error "No hash algorithm available for HMAC_DBRG."
50a8e1175bSopenharmony_ci#endif
51a8e1175bSopenharmony_ci
52a8e1175bSopenharmony_ci#else /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
53a8e1175bSopenharmony_ci
54a8e1175bSopenharmony_ci#error "No DRBG module available for the psa_crypto module."
55a8e1175bSopenharmony_ci
56a8e1175bSopenharmony_ci#endif /* !MBEDTLS_PSA_HMAC_DRBG_MD_TYPE && !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
57a8e1175bSopenharmony_ci
58a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C)
59a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h"
60a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
61a8e1175bSopenharmony_ci#include "mbedtls/hmac_drbg.h"
62a8e1175bSopenharmony_ci#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
63a8e1175bSopenharmony_ci
64a8e1175bSopenharmony_ci/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
65a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C)
66a8e1175bSopenharmony_ci#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
67a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
68a8e1175bSopenharmony_ci#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
69a8e1175bSopenharmony_ci#endif
70a8e1175bSopenharmony_ci
71a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C)
72a8e1175bSopenharmony_citypedef mbedtls_ctr_drbg_context            mbedtls_psa_drbg_context_t;
73a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
74a8e1175bSopenharmony_citypedef mbedtls_hmac_drbg_context           mbedtls_psa_drbg_context_t;
75a8e1175bSopenharmony_ci#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
76a8e1175bSopenharmony_ci
77a8e1175bSopenharmony_citypedef struct {
78a8e1175bSopenharmony_ci    void (* entropy_init)(mbedtls_entropy_context *ctx);
79a8e1175bSopenharmony_ci    void (* entropy_free)(mbedtls_entropy_context *ctx);
80a8e1175bSopenharmony_ci    mbedtls_entropy_context entropy;
81a8e1175bSopenharmony_ci    mbedtls_psa_drbg_context_t drbg;
82a8e1175bSopenharmony_ci} mbedtls_psa_random_context_t;
83a8e1175bSopenharmony_ci
84a8e1175bSopenharmony_ci/** Initialize the PSA DRBG.
85a8e1175bSopenharmony_ci *
86a8e1175bSopenharmony_ci * \param p_rng        Pointer to the Mbed TLS DRBG state.
87a8e1175bSopenharmony_ci */
88a8e1175bSopenharmony_cistatic inline void mbedtls_psa_drbg_init(mbedtls_psa_drbg_context_t *p_rng)
89a8e1175bSopenharmony_ci{
90a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C)
91a8e1175bSopenharmony_ci    mbedtls_ctr_drbg_init(p_rng);
92a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
93a8e1175bSopenharmony_ci    mbedtls_hmac_drbg_init(p_rng);
94a8e1175bSopenharmony_ci#endif
95a8e1175bSopenharmony_ci}
96a8e1175bSopenharmony_ci
97a8e1175bSopenharmony_ci/** Deinitialize the PSA DRBG.
98a8e1175bSopenharmony_ci *
99a8e1175bSopenharmony_ci * \param p_rng        Pointer to the Mbed TLS DRBG state.
100a8e1175bSopenharmony_ci */
101a8e1175bSopenharmony_cistatic inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng)
102a8e1175bSopenharmony_ci{
103a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C)
104a8e1175bSopenharmony_ci    mbedtls_ctr_drbg_free(p_rng);
105a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
106a8e1175bSopenharmony_ci    mbedtls_hmac_drbg_free(p_rng);
107a8e1175bSopenharmony_ci#endif
108a8e1175bSopenharmony_ci}
109a8e1175bSopenharmony_ci
110a8e1175bSopenharmony_ci/** Seed the PSA DRBG.
111a8e1175bSopenharmony_ci *
112a8e1175bSopenharmony_ci * \param entropy       An entropy context to read the seed from.
113a8e1175bSopenharmony_ci * \param custom        The personalization string.
114a8e1175bSopenharmony_ci *                      This can be \c NULL, in which case the personalization
115a8e1175bSopenharmony_ci *                      string is empty regardless of the value of \p len.
116a8e1175bSopenharmony_ci * \param len           The length of the personalization string.
117a8e1175bSopenharmony_ci *
118a8e1175bSopenharmony_ci * \return              \c 0 on success.
119a8e1175bSopenharmony_ci * \return              An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
120a8e1175bSopenharmony_ci */
121a8e1175bSopenharmony_cistatic inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx,
122a8e1175bSopenharmony_ci                                        mbedtls_entropy_context *entropy,
123a8e1175bSopenharmony_ci                                        const unsigned char *custom, size_t len)
124a8e1175bSopenharmony_ci{
125a8e1175bSopenharmony_ci#if defined(MBEDTLS_CTR_DRBG_C)
126a8e1175bSopenharmony_ci    return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len);
127a8e1175bSopenharmony_ci#elif defined(MBEDTLS_HMAC_DRBG_C)
128a8e1175bSopenharmony_ci    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
129a8e1175bSopenharmony_ci    return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len);
130a8e1175bSopenharmony_ci#endif
131a8e1175bSopenharmony_ci}
132a8e1175bSopenharmony_ci
133a8e1175bSopenharmony_ci#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
134a8e1175bSopenharmony_ci
135a8e1175bSopenharmony_ci#endif /* PSA_CRYPTO_RANDOM_IMPL_H */
136