1/* BEGIN_HEADER */
2
3/* Test random generation as a whole. */
4
5#include "mbedtls/bignum.h"
6#include "mbedtls/ctr_drbg.h"
7#include "mbedtls/ecdsa.h"
8#include "mbedtls/entropy.h"
9#include "mbedtls/hmac_drbg.h"
10#include "mbedtls/psa_util.h"
11#include "psa/crypto.h"
12
13/* How many bytes to generate in each test case for repeated generation.
14 * This must be high enough that the probability of generating the same
15 * output twice is infinitesimal, but low enough that random generators
16 * are willing to deliver that much. */
17#define OUTPUT_SIZE 32
18
19/* END_HEADER */
20
21/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_C:!MBEDTLS_PSA_INJECT_ENTROPY:MBEDTLS_CTR_DRBG_C */
22void random_twice_with_ctr_drbg()
23{
24    mbedtls_entropy_context entropy;
25    mbedtls_ctr_drbg_context drbg;
26    unsigned char output1[OUTPUT_SIZE];
27    unsigned char output2[OUTPUT_SIZE];
28
29#if defined(MBEDTLS_AES_C)
30    MD_PSA_INIT();
31#else
32    USE_PSA_INIT();
33#endif
34
35
36    /* First round */
37    mbedtls_entropy_init(&entropy);
38    mbedtls_ctr_drbg_init(&drbg);
39    TEST_EQUAL(0, mbedtls_ctr_drbg_seed(&drbg,
40                                        mbedtls_entropy_func, &entropy,
41                                        NULL, 0));
42    TEST_EQUAL(0, mbedtls_ctr_drbg_random(&drbg,
43                                          output1, sizeof(output1)));
44    mbedtls_ctr_drbg_free(&drbg);
45    mbedtls_entropy_free(&entropy);
46
47    /* Second round */
48    mbedtls_entropy_init(&entropy);
49    mbedtls_ctr_drbg_init(&drbg);
50    TEST_EQUAL(0, mbedtls_ctr_drbg_seed(&drbg,
51                                        mbedtls_entropy_func, &entropy,
52                                        NULL, 0));
53    TEST_EQUAL(0, mbedtls_ctr_drbg_random(&drbg,
54                                          output2, sizeof(output2)));
55    mbedtls_ctr_drbg_free(&drbg);
56    mbedtls_entropy_free(&entropy);
57
58    /* The two rounds must generate different random data. */
59    TEST_ASSERT(memcmp(output1, output2, OUTPUT_SIZE) != 0);
60
61exit:
62    mbedtls_ctr_drbg_free(&drbg);
63    mbedtls_entropy_free(&entropy);
64#if defined(MBEDTLS_AES_C)
65    MD_PSA_DONE();
66#else
67    USE_PSA_DONE();
68#endif
69}
70/* END_CASE */
71
72/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_C:!MBEDTLS_PSA_INJECT_ENTROPY:MBEDTLS_HMAC_DRBG_C */
73void random_twice_with_hmac_drbg(int md_type)
74{
75    mbedtls_entropy_context entropy;
76    mbedtls_hmac_drbg_context drbg;
77    unsigned char output1[OUTPUT_SIZE];
78    unsigned char output2[OUTPUT_SIZE];
79    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_type);
80
81    MD_PSA_INIT();
82
83    /* First round */
84    mbedtls_entropy_init(&entropy);
85    mbedtls_hmac_drbg_init(&drbg);
86    TEST_EQUAL(0, mbedtls_hmac_drbg_seed(&drbg, md_info,
87                                         mbedtls_entropy_func, &entropy,
88                                         NULL, 0));
89    TEST_EQUAL(0, mbedtls_hmac_drbg_random(&drbg,
90                                           output1, sizeof(output1)));
91    mbedtls_hmac_drbg_free(&drbg);
92    mbedtls_entropy_free(&entropy);
93
94    /* Second round */
95    mbedtls_entropy_init(&entropy);
96    mbedtls_hmac_drbg_init(&drbg);
97    TEST_EQUAL(0, mbedtls_hmac_drbg_seed(&drbg, md_info,
98                                         mbedtls_entropy_func, &entropy,
99                                         NULL, 0));
100    TEST_EQUAL(0, mbedtls_hmac_drbg_random(&drbg,
101                                           output2, sizeof(output2)));
102    mbedtls_hmac_drbg_free(&drbg);
103    mbedtls_entropy_free(&entropy);
104
105    /* The two rounds must generate different random data. */
106    TEST_ASSERT(memcmp(output1, output2, OUTPUT_SIZE) != 0);
107
108exit:
109    mbedtls_hmac_drbg_free(&drbg);
110    mbedtls_entropy_free(&entropy);
111    MD_PSA_DONE();
112}
113/* END_CASE */
114
115/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
116void random_twice_with_psa_from_classic()
117{
118    unsigned char output1[OUTPUT_SIZE];
119    unsigned char output2[OUTPUT_SIZE];
120
121    /* First round */
122    PSA_ASSERT(psa_crypto_init());
123    TEST_EQUAL(0, mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
124                                         output1, sizeof(output1)));
125    PSA_DONE();
126
127    /* Second round */
128    PSA_ASSERT(psa_crypto_init());
129    TEST_EQUAL(0, mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
130                                         output2, sizeof(output2)));
131    PSA_DONE();
132
133    /* The two rounds must generate different random data. */
134    TEST_ASSERT(memcmp(output1, output2, OUTPUT_SIZE) != 0);
135
136exit:
137    PSA_DONE();
138}
139/* END_CASE */
140
141/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
142void random_twice_with_psa_from_psa()
143{
144    unsigned char output1[OUTPUT_SIZE];
145    unsigned char output2[OUTPUT_SIZE];
146
147    /* First round */
148    PSA_ASSERT(psa_crypto_init());
149    PSA_ASSERT(psa_generate_random(output1, sizeof(output1)));
150    PSA_DONE();
151
152    /* Second round */
153    PSA_ASSERT(psa_crypto_init());
154    PSA_ASSERT(psa_generate_random(output2, sizeof(output2)));
155    PSA_DONE();
156
157    /* The two rounds must generate different random data. */
158    TEST_ASSERT(memcmp(output1, output2, OUTPUT_SIZE) != 0);
159
160exit:
161    PSA_DONE();
162}
163/* END_CASE */
164
165/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */
166void mbedtls_psa_get_random_no_init()
167{
168    unsigned char output[1];
169
170    TEST_ASSERT(mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
171                                       output, sizeof(output)) != 0);
172}
173/* END_CASE */
174
175/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C */
176void mbedtls_psa_get_random_length(int n)
177{
178    unsigned char *output = NULL;
179
180    PSA_ASSERT(psa_crypto_init());
181    TEST_CALLOC(output, n);
182
183    TEST_EQUAL(0, mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE,
184                                         output, n));
185exit:
186    mbedtls_free(output);
187    PSA_DONE();
188}
189/* END_CASE */
190
191/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_ECDSA_C */
192void mbedtls_psa_get_random_ecdsa_sign(int curve)
193{
194    mbedtls_ecp_group grp;
195    mbedtls_mpi d, r, s;
196    unsigned char buf[] = "This is not a hash.";
197
198    mbedtls_ecp_group_init(&grp);
199    mbedtls_mpi_init(&d);
200    mbedtls_mpi_init(&r);
201    mbedtls_mpi_init(&s);
202
203    TEST_EQUAL(0, mbedtls_mpi_lset(&d, 123456789));
204    TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, curve));
205    PSA_ASSERT(psa_crypto_init());
206    TEST_EQUAL(0, mbedtls_ecdsa_sign(&grp, &r, &s, &d,
207                                     buf, sizeof(buf),
208                                     mbedtls_psa_get_random,
209                                     MBEDTLS_PSA_RANDOM_STATE));
210exit:
211    mbedtls_mpi_free(&d);
212    mbedtls_mpi_free(&r);
213    mbedtls_mpi_free(&s);
214    mbedtls_ecp_group_free(&grp);
215    PSA_DONE();
216}
217/* END_CASE */
218