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 */
|