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