blob: 4fa54a9fa1bb51c7532aa43fb9e68ef3df9c4b81 [file] [log] [blame]
Gilles Peskineb2b64d32020-12-14 16:43:58 +01001/** \file psa_crypto_random_impl.h
Gilles Peskine90edc992020-11-13 15:39:19 +01002 *
Gilles Peskineb2b64d32020-12-14 16:43:58 +01003 * \brief PSA crypto random generator implementation abstraction.
Gilles Peskinee3ed8022021-02-03 20:04:08 +01004 *
5 * The definitions here need to be consistent with the declarations
6 * in include/mbedtls/psa_util.h.
Gilles Peskine90edc992020-11-13 15:39:19 +01007 */
8/*
9 * Copyright The Mbed TLS Contributors
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License"); you may
13 * not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
20 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24
Gilles Peskineb2b64d32020-12-14 16:43:58 +010025#ifndef PSA_CRYPTO_RANDOM_IMPL_H
26#define PSA_CRYPTO_RANDOM_IMPL_H
Gilles Peskine90edc992020-11-13 15:39:19 +010027
Gilles Peskine4fc21fd2020-11-13 18:47:18 +010028#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
29
30#include <string.h>
31#include <mbedtls/entropy.h> // only for error codes
32#include <psa/crypto.h>
33
34typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
35
Gilles Peskine9c3e0602021-01-05 16:03:55 +010036/* Trivial wrapper around psa_generate_random(). */
Gilles Peskine8814fc42020-12-14 15:33:44 +010037int mbedtls_psa_get_random( void *p_rng,
38 unsigned char *output,
39 size_t output_size );
Gilles Peskine4fc21fd2020-11-13 18:47:18 +010040
Gilles Peskine9c3e0602021-01-05 16:03:55 +010041/* The PSA RNG API doesn't need any externally maintained state. */
Gilles Peskine5894e8e2020-12-14 14:54:06 +010042#define MBEDTLS_PSA_RANDOM_STATE NULL
Gilles Peskine4fc21fd2020-11-13 18:47:18 +010043
44#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
45
Gilles Peskine82e57d12020-11-13 21:31:17 +010046/* Choose a DRBG based on configuration and availability */
47#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
48
49#include "mbedtls/hmac_drbg.h"
50
51#elif defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskine30524eb2020-11-13 17:02:26 +010052
53#include "mbedtls/ctr_drbg.h"
Gilles Peskine82e57d12020-11-13 21:31:17 +010054
55#elif defined(MBEDTLS_HMAC_DRBG_C)
56
57#include "mbedtls/hmac_drbg.h"
58#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA256_C)
59#include <limits.h>
60#if SIZE_MAX > 0xffffffff
61/* Looks like a 64-bit system, so prefer SHA-512. */
62#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
63#else
64/* Looks like a 32-bit system, so prefer SHA-256. */
65#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
66#endif
67#elif defined(MBEDTLS_SHA512_C)
68#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
69#elif defined(MBEDTLS_SHA256_C)
70#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
71#else
72#error "No hash algorithm available for HMAC_DBRG."
73#endif
74
75#else
76#error "No DRBG module available for the psa_crypto module."
77#endif
78
Gilles Peskine30524eb2020-11-13 17:02:26 +010079#include "mbedtls/entropy.h"
80
81/** The type of the PSA DRBG context.
82 */
Gilles Peskine82e57d12020-11-13 21:31:17 +010083#if defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskine30524eb2020-11-13 17:02:26 +010084typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
Gilles Peskine82e57d12020-11-13 21:31:17 +010085#elif defined(MBEDTLS_HMAC_DRBG_C)
86typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
87#endif
Gilles Peskine30524eb2020-11-13 17:02:26 +010088
89/** Initialize the PSA DRBG.
90 *
91 * \param p_rng Pointer to the Mbed TLS DRBG state.
92 */
93static inline void mbedtls_psa_drbg_init( mbedtls_psa_drbg_context_t *p_rng )
94{
Gilles Peskine82e57d12020-11-13 21:31:17 +010095#if defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskine30524eb2020-11-13 17:02:26 +010096 mbedtls_ctr_drbg_init( p_rng );
Gilles Peskine82e57d12020-11-13 21:31:17 +010097#elif defined(MBEDTLS_HMAC_DRBG_C)
98 mbedtls_hmac_drbg_init( p_rng );
99#endif
Gilles Peskine30524eb2020-11-13 17:02:26 +0100100}
101
102/** Deinitialize the PSA DRBG.
103 *
104 * \param p_rng Pointer to the Mbed TLS DRBG state.
105 */
106static inline void mbedtls_psa_drbg_free( mbedtls_psa_drbg_context_t *p_rng )
107{
Gilles Peskine82e57d12020-11-13 21:31:17 +0100108#if defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskine30524eb2020-11-13 17:02:26 +0100109 mbedtls_ctr_drbg_free( p_rng );
Gilles Peskine82e57d12020-11-13 21:31:17 +0100110#elif defined(MBEDTLS_HMAC_DRBG_C)
111 mbedtls_hmac_drbg_free( p_rng );
112#endif
Gilles Peskine30524eb2020-11-13 17:02:26 +0100113}
114
115/** The type of the PSA random generator context.
116 *
117 * The random generator context is composed of an entropy context and
118 * a DRBG context.
119 */
120typedef struct
121{
122 void (* entropy_init )( mbedtls_entropy_context *ctx );
123 void (* entropy_free )( mbedtls_entropy_context *ctx );
124 mbedtls_entropy_context entropy;
125 mbedtls_psa_drbg_context_t drbg;
126} mbedtls_psa_random_context_t;
127
Gilles Peskineb3cd9632020-12-14 19:54:24 +0100128/* The type of an Mbed TLS random generator function. This should be
129 * part of the public API instead of repeating the type everywhere.
130 * For the time being, declare it here. Declaring a type is necessary
131 * to define mbedtls_psa_get_random as a variable of a function pointer
132 * type without incurring the wrath of check-names.sh. */
133typedef int mbedtls_f_rng_t( void *p_rng, unsigned char *output, size_t output_size );
134
Gilles Peskine30524eb2020-11-13 17:02:26 +0100135/** Return random data.
136 *
137 * This function is suitable as the \p f_rng parameter to Mbed TLS functions
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100138 * that require a random generator. Use #MBEDTLS_PSA_RANDOM_STATE to
Gilles Peskine30524eb2020-11-13 17:02:26 +0100139 * obtain the \p p_rng parameter.
140 *
Gilles Peskine82e57d12020-11-13 21:31:17 +0100141 * \param p_rng The DRBG context. This must be
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100142 * #MBEDTLS_PSA_RANDOM_STATE.
Gilles Peskine30524eb2020-11-13 17:02:26 +0100143 * \param output The buffer to fill.
144 * \param output_len The length of the buffer in bytes.
145 * It must be at most #MBEDTLS_PSA_RANDOM_MAX_REQUEST.
146 *
Gilles Peskine82e57d12020-11-13 21:31:17 +0100147 * \retval \c 0 on success.
148 * \return \c MBEDTLS_ERR_xxx_DRBG_xxx or
149 * \c MBEDTLS_ERR_PLATFORM_xxx on failure.
Gilles Peskine30524eb2020-11-13 17:02:26 +0100150 */
Gilles Peskine82e57d12020-11-13 21:31:17 +0100151#if defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskineb3cd9632020-12-14 19:54:24 +0100152static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_ctr_drbg_random;
Gilles Peskine82e57d12020-11-13 21:31:17 +0100153#elif defined(MBEDTLS_HMAC_DRBG_C)
Gilles Peskineb3cd9632020-12-14 19:54:24 +0100154static mbedtls_f_rng_t *const mbedtls_psa_get_random = mbedtls_hmac_drbg_random;
Gilles Peskine82e57d12020-11-13 21:31:17 +0100155#endif
Gilles Peskine30524eb2020-11-13 17:02:26 +0100156
157/** The maximum number of bytes that mbedtls_psa_get_random() is expected to
158 * return.
159 */
Gilles Peskine82e57d12020-11-13 21:31:17 +0100160#if defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskine30524eb2020-11-13 17:02:26 +0100161#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
Gilles Peskine82e57d12020-11-13 21:31:17 +0100162#elif defined(MBEDTLS_HMAC_DRBG_C)
163#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
164#endif
Gilles Peskine30524eb2020-11-13 17:02:26 +0100165
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100166/** A pointer to the PSA DRBG state.
Gilles Peskine30524eb2020-11-13 17:02:26 +0100167 *
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100168 * This variable is only intended to be used through the macro
169 * #MBEDTLS_PSA_RANDOM_STATE.
Gilles Peskine30524eb2020-11-13 17:02:26 +0100170 */
Gilles Peskine9c3e0602021-01-05 16:03:55 +0100171/* psa_crypto.c sets this variable to a pointer to the DRBG state in the
172 * global PSA crypto state. */
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100173extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
174
175/** A pointer to the PSA DRBG state.
176 *
Gilles Peskine88fa5c42021-01-04 21:00:53 +0100177 * This macro expands to an expression that is suitable as the \c p_rng
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100178 * parameter to pass to mbedtls_psa_get_random().
179 *
180 * This macro exists in all configurations where the psa_crypto module is
181 * enabled. Its expansion depends on the configuration.
182 */
183#define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
Gilles Peskine30524eb2020-11-13 17:02:26 +0100184
Gilles Peskine30524eb2020-11-13 17:02:26 +0100185/** Seed the PSA DRBG.
186 *
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100187 * \param entropy An entropy context to read the seed from.
Gilles Peskine30524eb2020-11-13 17:02:26 +0100188 * \param custom The personalization string.
189 * This can be \c NULL, in which case the personalization
190 * string is empty regardless of the value of \p len.
191 * \param len The length of the personalization string.
192 *
193 * \return \c 0 on success.
194 * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
195 */
196static inline int mbedtls_psa_drbg_seed(
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100197 mbedtls_entropy_context *entropy,
Gilles Peskine30524eb2020-11-13 17:02:26 +0100198 const unsigned char *custom, size_t len )
199{
Gilles Peskine82e57d12020-11-13 21:31:17 +0100200#if defined(MBEDTLS_CTR_DRBG_C)
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100201 return( mbedtls_ctr_drbg_seed( MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine30524eb2020-11-13 17:02:26 +0100202 mbedtls_entropy_func,
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100203 entropy,
Gilles Peskine30524eb2020-11-13 17:02:26 +0100204 custom, len ) );
Gilles Peskine82e57d12020-11-13 21:31:17 +0100205#elif defined(MBEDTLS_HMAC_DRBG_C)
206 const mbedtls_md_info_t *md_info =
207 mbedtls_md_info_from_type( MBEDTLS_PSA_HMAC_DRBG_MD_TYPE );
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100208 return( mbedtls_hmac_drbg_seed( MBEDTLS_PSA_RANDOM_STATE,
Gilles Peskine82e57d12020-11-13 21:31:17 +0100209 md_info,
210 mbedtls_entropy_func,
Gilles Peskine5894e8e2020-12-14 14:54:06 +0100211 entropy,
Gilles Peskine82e57d12020-11-13 21:31:17 +0100212 custom, len ) );
213#endif
Gilles Peskine30524eb2020-11-13 17:02:26 +0100214}
Gilles Peskine90edc992020-11-13 15:39:19 +0100215
Gilles Peskine4fc21fd2020-11-13 18:47:18 +0100216#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
217
Gilles Peskineb2b64d32020-12-14 16:43:58 +0100218#endif /* PSA_CRYPTO_RANDOM_IMPL_H */