text
[RRG-proxmark3.git] / common / mbedtls / dhm.c
blobf823f455ba9d717295b1e89e8848858ee62df95d
1 /*
2 * Diffie-Hellman-Merkle key exchange
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 * The following sources were referenced in the design of this implementation
21 * of the Diffie-Hellman-Merkle algorithm:
23 * [1] Handbook of Applied Cryptography - 1997, Chapter 12
24 * Menezes, van Oorschot and Vanstone
28 #include "common.h"
30 #if defined(MBEDTLS_DHM_C)
32 #include "mbedtls/dhm.h"
33 #include "mbedtls/platform_util.h"
34 #include "mbedtls/error.h"
36 #include <string.h>
38 #if defined(MBEDTLS_PEM_PARSE_C)
39 #include "mbedtls/pem.h"
40 #endif
42 #if defined(MBEDTLS_ASN1_PARSE_C)
43 #include "mbedtls/asn1.h"
44 #endif
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
48 #else
49 #include <stdlib.h>
50 #include <stdio.h>
51 #define mbedtls_printf printf
52 #define mbedtls_calloc calloc
53 #define mbedtls_free free
54 #endif
56 #if !defined(MBEDTLS_DHM_ALT)
58 #define DHM_VALIDATE_RET( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
60 #define DHM_VALIDATE( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE( cond )
64 * helper to validate the mbedtls_mpi size and import it
66 static int dhm_read_bignum(mbedtls_mpi *X,
67 unsigned char **p,
68 const unsigned char *end) {
69 int ret, n;
71 if (end - *p < 2)
72 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
74 n = ((*p)[0] << 8) | (*p)[1];
75 (*p) += 2;
77 if ((int)(end - *p) < n)
78 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
80 if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0)
81 return (MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret);
83 (*p) += n;
85 return (0);
89 * Verify sanity of parameter with regards to P
91 * Parameter should be: 2 <= public_param <= P - 2
93 * This means that we need to return an error if
94 * public_param < 2 or public_param > P-2
96 * For more information on the attack, see:
97 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
98 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
100 static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P) {
101 mbedtls_mpi L, U;
102 int ret = 0;
104 mbedtls_mpi_init(&L);
105 mbedtls_mpi_init(&U);
107 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&L, 2));
108 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
110 if (mbedtls_mpi_cmp_mpi(param, &L) < 0 ||
111 mbedtls_mpi_cmp_mpi(param, &U) > 0) {
112 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
115 cleanup:
116 mbedtls_mpi_free(&L);
117 mbedtls_mpi_free(&U);
118 return (ret);
121 void mbedtls_dhm_init(mbedtls_dhm_context *ctx) {
122 DHM_VALIDATE(ctx != NULL);
123 memset(ctx, 0, sizeof(mbedtls_dhm_context));
127 * Parse the ServerKeyExchange parameters
129 int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
130 unsigned char **p,
131 const unsigned char *end) {
132 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
133 DHM_VALIDATE_RET(ctx != NULL);
134 DHM_VALIDATE_RET(p != NULL && *p != NULL);
135 DHM_VALIDATE_RET(end != NULL);
137 if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
138 (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
139 (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0)
140 return (ret);
142 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0)
143 return (ret);
145 ctx->len = mbedtls_mpi_size(&ctx->P);
147 return (0);
151 * Setup and write the ServerKeyExchange parameters
153 int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
154 unsigned char *output, size_t *olen,
155 int (*f_rng)(void *, unsigned char *, size_t),
156 void *p_rng) {
157 int ret, count = 0;
158 size_t n1, n2, n3;
159 unsigned char *p;
160 DHM_VALIDATE_RET(ctx != NULL);
161 DHM_VALIDATE_RET(output != NULL);
162 DHM_VALIDATE_RET(olen != NULL);
163 DHM_VALIDATE_RET(f_rng != NULL);
165 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0)
166 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
169 * Generate X as large as possible ( < P )
171 do {
172 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
174 while (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->P) >= 0)
175 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&ctx->X, 1));
177 if (count++ > 10)
178 return (MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED);
179 } while (dhm_check_range(&ctx->X, &ctx->P) != 0);
182 * Calculate GX = G^X mod P
184 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
185 &ctx->P, &ctx->RP));
187 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0)
188 return (ret);
191 * export P, G, GX
193 #define DHM_MPI_EXPORT( X, n ) \
194 do { \
195 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
196 p + 2, \
197 ( n ) ) ); \
198 *p++ = (unsigned char)( ( n ) >> 8 ); \
199 *p++ = (unsigned char)( ( n ) ); \
200 p += ( n ); \
201 } while( 0 )
203 n1 = mbedtls_mpi_size(&ctx->P);
204 n2 = mbedtls_mpi_size(&ctx->G);
205 n3 = mbedtls_mpi_size(&ctx->GX);
207 p = output;
208 DHM_MPI_EXPORT(&ctx->P, n1);
209 DHM_MPI_EXPORT(&ctx->G, n2);
210 DHM_MPI_EXPORT(&ctx->GX, n3);
212 *olen = p - output;
214 ctx->len = n1;
216 cleanup:
218 if (ret != 0)
219 return (MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret);
221 return (0);
225 * Set prime modulus and generator
227 int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
228 const mbedtls_mpi *P,
229 const mbedtls_mpi *G) {
230 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
231 DHM_VALIDATE_RET(ctx != NULL);
232 DHM_VALIDATE_RET(P != NULL);
233 DHM_VALIDATE_RET(G != NULL);
235 if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
236 (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
237 return (MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret);
240 ctx->len = mbedtls_mpi_size(&ctx->P);
241 return (0);
245 * Import the peer's public value G^Y
247 int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
248 const unsigned char *input, size_t ilen) {
249 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
250 DHM_VALIDATE_RET(ctx != NULL);
251 DHM_VALIDATE_RET(input != NULL);
253 if (ilen < 1 || ilen > ctx->len)
254 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
256 if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0)
257 return (MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret);
259 return (0);
263 * Create own private value X and export G^X
265 int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
266 unsigned char *output, size_t olen,
267 int (*f_rng)(void *, unsigned char *, size_t),
268 void *p_rng) {
269 int ret, count = 0;
270 DHM_VALIDATE_RET(ctx != NULL);
271 DHM_VALIDATE_RET(output != NULL);
272 DHM_VALIDATE_RET(f_rng != NULL);
274 if (olen < 1 || olen > ctx->len)
275 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
277 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0)
278 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
281 * generate X and calculate GX = G^X mod P
283 do {
284 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
286 while (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->P) >= 0)
287 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&ctx->X, 1));
289 if (count++ > 10)
290 return (MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED);
291 } while (dhm_check_range(&ctx->X, &ctx->P) != 0);
293 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
294 &ctx->P, &ctx->RP));
296 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0)
297 return (ret);
299 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
301 cleanup:
303 if (ret != 0)
304 return (MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret);
306 return (0);
310 * Pick a random R in the range [2, M) for blinding purposes
312 static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
313 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) {
314 int ret, count;
316 count = 0;
317 do {
318 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(R, mbedtls_mpi_size(M), f_rng, p_rng));
320 while (mbedtls_mpi_cmp_mpi(R, M) >= 0)
321 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(R, 1));
323 if (count++ > 10)
324 return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
325 } while (mbedtls_mpi_cmp_int(R, 1) <= 0);
327 cleanup:
328 return (ret);
333 * Use the blinding method and optimisation suggested in section 10 of:
334 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
335 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
336 * Berlin Heidelberg, 1996. p. 104-113.
338 static int dhm_update_blinding(mbedtls_dhm_context *ctx,
339 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) {
340 int ret;
341 mbedtls_mpi R;
343 mbedtls_mpi_init(&R);
346 * Don't use any blinding the first time a particular X is used,
347 * but remember it to use blinding next time.
349 if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
350 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
351 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
352 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
354 return (0);
358 * Ok, we need blinding. Can we re-use existing values?
359 * If yes, just update them by squaring them.
361 if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
362 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
363 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
365 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
366 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
368 return (0);
372 * We need to generate blinding values from scratch
375 /* Vi = random( 2, P-1 ) */
376 MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
378 /* Vf = Vi^-X mod P
379 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
380 * then elevate to the Xth power. */
381 MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng));
382 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R));
383 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
384 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P));
385 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R));
386 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
388 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP));
390 cleanup:
391 mbedtls_mpi_free(&R);
393 return (ret);
397 * Derive and export the shared secret (G^Y)^X mod P
399 int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
400 unsigned char *output, size_t output_size, size_t *olen,
401 int (*f_rng)(void *, unsigned char *, size_t),
402 void *p_rng) {
403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404 mbedtls_mpi GYb;
405 DHM_VALIDATE_RET(ctx != NULL);
406 DHM_VALIDATE_RET(output != NULL);
407 DHM_VALIDATE_RET(olen != NULL);
409 if (output_size < ctx->len)
410 return (MBEDTLS_ERR_DHM_BAD_INPUT_DATA);
412 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0)
413 return (ret);
415 mbedtls_mpi_init(&GYb);
417 /* Blind peer's value */
418 if (f_rng != NULL) {
419 MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
420 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
421 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
422 } else
423 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&GYb, &ctx->GY));
425 /* Do modular exponentiation */
426 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
427 &ctx->P, &ctx->RP));
429 /* Unblind secret value */
430 if (f_rng != NULL) {
431 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
432 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
435 *olen = mbedtls_mpi_size(&ctx->K);
437 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
439 cleanup:
440 mbedtls_mpi_free(&GYb);
442 if (ret != 0)
443 return (MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret);
445 return (0);
449 * Free the components of a DHM key
451 void mbedtls_dhm_free(mbedtls_dhm_context *ctx) {
452 if (ctx == NULL)
453 return;
455 mbedtls_mpi_free(&ctx->pX);
456 mbedtls_mpi_free(&ctx->Vf);
457 mbedtls_mpi_free(&ctx->Vi);
458 mbedtls_mpi_free(&ctx->RP);
459 mbedtls_mpi_free(&ctx->K);
460 mbedtls_mpi_free(&ctx->GY);
461 mbedtls_mpi_free(&ctx->GX);
462 mbedtls_mpi_free(&ctx->X);
463 mbedtls_mpi_free(&ctx->G);
464 mbedtls_mpi_free(&ctx->P);
466 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
469 #if defined(MBEDTLS_ASN1_PARSE_C)
471 * Parse DHM parameters
473 int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
474 size_t dhminlen) {
475 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
476 size_t len;
477 unsigned char *p, *end;
478 #if defined(MBEDTLS_PEM_PARSE_C)
479 mbedtls_pem_context pem;
480 #endif /* MBEDTLS_PEM_PARSE_C */
482 DHM_VALIDATE_RET(dhm != NULL);
483 DHM_VALIDATE_RET(dhmin != NULL);
485 #if defined(MBEDTLS_PEM_PARSE_C)
486 mbedtls_pem_init(&pem);
488 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
489 if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0')
490 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
491 else
492 ret = mbedtls_pem_read_buffer(&pem,
493 "-----BEGIN DH PARAMETERS-----",
494 "-----END DH PARAMETERS-----",
495 dhmin, NULL, 0, &dhminlen);
497 if (ret == 0) {
499 * Was PEM encoded
501 dhminlen = pem.buflen;
502 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT)
503 goto exit;
505 p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
506 #else
507 p = (unsigned char *) dhmin;
508 #endif /* MBEDTLS_PEM_PARSE_C */
509 end = p + dhminlen;
512 * DHParams ::= SEQUENCE {
513 * prime INTEGER, -- P
514 * generator INTEGER, -- g
515 * privateValueLength INTEGER OPTIONAL
518 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
519 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
520 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
521 goto exit;
524 end = p + len;
526 if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
527 (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
528 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
529 goto exit;
532 if (p != end) {
533 /* This might be the optional privateValueLength.
534 * If so, we can cleanly discard it */
535 mbedtls_mpi rec;
536 mbedtls_mpi_init(&rec);
537 ret = mbedtls_asn1_get_mpi(&p, end, &rec);
538 mbedtls_mpi_free(&rec);
539 if (ret != 0) {
540 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
541 goto exit;
543 if (p != end) {
544 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
545 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
546 goto exit;
550 ret = 0;
552 dhm->len = mbedtls_mpi_size(&dhm->P);
554 exit:
555 #if defined(MBEDTLS_PEM_PARSE_C)
556 mbedtls_pem_free(&pem);
557 #endif
558 if (ret != 0)
559 mbedtls_dhm_free(dhm);
561 return (ret);
564 #if defined(MBEDTLS_FS_IO)
566 * Load all data from a file into a given buffer.
568 * The file is expected to contain either PEM or DER encoded data.
569 * A terminating null byte is always appended. It is included in the announced
570 * length only if the data looks like it is PEM encoded.
572 static int load_file(const char *path, unsigned char **buf, size_t *n) {
573 FILE *f;
574 long size;
576 if ((f = fopen(path, "rb")) == NULL)
577 return (MBEDTLS_ERR_DHM_FILE_IO_ERROR);
579 fseek(f, 0, SEEK_END);
580 if ((size = ftell(f)) == -1) {
581 fclose(f);
582 return (MBEDTLS_ERR_DHM_FILE_IO_ERROR);
584 fseek(f, 0, SEEK_SET);
586 *n = (size_t) size;
588 if (*n + 1 == 0 ||
589 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
590 fclose(f);
591 return (MBEDTLS_ERR_DHM_ALLOC_FAILED);
594 if (fread(*buf, 1, *n, f) != *n) {
595 fclose(f);
597 mbedtls_platform_zeroize(*buf, *n + 1);
598 mbedtls_free(*buf);
600 return (MBEDTLS_ERR_DHM_FILE_IO_ERROR);
603 fclose(f);
605 (*buf)[*n] = '\0';
607 if (strstr((const char *) *buf, "-----BEGIN ") != NULL)
608 ++*n;
610 return (0);
614 * Load and parse DHM parameters
616 int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path) {
617 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
618 size_t n;
619 unsigned char *buf;
620 DHM_VALIDATE_RET(dhm != NULL);
621 DHM_VALIDATE_RET(path != NULL);
623 if ((ret = load_file(path, &buf, &n)) != 0)
624 return (ret);
626 ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
628 mbedtls_platform_zeroize(buf, n);
629 mbedtls_free(buf);
631 return (ret);
633 #endif /* MBEDTLS_FS_IO */
634 #endif /* MBEDTLS_ASN1_PARSE_C */
635 #endif /* MBEDTLS_DHM_ALT */
637 #if defined(MBEDTLS_SELF_TEST)
639 #if defined(MBEDTLS_PEM_PARSE_C)
640 static const char mbedtls_test_dhm_params[] =
641 "-----BEGIN DH PARAMETERS-----\r\n"
642 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
643 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
644 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
645 "-----END DH PARAMETERS-----\r\n";
646 #else /* MBEDTLS_PEM_PARSE_C */
647 static const char mbedtls_test_dhm_params[] = {
648 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
649 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
650 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
651 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
652 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
653 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
654 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
655 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
656 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
657 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
658 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
659 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
661 #endif /* MBEDTLS_PEM_PARSE_C */
663 static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
666 * Checkup routine
668 int mbedtls_dhm_self_test(int verbose) {
669 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
670 mbedtls_dhm_context dhm;
672 mbedtls_dhm_init(&dhm);
674 if (verbose != 0)
675 mbedtls_printf(" DHM parameter load: ");
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");
683 ret = 1;
684 goto exit;
687 if (verbose != 0)
688 mbedtls_printf("passed\n\n");
690 exit:
691 mbedtls_dhm_free(&dhm);
693 return (ret);
696 #endif /* MBEDTLS_SELF_TEST */
698 #endif /* MBEDTLS_DHM_C */