psa_crypto_random_impl.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. void (* entropy_init)(mbedtls_entropy_context *ctx);
  102. void (* entropy_free)(mbedtls_entropy_context *ctx);
  103. mbedtls_entropy_context entropy;
  104. mbedtls_psa_drbg_context_t drbg;
  105. } mbedtls_psa_random_context_t;
  106. /* Defined in include/mbedtls/psa_util.h so that it's visible to
  107. * application code. The declaration here is redundant, but included
  108. * as a safety net to make it more likely that a future change that
  109. * accidentally causes the implementation to diverge from the interface
  110. * will be noticed. */
  111. /* Do not include the declaration under MSVC because it doesn't accept it
  112. * ("error C2370: 'mbedtls_psa_get_random' : redefinition; different storage class").
  113. * Observed with Visual Studio 2013. A known bug apparently:
  114. * https://stackoverflow.com/questions/8146541/duplicate-external-static-declarations-not-allowed-in-visual-studio
  115. */
  116. #if !defined(_MSC_VER)
  117. static mbedtls_f_rng_t *const mbedtls_psa_get_random;
  118. #endif
  119. /** The maximum number of bytes that mbedtls_psa_get_random() is expected to
  120. * return.
  121. */
  122. #if defined(MBEDTLS_CTR_DRBG_C)
  123. #define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
  124. #elif defined(MBEDTLS_HMAC_DRBG_C)
  125. #define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
  126. #endif
  127. /** A pointer to the PSA DRBG state.
  128. *
  129. * This variable is only intended to be used through the macro
  130. * #MBEDTLS_PSA_RANDOM_STATE.
  131. */
  132. /* psa_crypto.c sets this variable to a pointer to the DRBG state in the
  133. * global PSA crypto state. */
  134. /* The type `mbedtls_psa_drbg_context_t` is defined in
  135. * include/mbedtls/psa_util.h so that `mbedtls_psa_random_state` can be
  136. * declared there and be visible to application code. */
  137. extern mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state;
  138. /** A pointer to the PSA DRBG state.
  139. *
  140. * This macro expands to an expression that is suitable as the \c p_rng
  141. * parameter to pass to mbedtls_psa_get_random().
  142. *
  143. * This macro exists in all configurations where the psa_crypto module is
  144. * enabled. Its expansion depends on the configuration.
  145. */
  146. #define MBEDTLS_PSA_RANDOM_STATE mbedtls_psa_random_state
  147. /** Seed the PSA DRBG.
  148. *
  149. * \param entropy An entropy context to read the seed from.
  150. * \param custom The personalization string.
  151. * This can be \c NULL, in which case the personalization
  152. * string is empty regardless of the value of \p len.
  153. * \param len The length of the personalization string.
  154. *
  155. * \return \c 0 on success.
  156. * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
  157. */
  158. static inline int mbedtls_psa_drbg_seed(
  159. mbedtls_entropy_context *entropy,
  160. const unsigned char *custom, size_t len)
  161. {
  162. #if defined(MBEDTLS_CTR_DRBG_C)
  163. return mbedtls_ctr_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
  164. mbedtls_entropy_func,
  165. entropy,
  166. custom, len);
  167. #elif defined(MBEDTLS_HMAC_DRBG_C)
  168. const mbedtls_md_info_t *md_info =
  169. mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
  170. return mbedtls_hmac_drbg_seed(MBEDTLS_PSA_RANDOM_STATE,
  171. md_info,
  172. mbedtls_entropy_func,
  173. entropy,
  174. custom, len);
  175. #endif
  176. }
  177. #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
  178. #endif /* PSA_CRYPTO_RANDOM_IMPL_H */