Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/mbedtls/library/dhm.c
21662 views
1
/*
2
* Diffie-Hellman-Merkle key exchange
3
*
4
* Copyright The Mbed TLS Contributors
5
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6
*/
7
/*
8
* The following sources were referenced in the design of this implementation
9
* of the Diffie-Hellman-Merkle algorithm:
10
*
11
* [1] Handbook of Applied Cryptography - 1997, Chapter 12
12
* Menezes, van Oorschot and Vanstone
13
*
14
*/
15
16
#include "common.h"
17
18
#if defined(MBEDTLS_DHM_C)
19
20
#include "mbedtls/dhm.h"
21
#include "bignum_internal.h"
22
#include "mbedtls/platform_util.h"
23
#include "mbedtls/error.h"
24
25
#include <string.h>
26
27
#if defined(MBEDTLS_PEM_PARSE_C)
28
#include "mbedtls/pem.h"
29
#endif
30
31
#if defined(MBEDTLS_ASN1_PARSE_C)
32
#include "mbedtls/asn1.h"
33
#endif
34
35
#include "mbedtls/platform.h"
36
37
#if !defined(MBEDTLS_DHM_ALT)
38
39
/*
40
* helper to validate the mbedtls_mpi size and import it
41
*/
42
static int dhm_read_bignum(mbedtls_mpi *X,
43
unsigned char **p,
44
const unsigned char *end)
45
{
46
int ret, n;
47
48
if (end - *p < 2) {
49
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
50
}
51
52
n = MBEDTLS_GET_UINT16_BE(*p, 0);
53
(*p) += 2;
54
55
if ((size_t) (end - *p) < (size_t) n) {
56
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
57
}
58
59
if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) {
60
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret);
61
}
62
63
(*p) += n;
64
65
return 0;
66
}
67
68
/*
69
* Verify sanity of parameter with regards to P
70
*
71
* Parameter should be: 2 <= public_param <= P - 2
72
*
73
* This means that we need to return an error if
74
* public_param < 2 or public_param > P-2
75
*
76
* For more information on the attack, see:
77
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
78
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
79
*/
80
static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P)
81
{
82
mbedtls_mpi U;
83
int ret = 0;
84
85
mbedtls_mpi_init(&U);
86
87
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
88
89
if (mbedtls_mpi_cmp_int(param, 2) < 0 ||
90
mbedtls_mpi_cmp_mpi(param, &U) > 0) {
91
ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
92
}
93
94
cleanup:
95
mbedtls_mpi_free(&U);
96
return ret;
97
}
98
99
void mbedtls_dhm_init(mbedtls_dhm_context *ctx)
100
{
101
memset(ctx, 0, sizeof(mbedtls_dhm_context));
102
}
103
104
size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx)
105
{
106
return mbedtls_mpi_bitlen(&ctx->P);
107
}
108
109
size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx)
110
{
111
return mbedtls_mpi_size(&ctx->P);
112
}
113
114
int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,
115
mbedtls_dhm_parameter param,
116
mbedtls_mpi *dest)
117
{
118
const mbedtls_mpi *src = NULL;
119
switch (param) {
120
case MBEDTLS_DHM_PARAM_P:
121
src = &ctx->P;
122
break;
123
case MBEDTLS_DHM_PARAM_G:
124
src = &ctx->G;
125
break;
126
case MBEDTLS_DHM_PARAM_X:
127
src = &ctx->X;
128
break;
129
case MBEDTLS_DHM_PARAM_GX:
130
src = &ctx->GX;
131
break;
132
case MBEDTLS_DHM_PARAM_GY:
133
src = &ctx->GY;
134
break;
135
case MBEDTLS_DHM_PARAM_K:
136
src = &ctx->K;
137
break;
138
default:
139
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
140
}
141
return mbedtls_mpi_copy(dest, src);
142
}
143
144
/*
145
* Parse the ServerKeyExchange parameters
146
*/
147
int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
148
unsigned char **p,
149
const unsigned char *end)
150
{
151
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
152
153
if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
154
(ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
155
(ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) {
156
return ret;
157
}
158
159
if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
160
return ret;
161
}
162
163
return 0;
164
}
165
166
/*
167
* Pick a random R in the range [2, M-2] for blinding or key generation.
168
*/
169
static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
170
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
171
{
172
int ret;
173
174
MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng));
175
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1));
176
177
cleanup:
178
return ret;
179
}
180
181
static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size,
182
int (*f_rng)(void *, unsigned char *, size_t),
183
void *p_rng)
184
{
185
int ret = 0;
186
187
if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) {
188
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
189
}
190
if (x_size < 0) {
191
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
192
}
193
194
if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) {
195
MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
196
} else {
197
/* Generate X as large as possible ( <= P - 2 ) */
198
ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng);
199
if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
200
return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED;
201
}
202
if (ret != 0) {
203
return ret;
204
}
205
}
206
207
/*
208
* Calculate GX = G^X mod P
209
*/
210
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
211
&ctx->P, &ctx->RP));
212
213
if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) {
214
return ret;
215
}
216
217
cleanup:
218
return ret;
219
}
220
221
/*
222
* Setup and write the ServerKeyExchange parameters
223
*/
224
int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
225
unsigned char *output, size_t *olen,
226
int (*f_rng)(void *, unsigned char *, size_t),
227
void *p_rng)
228
{
229
int ret;
230
size_t n1, n2, n3;
231
unsigned char *p;
232
233
ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
234
if (ret != 0) {
235
goto cleanup;
236
}
237
238
/*
239
* Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
240
* not required". We omit leading zeros for compactness.
241
*/
242
#define DHM_MPI_EXPORT(X, n) \
243
do { \
244
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \
245
p + 2, \
246
(n))); \
247
*p++ = MBEDTLS_BYTE_1(n); \
248
*p++ = MBEDTLS_BYTE_0(n); \
249
p += (n); \
250
} while (0)
251
252
n1 = mbedtls_mpi_size(&ctx->P);
253
n2 = mbedtls_mpi_size(&ctx->G);
254
n3 = mbedtls_mpi_size(&ctx->GX);
255
256
p = output;
257
DHM_MPI_EXPORT(&ctx->P, n1);
258
DHM_MPI_EXPORT(&ctx->G, n2);
259
DHM_MPI_EXPORT(&ctx->GX, n3);
260
261
*olen = (size_t) (p - output);
262
263
cleanup:
264
if (ret != 0 && ret > -128) {
265
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret);
266
}
267
return ret;
268
}
269
270
/*
271
* Set prime modulus and generator
272
*/
273
int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
274
const mbedtls_mpi *P,
275
const mbedtls_mpi *G)
276
{
277
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
278
279
if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
280
(ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
281
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret);
282
}
283
284
return 0;
285
}
286
287
/*
288
* Import the peer's public value G^Y
289
*/
290
int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
291
const unsigned char *input, size_t ilen)
292
{
293
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
294
295
if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) {
296
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
297
}
298
299
if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) {
300
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret);
301
}
302
303
return 0;
304
}
305
306
/*
307
* Create own private value X and export G^X
308
*/
309
int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
310
unsigned char *output, size_t olen,
311
int (*f_rng)(void *, unsigned char *, size_t),
312
void *p_rng)
313
{
314
int ret;
315
316
if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) {
317
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
318
}
319
320
ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
321
if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) {
322
return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED;
323
}
324
if (ret != 0) {
325
goto cleanup;
326
}
327
328
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
329
330
cleanup:
331
if (ret != 0 && ret > -128) {
332
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret);
333
}
334
return ret;
335
}
336
337
338
/*
339
* Use the blinding method and optimisation suggested in section 10 of:
340
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
341
* DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
342
* Berlin Heidelberg, 1996. p. 104-113.
343
*/
344
static int dhm_update_blinding(mbedtls_dhm_context *ctx,
345
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
346
{
347
int ret;
348
349
/*
350
* Don't use any blinding the first time a particular X is used,
351
* but remember it to use blinding next time.
352
*/
353
if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
354
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
355
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
356
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
357
358
return 0;
359
}
360
361
/*
362
* Ok, we need blinding. Can we re-use existing values?
363
* If yes, just update them by squaring them.
364
*/
365
if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
366
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
367
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
368
369
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
370
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
371
372
return 0;
373
}
374
375
/*
376
* We need to generate blinding values from scratch
377
*/
378
379
/* Vi = random( 2, P-2 ) */
380
MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
381
382
/* Vf = Vi^-X = (Vi^-1)^X mod P */
383
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &ctx->Vf, &ctx->Vi, &ctx->P));
384
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP));
385
386
cleanup:
387
return ret;
388
}
389
390
/*
391
* Derive and export the shared secret (G^Y)^X mod P
392
*/
393
int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
394
unsigned char *output, size_t output_size, size_t *olen,
395
int (*f_rng)(void *, unsigned char *, size_t),
396
void *p_rng)
397
{
398
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
399
mbedtls_mpi GYb;
400
401
if (f_rng == NULL) {
402
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
403
}
404
405
if (output_size < mbedtls_dhm_get_len(ctx)) {
406
return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
407
}
408
409
if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
410
return ret;
411
}
412
413
mbedtls_mpi_init(&GYb);
414
415
/* Blind peer's value */
416
MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
417
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
418
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
419
420
/* Do modular exponentiation */
421
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
422
&ctx->P, &ctx->RP));
423
424
/* Unblind secret value */
425
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
426
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
427
428
/* Output the secret without any leading zero byte. This is mandatory
429
* for TLS per RFC 5246 §8.1.2. */
430
*olen = mbedtls_mpi_size(&ctx->K);
431
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
432
433
cleanup:
434
mbedtls_mpi_free(&GYb);
435
436
if (ret != 0) {
437
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret);
438
}
439
440
return 0;
441
}
442
443
/*
444
* Free the components of a DHM key
445
*/
446
void mbedtls_dhm_free(mbedtls_dhm_context *ctx)
447
{
448
if (ctx == NULL) {
449
return;
450
}
451
452
mbedtls_mpi_free(&ctx->pX);
453
mbedtls_mpi_free(&ctx->Vf);
454
mbedtls_mpi_free(&ctx->Vi);
455
mbedtls_mpi_free(&ctx->RP);
456
mbedtls_mpi_free(&ctx->K);
457
mbedtls_mpi_free(&ctx->GY);
458
mbedtls_mpi_free(&ctx->GX);
459
mbedtls_mpi_free(&ctx->X);
460
mbedtls_mpi_free(&ctx->G);
461
mbedtls_mpi_free(&ctx->P);
462
463
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
464
}
465
466
#if defined(MBEDTLS_ASN1_PARSE_C)
467
/*
468
* Parse DHM parameters
469
*/
470
int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
471
size_t dhminlen)
472
{
473
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
474
size_t len;
475
unsigned char *p, *end;
476
#if defined(MBEDTLS_PEM_PARSE_C)
477
mbedtls_pem_context pem;
478
#endif /* MBEDTLS_PEM_PARSE_C */
479
480
#if defined(MBEDTLS_PEM_PARSE_C)
481
mbedtls_pem_init(&pem);
482
483
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
484
if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') {
485
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
486
} else {
487
ret = mbedtls_pem_read_buffer(&pem,
488
"-----BEGIN DH PARAMETERS-----",
489
"-----END DH PARAMETERS-----",
490
dhmin, NULL, 0, &dhminlen);
491
}
492
493
if (ret == 0) {
494
/*
495
* Was PEM encoded
496
*/
497
dhminlen = pem.buflen;
498
} else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
499
goto exit;
500
}
501
502
p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
503
#else
504
p = (unsigned char *) dhmin;
505
#endif /* MBEDTLS_PEM_PARSE_C */
506
end = p + dhminlen;
507
508
/*
509
* DHParams ::= SEQUENCE {
510
* prime INTEGER, -- P
511
* generator INTEGER, -- g
512
* privateValueLength INTEGER OPTIONAL
513
* }
514
*/
515
if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
516
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
517
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
518
goto exit;
519
}
520
521
end = p + len;
522
523
if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
524
(ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
525
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
526
goto exit;
527
}
528
529
if (p != end) {
530
/* This might be the optional privateValueLength.
531
* If so, we can cleanly discard it */
532
mbedtls_mpi rec;
533
mbedtls_mpi_init(&rec);
534
ret = mbedtls_asn1_get_mpi(&p, end, &rec);
535
mbedtls_mpi_free(&rec);
536
if (ret != 0) {
537
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
538
goto exit;
539
}
540
if (p != end) {
541
ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT,
542
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
543
goto exit;
544
}
545
}
546
547
ret = 0;
548
549
exit:
550
#if defined(MBEDTLS_PEM_PARSE_C)
551
mbedtls_pem_free(&pem);
552
#endif
553
if (ret != 0) {
554
mbedtls_dhm_free(dhm);
555
}
556
557
return ret;
558
}
559
560
#if defined(MBEDTLS_FS_IO)
561
/*
562
* Load all data from a file into a given buffer.
563
*
564
* The file is expected to contain either PEM or DER encoded data.
565
* A terminating null byte is always appended. It is included in the announced
566
* length only if the data looks like it is PEM encoded.
567
*/
568
static int load_file(const char *path, unsigned char **buf, size_t *n)
569
{
570
FILE *f;
571
long size;
572
573
if ((f = fopen(path, "rb")) == NULL) {
574
return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
575
}
576
/* The data loaded here is public, so don't bother disabling buffering. */
577
578
fseek(f, 0, SEEK_END);
579
if ((size = ftell(f)) == -1) {
580
fclose(f);
581
return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
582
}
583
fseek(f, 0, SEEK_SET);
584
585
*n = (size_t) size;
586
587
if (*n + 1 == 0 ||
588
(*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
589
fclose(f);
590
return MBEDTLS_ERR_DHM_ALLOC_FAILED;
591
}
592
593
if (fread(*buf, 1, *n, f) != *n) {
594
fclose(f);
595
596
mbedtls_zeroize_and_free(*buf, *n + 1);
597
598
return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
599
}
600
601
fclose(f);
602
603
(*buf)[*n] = '\0';
604
605
if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
606
++*n;
607
}
608
609
return 0;
610
}
611
612
/*
613
* Load and parse DHM parameters
614
*/
615
int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
616
{
617
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
618
size_t n;
619
unsigned char *buf;
620
621
if ((ret = load_file(path, &buf, &n)) != 0) {
622
return ret;
623
}
624
625
ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
626
627
mbedtls_zeroize_and_free(buf, n);
628
629
return ret;
630
}
631
#endif /* MBEDTLS_FS_IO */
632
#endif /* MBEDTLS_ASN1_PARSE_C */
633
#endif /* MBEDTLS_DHM_ALT */
634
635
#if defined(MBEDTLS_SELF_TEST)
636
637
#if defined(MBEDTLS_PEM_PARSE_C)
638
static const char mbedtls_test_dhm_params[] =
639
"-----BEGIN DH PARAMETERS-----\r\n"
640
"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
641
"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
642
"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
643
"-----END DH PARAMETERS-----\r\n";
644
#else /* MBEDTLS_PEM_PARSE_C */
645
static const char mbedtls_test_dhm_params[] = {
646
0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
647
0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
648
0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
649
0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
650
0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
651
0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
652
0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
653
0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
654
0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
655
0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
656
0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
657
0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
658
};
659
#endif /* MBEDTLS_PEM_PARSE_C */
660
661
static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
662
663
/*
664
* Checkup routine
665
*/
666
int mbedtls_dhm_self_test(int verbose)
667
{
668
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
669
mbedtls_dhm_context dhm;
670
671
mbedtls_dhm_init(&dhm);
672
673
if (verbose != 0) {
674
mbedtls_printf(" DHM parameter load: ");
675
}
676
677
if ((ret = mbedtls_dhm_parse_dhm(&dhm,
678
(const unsigned char *) mbedtls_test_dhm_params,
679
mbedtls_test_dhm_params_len)) != 0) {
680
if (verbose != 0) {
681
mbedtls_printf("failed\n");
682
}
683
684
ret = 1;
685
goto exit;
686
}
687
688
if (verbose != 0) {
689
mbedtls_printf("passed\n\n");
690
}
691
692
exit:
693
mbedtls_dhm_free(&dhm);
694
695
return ret;
696
}
697
698
#endif /* MBEDTLS_SELF_TEST */
699
700
#endif /* MBEDTLS_DHM_C */
701
702