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