psa_crypto_random_impl.h 6.9 KB

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