1 /** \file psa_crypto_random_impl.h
3 * \brief PSA crypto random generator implementation abstraction.
5 * The definitions here need to be consistent with the declarations
6 * in include/mbedtls/psa_util.h. This file contains some redundant
7 * declarations to increase the chance that a compiler will detect
8 * inconsistencies if one file is changed without updating the other,
9 * but not all potential inconsistencies can be enforced, so make sure
10 * to check the public declarations and contracts in
11 * include/mbedtls/psa_util.h if you modify this file.
14 * Copyright The Mbed TLS Contributors
15 * SPDX-License-Identifier: Apache-2.0
17 * Licensed under the Apache License, Version 2.0 (the "License"); you may
18 * not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
21 * http://www.apache.org/licenses/LICENSE-2.0
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
30 #ifndef PSA_CRYPTO_RANDOM_IMPL_H
31 #define PSA_CRYPTO_RANDOM_IMPL_H
33 #include <mbedtls/psa_util.h>
35 #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
38 #include <mbedtls/entropy.h> // only for error codes
39 #include <psa/crypto.h>
41 typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t
;
43 /* Trivial wrapper around psa_generate_random(). */
44 int mbedtls_psa_get_random(void *p_rng
,
45 unsigned char *output
,
48 /* The PSA RNG API doesn't need any externally maintained state. */
49 #define MBEDTLS_PSA_RANDOM_STATE NULL
51 #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
53 /* Choose a DRBG based on configuration and availability */
54 #if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
56 #include "mbedtls/hmac_drbg.h"
58 #elif defined(MBEDTLS_CTR_DRBG_C)
60 #include "mbedtls/ctr_drbg.h"
62 #elif defined(MBEDTLS_HMAC_DRBG_C)
64 #include "mbedtls/hmac_drbg.h"
65 #if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA256_C)
67 #if SIZE_MAX > 0xffffffff
68 /* Looks like a 64-bit system, so prefer SHA-512. */
69 #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
71 /* Looks like a 32-bit system, so prefer SHA-256. */
72 #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
74 #elif defined(MBEDTLS_SHA512_C)
75 #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
76 #elif defined(MBEDTLS_SHA256_C)
77 #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
79 #error "No hash algorithm available for HMAC_DBRG."
83 #error "No DRBG module available for the psa_crypto module."
86 #include "mbedtls/entropy.h"
88 /** Initialize the PSA DRBG.
90 * \param p_rng Pointer to the Mbed TLS DRBG state.
92 static inline void mbedtls_psa_drbg_init(mbedtls_psa_drbg_context_t
*p_rng
) {
93 #if defined(MBEDTLS_CTR_DRBG_C)
94 mbedtls_ctr_drbg_init(p_rng
);
95 #elif defined(MBEDTLS_HMAC_DRBG_C)
96 mbedtls_hmac_drbg_init(p_rng
);
100 /** Deinitialize the PSA DRBG.
102 * \param p_rng Pointer to the Mbed TLS DRBG state.
104 static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t
*p_rng
) {
105 #if defined(MBEDTLS_CTR_DRBG_C)
106 mbedtls_ctr_drbg_free(p_rng
);
107 #elif defined(MBEDTLS_HMAC_DRBG_C)
108 mbedtls_hmac_drbg_free(p_rng
);
112 /** The type of the PSA random generator context.
114 * The random generator context is composed of an entropy context and
118 void (* entropy_init
)(mbedtls_entropy_context
*ctx
);
119 void (* entropy_free
)(mbedtls_entropy_context
*ctx
);
120 mbedtls_entropy_context entropy
;
121 mbedtls_psa_drbg_context_t drbg
;
122 } mbedtls_psa_random_context_t
;
124 /* Defined in include/mbedtls/psa_util.h so that it's visible to
125 * application code. The declaration here is redundant, but included
126 * as a safety net to make it more likely that a future change that
127 * accidentally causes the implementation to diverge from the interface
128 * will be noticed. */
129 /* Do not include the declaration under MSVC because it doesn't accept it
130 * ("error C2370: 'mbedtls_psa_get_random' : redefinition; different storage class").
131 * Observed with Visual Studio 2013. A known bug apparently:
132 * https://stackoverflow.com/questions/8146541/duplicate-external-static-declarations-not-allowed-in-visual-studio
134 #if !defined(_MSC_VER)
135 static mbedtls_f_rng_t
*const mbedtls_psa_get_random
;
138 /** The maximum number of bytes that mbedtls_psa_get_random() is expected to
141 #if defined(MBEDTLS_CTR_DRBG_C)
142 #define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
143 #elif defined(MBEDTLS_HMAC_DRBG_C)
144 #define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
147 /** A pointer to the PSA DRBG state.
149 * This variable is only intended to be used through the macro
150 * #MBEDTLS_PSA_RANDOM_STATE.
152 /* psa_crypto.c sets this variable to a pointer to the DRBG state in the
153 * global PSA crypto state. */
154 /* The type `mbedtls_psa_drbg_context_t` is defined in
155 * include/mbedtls/psa_util.h so that `mbedtls_psa_random_state` can be
156 * declared there and be visible to application code. */
157 extern mbedtls_psa_drbg_context_t
*const mbedtls_psa_random_state
;
159 /** A pointer to the PSA DRBG state.
161 * This macro expands to an expression that is suitable as the \c p_rng
162 * parameter to pass to mbedtls_psa_get_random().
164 * This macro exists in all configurations where the psa_crypto module is
165 * enabled. Its expansion depends on the configuration.
167 #define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
169 /** Seed the PSA DRBG.
171 * \param entropy An entropy context to read the seed from.
172 * \param custom The personalization string.
173 * This can be \c NULL, in which case the personalization
174 * string is empty regardless of the value of \p len.
175 * \param len The length of the personalization string.
177 * \return \c 0 on success.
178 * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
180 static inline int mbedtls_psa_drbg_seed(
181 mbedtls_entropy_context
*entropy
,
182 const unsigned char *custom
, size_t len
) {
183 #if defined(MBEDTLS_CTR_DRBG_C)
184 return (mbedtls_ctr_drbg_seed(MBEDTLS_PSA_RANDOM_STATE
,
185 mbedtls_entropy_func
,
188 #elif defined(MBEDTLS_HMAC_DRBG_C)
189 const mbedtls_md_info_t
*md_info
=
190 mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE
);
191 return (mbedtls_hmac_drbg_seed(MBEDTLS_PSA_RANDOM_STATE
,
193 mbedtls_entropy_func
,
199 #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
201 #endif /* PSA_CRYPTO_RANDOM_IMPL_H */