/src/mbedtls/library/psa_crypto_random_impl.h
Line | Count | Source |
1 | | /** \file psa_crypto_random_impl.h |
2 | | * |
3 | | * \brief PSA crypto random generator implementation abstraction. |
4 | | */ |
5 | | /* |
6 | | * Copyright The Mbed TLS Contributors |
7 | | * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
8 | | */ |
9 | | |
10 | | #ifndef PSA_CRYPTO_RANDOM_IMPL_H |
11 | | #define PSA_CRYPTO_RANDOM_IMPL_H |
12 | | |
13 | | #include "psa_util_internal.h" |
14 | | |
15 | | #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) |
16 | | |
17 | | typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t; |
18 | | |
19 | | #else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ |
20 | | |
21 | | #include "mbedtls/entropy.h" |
22 | | |
23 | | /* Choose a DRBG based on configuration and availability */ |
24 | | #if defined(MBEDTLS_CTR_DRBG_C) |
25 | | |
26 | | #include "mbedtls/ctr_drbg.h" |
27 | | #undef MBEDTLS_PSA_HMAC_DRBG_MD_TYPE |
28 | | |
29 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
30 | | |
31 | | #include "mbedtls/hmac_drbg.h" |
32 | | #if defined(MBEDTLS_MD_CAN_SHA512) && defined(MBEDTLS_MD_CAN_SHA256) |
33 | | #include <limits.h> |
34 | | #if SIZE_MAX > 0xffffffff |
35 | | /* Looks like a 64-bit system, so prefer SHA-512. */ |
36 | | #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512 |
37 | | #else |
38 | | /* Looks like a 32-bit system, so prefer SHA-256. */ |
39 | | #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 |
40 | | #endif |
41 | | #elif defined(MBEDTLS_MD_CAN_SHA512) |
42 | | #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512 |
43 | | #elif defined(MBEDTLS_MD_CAN_SHA256) |
44 | | #define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 |
45 | | #else |
46 | | #error "No hash algorithm available for HMAC_DBRG." |
47 | | #endif |
48 | | |
49 | | #else /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/ |
50 | | |
51 | | #error "No DRBG module available for the psa_crypto module." |
52 | | |
53 | | #endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/ |
54 | | |
55 | | /* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */ |
56 | | #if defined(MBEDTLS_CTR_DRBG_C) |
57 | 0 | #define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST |
58 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
59 | | #define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST |
60 | | #endif |
61 | | |
62 | | #if defined(MBEDTLS_CTR_DRBG_C) |
63 | | typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t; |
64 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
65 | | typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t; |
66 | | #endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */ |
67 | | |
68 | | typedef struct { |
69 | | void (* entropy_init)(mbedtls_entropy_context *ctx); |
70 | | void (* entropy_free)(mbedtls_entropy_context *ctx); |
71 | | mbedtls_entropy_context entropy; |
72 | | mbedtls_psa_drbg_context_t drbg; |
73 | | #if defined(MBEDTLS_PLATFORM_IS_UNIXLIKE) |
74 | | /* Fork protection: normally pid = getpid(). If the value changes, |
75 | | * we are in a (grand)*child of the original process, so reseed |
76 | | * the RNG to ensure that the child and the original process have |
77 | | * distinct RNG states. See psa_random_internal_generate(). |
78 | | * |
79 | | * The type is intmax_t, not pid_t, for portability reasons: |
80 | | * pid_t is defined in `unistd.h`, but on some platforms, it may |
81 | | * only be defined if a certain compatibility level is requested |
82 | | * by defining a macro such as _POSIX_C_SOURCE or _XOPEN_SOURCE. |
83 | | * The macro needs to be defined before any system header, which |
84 | | * may be hard to do in some C files that include this header |
85 | | * (e.g. test suites). So we sidestep this complication, at the |
86 | | * cost of possibly a few more instructions to compare pid values. |
87 | | */ |
88 | | intmax_t pid; |
89 | | #endif |
90 | | } mbedtls_psa_random_context_t; |
91 | | |
92 | | /** Initialize the PSA DRBG. |
93 | | * |
94 | | * \param p_rng Pointer to the Mbed TLS DRBG state. |
95 | | */ |
96 | | static inline void mbedtls_psa_drbg_init(mbedtls_psa_drbg_context_t *p_rng) |
97 | 114 | { |
98 | 114 | #if defined(MBEDTLS_CTR_DRBG_C) |
99 | 114 | mbedtls_ctr_drbg_init(p_rng); |
100 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
101 | | mbedtls_hmac_drbg_init(p_rng); |
102 | | #endif |
103 | 114 | } Unexecuted instantiation: psa_crypto.c:mbedtls_psa_drbg_init Unexecuted instantiation: psa_crypto_cipher.c:mbedtls_psa_drbg_init Unexecuted instantiation: psa_crypto_ecp.c:mbedtls_psa_drbg_init Unexecuted instantiation: psa_crypto_ffdh.c:mbedtls_psa_drbg_init Unexecuted instantiation: psa_crypto_rsa.c:mbedtls_psa_drbg_init psa_crypto_random.c:mbedtls_psa_drbg_init Line | Count | Source | 97 | 114 | { | 98 | 114 | #if defined(MBEDTLS_CTR_DRBG_C) | 99 | 114 | mbedtls_ctr_drbg_init(p_rng); | 100 | | #elif defined(MBEDTLS_HMAC_DRBG_C) | 101 | | mbedtls_hmac_drbg_init(p_rng); | 102 | | #endif | 103 | 114 | } |
|
104 | | |
105 | | /** Deinitialize the PSA DRBG. |
106 | | * |
107 | | * \param p_rng Pointer to the Mbed TLS DRBG state. |
108 | | */ |
109 | | static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng) |
110 | 114 | { |
111 | 114 | #if defined(MBEDTLS_CTR_DRBG_C) |
112 | 114 | mbedtls_ctr_drbg_free(p_rng); |
113 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
114 | | mbedtls_hmac_drbg_free(p_rng); |
115 | | #endif |
116 | 114 | } Unexecuted instantiation: psa_crypto.c:mbedtls_psa_drbg_free Unexecuted instantiation: psa_crypto_cipher.c:mbedtls_psa_drbg_free Unexecuted instantiation: psa_crypto_ecp.c:mbedtls_psa_drbg_free Unexecuted instantiation: psa_crypto_ffdh.c:mbedtls_psa_drbg_free Unexecuted instantiation: psa_crypto_rsa.c:mbedtls_psa_drbg_free psa_crypto_random.c:mbedtls_psa_drbg_free Line | Count | Source | 110 | 114 | { | 111 | 114 | #if defined(MBEDTLS_CTR_DRBG_C) | 112 | 114 | mbedtls_ctr_drbg_free(p_rng); | 113 | | #elif defined(MBEDTLS_HMAC_DRBG_C) | 114 | | mbedtls_hmac_drbg_free(p_rng); | 115 | | #endif | 116 | 114 | } |
|
117 | | |
118 | | /** Seed the PSA DRBG. |
119 | | * |
120 | | * \param drbg_ctx The DRBG context to seed. |
121 | | * It must be initialized but not active. |
122 | | * \param entropy An entropy context to read the seed from. |
123 | | * \param custom The personalization string. |
124 | | * This can be \c NULL, in which case the personalization |
125 | | * string is empty regardless of the value of \p len. |
126 | | * \param len The length of the personalization string. |
127 | | * |
128 | | * \return \c 0 on success. |
129 | | * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure. |
130 | | */ |
131 | | static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx, |
132 | | mbedtls_entropy_context *entropy, |
133 | | const unsigned char *custom, size_t len) |
134 | 114 | { |
135 | 114 | #if defined(MBEDTLS_CTR_DRBG_C) |
136 | 114 | return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len); |
137 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
138 | | const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE); |
139 | | return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len); |
140 | | #endif |
141 | 114 | } Unexecuted instantiation: psa_crypto.c:mbedtls_psa_drbg_seed Unexecuted instantiation: psa_crypto_cipher.c:mbedtls_psa_drbg_seed Unexecuted instantiation: psa_crypto_ecp.c:mbedtls_psa_drbg_seed Unexecuted instantiation: psa_crypto_ffdh.c:mbedtls_psa_drbg_seed Unexecuted instantiation: psa_crypto_rsa.c:mbedtls_psa_drbg_seed psa_crypto_random.c:mbedtls_psa_drbg_seed Line | Count | Source | 134 | 114 | { | 135 | 114 | #if defined(MBEDTLS_CTR_DRBG_C) | 136 | 114 | return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len); | 137 | | #elif defined(MBEDTLS_HMAC_DRBG_C) | 138 | | const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE); | 139 | | return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len); | 140 | | #endif | 141 | 114 | } |
|
142 | | |
143 | | /** Reseed the PSA DRBG. |
144 | | * |
145 | | * \param drbg_ctx The DRBG context to reseed. |
146 | | * It must be active. |
147 | | * \param additional Additional data to inject. |
148 | | * \param len The length of \p additional in bytes. |
149 | | * This can be 0 to simply reseed from the entropy source. |
150 | | * |
151 | | * \return \c 0 on success. |
152 | | * \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure. |
153 | | */ |
154 | | static inline int mbedtls_psa_drbg_reseed(mbedtls_psa_drbg_context_t *drbg_ctx, |
155 | | const unsigned char *additional, |
156 | | size_t len) |
157 | 0 | { |
158 | 0 | #if defined(MBEDTLS_CTR_DRBG_C) |
159 | 0 | return mbedtls_ctr_drbg_reseed(drbg_ctx, additional, len); |
160 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
161 | | return mbedtls_hmac_drbg_reseed(drbg_ctx, additional, len); |
162 | | #endif |
163 | 0 | } Unexecuted instantiation: psa_crypto.c:mbedtls_psa_drbg_reseed Unexecuted instantiation: psa_crypto_cipher.c:mbedtls_psa_drbg_reseed Unexecuted instantiation: psa_crypto_ecp.c:mbedtls_psa_drbg_reseed Unexecuted instantiation: psa_crypto_ffdh.c:mbedtls_psa_drbg_reseed Unexecuted instantiation: psa_crypto_rsa.c:mbedtls_psa_drbg_reseed Unexecuted instantiation: psa_crypto_random.c:mbedtls_psa_drbg_reseed |
164 | | |
165 | | /** Deplete the PSA DRBG, i.e. cause it to reseed the next time it is used. |
166 | | * |
167 | | * \note This function is not thread-safe. |
168 | | * |
169 | | * \param drbg_ctx The DRBG context to deplete. |
170 | | * It must be active. |
171 | | */ |
172 | | static inline void mbedtls_psa_drbg_deplete(mbedtls_psa_drbg_context_t *drbg_ctx) |
173 | 0 | { |
174 | 0 | drbg_ctx->reseed_counter = drbg_ctx->reseed_interval; |
175 | 0 | } Unexecuted instantiation: psa_crypto.c:mbedtls_psa_drbg_deplete Unexecuted instantiation: psa_crypto_cipher.c:mbedtls_psa_drbg_deplete Unexecuted instantiation: psa_crypto_ecp.c:mbedtls_psa_drbg_deplete Unexecuted instantiation: psa_crypto_ffdh.c:mbedtls_psa_drbg_deplete Unexecuted instantiation: psa_crypto_rsa.c:mbedtls_psa_drbg_deplete Unexecuted instantiation: psa_crypto_random.c:mbedtls_psa_drbg_deplete |
176 | | |
177 | | #if MBEDTLS_ENTROPY_TRUE_SOURCES > 0 |
178 | | /** Set prediction resistance in the PSA DRBG. |
179 | | * |
180 | | * \note This function is not thread-safe. |
181 | | * |
182 | | * \param drbg_ctx The DRBG context to reconfigure. |
183 | | * It must be active. |
184 | | * \param enabled \c 1 to enable, or \c 0 to disable. |
185 | | */ |
186 | | static inline void mbedtls_psa_drbg_set_prediction_resistance( |
187 | | mbedtls_psa_drbg_context_t *drbg_ctx, |
188 | | unsigned enabled) |
189 | 0 | { |
190 | 0 | #if defined(MBEDTLS_CTR_DRBG_C) |
191 | 0 | mbedtls_ctr_drbg_set_prediction_resistance(drbg_ctx, enabled); |
192 | | #elif defined(MBEDTLS_HMAC_DRBG_C) |
193 | | mbedtls_hmac_drbg_set_prediction_resistance(drbg_ctx, enabled); |
194 | | #endif |
195 | 0 | } Unexecuted instantiation: psa_crypto.c:mbedtls_psa_drbg_set_prediction_resistance Unexecuted instantiation: psa_crypto_cipher.c:mbedtls_psa_drbg_set_prediction_resistance Unexecuted instantiation: psa_crypto_ecp.c:mbedtls_psa_drbg_set_prediction_resistance Unexecuted instantiation: psa_crypto_ffdh.c:mbedtls_psa_drbg_set_prediction_resistance Unexecuted instantiation: psa_crypto_rsa.c:mbedtls_psa_drbg_set_prediction_resistance Unexecuted instantiation: psa_crypto_random.c:mbedtls_psa_drbg_set_prediction_resistance |
196 | | #endif /* MBEDTLS_ENTROPY_TRUE_SOURCES > 0 */ |
197 | | |
198 | | #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ |
199 | | |
200 | | #endif /* PSA_CRYPTO_RANDOM_IMPL_H */ |