ReactOS 0.4.17-dev-784-g3812a95
dsa.c
Go to the documentation of this file.
1/*
2 * Digital Signature Algorithm (DSA)
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7
8#if !defined(MBEDTLS_CONFIG_FILE)
9#include "mbedtls/config.h"
10#else
11#include MBEDTLS_CONFIG_FILE
12#endif
13
14#if defined(MBEDTLS_DSA_C)
15
16#include "mbedtls/dsa.h"
17#include "mbedtls/asn1write.h"
19
20#include <string.h>
21
22#if defined(MBEDTLS_PLATFORM_C)
23#include "mbedtls/platform.h"
24#else
25#include <stdlib.h>
26#include <stdio.h>
27#define mbedtls_printf printf
28#define mbedtls_calloc calloc
29#define mbedtls_free free
30#endif
31
32#if !defined(MBEDTLS_DSA_ALT)
33
34#define DSA_VALIDATE_RET( cond ) \
35 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DSA_BAD_INPUT_DATA )
36#define DSA_VALIDATE( cond ) \
37 MBEDTLS_INTERNAL_VALIDATE( cond )
38
39/*
40 * Initialize context
41 */
43{
44 DSA_VALIDATE( ctx != NULL );
45 memset( ctx, 0, sizeof( mbedtls_dsa_context ) );
46
47 mbedtls_mpi_init( &ctx->P );
48 mbedtls_mpi_init( &ctx->Q );
49 mbedtls_mpi_init( &ctx->G );
50 mbedtls_mpi_init( &ctx->Y );
51 mbedtls_mpi_init( &ctx->X );
52}
53
54/*
55 * Free context
56 */
58{
59 if( ctx == NULL )
60 return;
61
62 mbedtls_mpi_free( &ctx->P );
63 mbedtls_mpi_free( &ctx->Q );
64 mbedtls_mpi_free( &ctx->G );
65 mbedtls_mpi_free( &ctx->Y );
66 mbedtls_mpi_free( &ctx->X );
67
69}
70
71/*
72 * Set group parameters
73 */
75{
76 int ret;
77 DSA_VALIDATE_RET( ctx != NULL );
78 DSA_VALIDATE_RET( P != NULL );
79 DSA_VALIDATE_RET( Q != NULL );
80 DSA_VALIDATE_RET( G != NULL );
81
82 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 )
83 {
85 }
86
87 if( ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 )
88 {
90 }
91
92 if( ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
93 {
95 }
96
97 if (!ctx->len) ctx->len = mbedtls_mpi_size( &ctx->P );
98
99 return( 0 );
100}
101
108int mpi_2expt(mbedtls_mpi *a, int n)
109{
110 int ret;
111
112 DSA_VALIDATE_RET( a != NULL );
113
116
117cleanup:
118 return ret;
119}
120
121/*
122 * Generate keypair
123 */
124int mbedtls_dsa_genkey( mbedtls_dsa_context *ctx, size_t group_size, size_t modulus_size,
125 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
126{
127 int ret;
128 unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
129 int mr_tests_q, mr_tests_p, found_p, found_q;
130 mbedtls_mpi t2L1, t2N1, t2seedlen, U, U1, W, W1, X, q, q1, p, p1, e, h, h1, g, c, t2q, seedinc, seedinc1;
131 unsigned char *wbuf, *sbuf, digest[MBEDTLS_DSA_MAX_GROUP];
132 const mbedtls_md_info_t * md_info;
133
134 DSA_VALIDATE_RET( ctx != NULL );
135 DSA_VALIDATE_RET( f_rng != NULL );
136
137 /* check size */
138 DSA_VALIDATE_RET( group_size <= MBEDTLS_DSA_MAX_GROUP );
139 DSA_VALIDATE_RET( group_size >= 1 );
140 DSA_VALIDATE_RET( group_size < modulus_size );
141 DSA_VALIDATE_RET( modulus_size <= MBEDTLS_DSA_MAX_MODULUS );
142
143#if !defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA256_C)
145#endif
146
147#if defined(MBEDTLS_SHA512_C)
149#else
151#endif
152
153 seedbytes = group_size;
154 L = modulus_size * 8;
155 N = group_size * 8;
156 if (N > mbedtls_md_get_size(md_info) * 8) return MBEDTLS_ERR_DSA_BAD_INPUT_DATA; /* group_size too big */
157
158 outbytes = mbedtls_md_get_size(md_info);
159 n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;
160
161 if ((wbuf = mbedtls_calloc(1, (n+1)*outbytes)) == NULL) { ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; goto cleanup3; }
162 if ((sbuf = mbedtls_calloc(1, seedbytes)) == NULL) { ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; goto cleanup2; }
163
164 mbedtls_mpi_init( &t2L1 );
165 mbedtls_mpi_init( &t2N1 );
166 mbedtls_mpi_init( &t2seedlen );
168 mbedtls_mpi_init( &U1 );
170 mbedtls_mpi_init( &W1 );
173 mbedtls_mpi_init( &q1 );
175 mbedtls_mpi_init( &p1 );
178 mbedtls_mpi_init( &h1 );
181 mbedtls_mpi_init( &t2q );
182 mbedtls_mpi_init( &seedinc );
183 mbedtls_mpi_init( &seedinc1 );
184
185 /* M-R tests (without Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
186 if (L <= 1024) { mr_tests_p = 40; }
187 else if (L <= 2048) { mr_tests_p = 56; }
188 else { mr_tests_p = 64; }
189
190 if (N <= 160) { mr_tests_q = 40; }
191 else if (N <= 224) { mr_tests_q = 56; }
192 else { mr_tests_q = 64; }
193
194 /* t2L1 = 2^(L-1) */
195 MBEDTLS_MPI_CHK( mpi_2expt(&t2L1, L-1) );
196 /* t2N1 = 2^(N-1) */
197 MBEDTLS_MPI_CHK( mpi_2expt(&t2N1, N-1) );
198 /* t2seedlen = 2^seedlen */
199 MBEDTLS_MPI_CHK( mpi_2expt(&t2seedlen, seedbytes*8) );
200
201 /* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
202 *
203 * L = The desired length of the prime p (in bits e.g. L = 1024)
204 * N = The desired length of the prime q (in bits e.g. N = 160)
205 * seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
206 * outlen = The bit length of Hash function
207 *
208 * 1. Check that the (L, N)
209 * 2. If (seedlen <N), then return INVALID.
210 * 3. n = ceil(L / outlen) - 1
211 * 4. b = L- 1 - (n * outlen)
212 * 5. domain_parameter_seed = an arbitrary sequence of seedlen bits
213 * 6. U = Hash (domain_parameter_seed) mod 2^(N-1)
214 * 7. q = 2^(N-1) + U + 1 - (U mod 2)
215 * 8. Test whether or not q is prime as specified in Appendix C.3
216 * 9. If qis not a prime, then go to step 5.
217 * 10. offset = 1
218 * 11. For counter = 0 to (4L- 1) do {
219 * For j=0 to n do {
220 * Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
221 * }
222 * W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
223 * X = W + 2^(L-1) Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
224 * c = X mod 2*q
225 * p = X - (c - 1) Comment: p ~ 1 (mod 2*q)
226 * If (p >= 2^(L-1)) {
227 * Test whether or not p is prime as specified in Appendix C.3.
228 * If p is determined to be prime, then return VALID and the values of p, qand (optionally) the values of domain_parameter_seed and counter
229 * }
230 * offset = offset + n + 1 Comment: Increment offset
231 * }
232 */
233 for(found_p=0; !found_p;) {
234 /* q */
235 for(found_q=0; !found_q;) {
236 f_rng( p_rng, sbuf, seedbytes );
237 i = outbytes;
238 MBEDTLS_MPI_CHK( mbedtls_md(md_info, sbuf, seedbytes, digest) );
239 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&U, digest, outbytes) );
240 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&U1, &U, &t2N1) );
241 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(&q, &t2N1, &U1) );
242 if (mbedtls_mpi_get_bit(&q, 0) == 0)
243 {
246 }
247 if( mbedtls_mpi_is_prime_ext(&q, mr_tests_q, f_rng, p_rng) == 0) found_q = 1;
248 }
249 /* p */
250 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&seedinc, sbuf, seedbytes) );
252 for(counter=0; counter < 4*L && !found_p; counter++) {
253 for(j=0; j<=n; j++) {
254 MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&seedinc1, &seedinc) );
255 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&seedinc, &seedinc1, 1) );
256 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&seedinc1, &seedinc, &t2seedlen) );
257 MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&seedinc, &seedinc1) );
258 /* seedinc = (seedinc+1) % 2^seed_bitlen */
259 i = mbedtls_mpi_size(&seedinc);
260 if (i > seedbytes) { ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA; goto cleanup; }
261 mbedtls_platform_zeroize(sbuf, seedbytes);
262 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary(&seedinc, sbuf + seedbytes-i, i) );
263 i = outbytes;
264 MBEDTLS_MPI_CHK( mbedtls_md(md_info, sbuf, seedbytes, wbuf+(n-j)*outbytes) );
265 }
266 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&W, wbuf, (n+1)*outbytes) );
267 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&W1, &W, &t2L1) );
268 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(&X, &W1, &t2L1) );
272 if (mbedtls_mpi_cmp_mpi(&p, &t2L1) >= 0) {
273 /* p >= 2^(L-1) */
274 if( mbedtls_mpi_is_prime_ext(&p, mr_tests_p, f_rng, p_rng) == 0 ) found_p = 1;
275 }
276 }
277 }
278
279 /* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
280 * 1. e = (p - 1)/q
281 * 2. h = any integer satisfying: 1 < h < (p - 1)
282 * h could be obtained from a random number generator or from a counter that changes after each use
283 * 3. g = h^e mod p
284 * 4. if (g == 1), then go to step 2.
285 *
286 */
287
288 /* e = (p - 1)/q */
291
292 i = mbedtls_mpi_size(&p);
293 do {
294 /* h is random and 1 < h < (p-1) */
295 do {
296 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random(&h, i, f_rng, p_rng) );
297 } while (mbedtls_mpi_cmp_mpi(&h, &p) >= 0 || mbedtls_mpi_cmp_int(&h, 2) <= 0);
299 /* g = h^e mod p */
301 } while (mbedtls_mpi_cmp_int(&g, 1) == 0);
302
306
308
309 /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
310 do {
311 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, mbedtls_mpi_size( &q1 ), f_rng, p_rng ) );
312 } while ( mbedtls_mpi_cmp_int( &ctx->X, 1 ) < 0 || mbedtls_mpi_cmp_mpi( &ctx->X, &q1 ) > 0 );
313
314 /* compute y = g^x mod p */
315 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Y, &ctx->G, &ctx->X, &ctx->P, NULL ) );
316
317cleanup:
318 mbedtls_mpi_free( &t2L1 );
319 mbedtls_mpi_free( &t2N1 );
320 mbedtls_mpi_free( &t2seedlen );
322 mbedtls_mpi_free( &U1 );
324 mbedtls_mpi_free( &W1 );
327 mbedtls_mpi_free( &q1 );
329 mbedtls_mpi_free( &p1 );
332 mbedtls_mpi_free( &h1 );
335 mbedtls_mpi_free( &t2q );
336 mbedtls_mpi_free( &seedinc );
337 mbedtls_mpi_free( &seedinc1 );
338 mbedtls_free(sbuf);
339cleanup2:
340 mbedtls_free(wbuf);
341cleanup3:
342 return( ret );
343}
344
345/*
346 * Check group parameters
347 */
348int mbedtls_dsa_check_pqg( const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G )
349{
350 int ret = 0;
351 mbedtls_mpi P1, T;
352
353 DSA_VALIDATE_RET( P != NULL );
354 DSA_VALIDATE_RET( Q != NULL );
355 DSA_VALIDATE_RET( G != NULL );
356
357 mbedtls_mpi_init( &P1 );
359
360 if( mbedtls_mpi_cmp_int( P, 0 ) == 0 )
361 {
363 goto cleanup;
364 }
365
366 if( mbedtls_mpi_cmp_int( Q, 0 ) == 0 )
367 {
369 goto cleanup;
370 }
371
372 if( mbedtls_mpi_cmp_int( G, 0 ) == 0 )
373 {
375 goto cleanup;
376 }
377
378 /* Check if P-1 is a multiple of Q */
381 if( mbedtls_mpi_cmp_int( &T, 0 ) != 0 )
382 {
384 goto cleanup;
385 }
386
387 /* Check if 1 < G < P */
388 if( mbedtls_mpi_cmp_int( G, 1 ) <= 0 || mbedtls_mpi_cmp_mpi( G, P ) >= 0 )
389 {
391 goto cleanup;
392 }
393
394 /* Check if G^Q mod P = 1 */
396 if( mbedtls_mpi_cmp_int( &T, 1 ) != 0 )
397 {
399 goto cleanup;
400 }
401
402cleanup:
403 mbedtls_mpi_free( &P1 );
405
406 return( ret );
407}
408
409/*
410 * Check public key
411 */
413{
414 int ret = 0;
416
417 DSA_VALIDATE_RET( ctx != NULL );
418
419 /* Y must be in [2, P-1] */
420 if( mbedtls_mpi_cmp_int( &ctx->Y, 2 ) < 0 ||
421 mbedtls_mpi_cmp_mpi( &ctx->Y, &ctx->P ) >= 0 )
422 {
424 }
425
427
428 /* Y^Q mod P = 1 */
429 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &ctx->Y, &ctx->Q, &ctx->P, NULL ) );
430 if( mbedtls_mpi_cmp_int( &T, 1 ) != 0 )
431 {
433 }
434
435cleanup:
437 return( ret );
438}
439
440/*
441 * Check private key
442 */
444{
445 int ret = 0;
447
448 DSA_VALIDATE_RET( ctx != NULL );
449
450 /* X must be in ]0, Q[ */
451 if( mbedtls_mpi_cmp_int( &ctx->X, 0 ) <= 0 ||
452 mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->Q ) >= 0 )
453 {
455 }
456
458
459 /* Y = G^X mod P */
460 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &ctx->G, &ctx->X, &ctx->P, NULL ) );
461 if( mbedtls_mpi_cmp_mpi( &T, &ctx->Y ) != 0 )
462 {
464 }
465
466cleanup:
468 return( ret );
469}
470
471/*
472 * Derive public key from private key
473 */
475{
476 int ret = 0;
477
478 DSA_VALIDATE_RET( ctx != NULL );
479
480 /* X must be in ]0, Q[ */
481 if( mbedtls_mpi_cmp_int( &ctx->X, 0 ) <= 0 ||
482 mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->Q ) >= 0 )
483 {
485 }
486
487 /* Y = G^X mod P */
488 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Y, &ctx->G, &ctx->X, &ctx->P, NULL ) );
489
490cleanup:
491 return( ret );
492}
493
494/*
495 * Convert a signature (given by context) to ASN.1
496 */
497static int dsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
498 unsigned char *sig, size_t *slen )
499{
500 int ret;
502 unsigned char *p = buf + sizeof( buf );
503 size_t len = 0;
504
507
511
512 memcpy( sig, p, len );
513 *slen = len;
514
515 return( 0 );
516}
517
518/*
519 * Compute and write signature
520 */
522 const unsigned char *hash, size_t hlen,
523 unsigned char *sig, size_t *slen,
524 int (*f_rng)(void *, unsigned char *, size_t),
525 void *p_rng )
526{
527 int ret;
528 mbedtls_mpi k, r, rp, kq, gcd, s, xr, xrh, xrhkq, h;
529 size_t hashlen, qlen;
530
531 DSA_VALIDATE_RET( ctx != NULL );
532 DSA_VALIDATE_RET( hash != NULL );
533 DSA_VALIDATE_RET( sig != NULL );
534 DSA_VALIDATE_RET( slen != NULL );
535 DSA_VALIDATE_RET( f_rng != NULL );
536
539 mbedtls_mpi_init( &rp );
540 mbedtls_mpi_init( &kq );
543 mbedtls_mpi_init( &xr );
544 mbedtls_mpi_init( &xrh );
545 mbedtls_mpi_init( &xrhkq );
547
548 /* FIPS 186-4 4.7: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash' */
549 qlen = mbedtls_mpi_size( &ctx->Q );
550 hashlen = hlen;
551 if (hashlen > qlen) hashlen = qlen;
552
554
555retry:
556 do
557 {
558 /* gen random k */
559 if( mbedtls_mpi_fill_random( &k, qlen, f_rng, p_rng ) != 0 ) goto cleanup;
560
561 /* k should be from range: 1 <= k <= q-1 (see FIPS 186-4 B.2.2) */
562 if( mbedtls_mpi_cmp_int( &k, 0 ) <= 0 || mbedtls_mpi_cmp_mpi( &k, &ctx->Q ) >= 0 ) goto retry;
563
564 /* test gcd */
565 if( mbedtls_mpi_gcd( &gcd, &k, &ctx->Q ) != 0 ) goto cleanup;
566
567 } while( mbedtls_mpi_cmp_int( &gcd, 1 ) != 0 );
568
569 /* now find 1/k mod q */
570 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &kq, &k, &ctx->Q ) );
571
572 /* now find r = g^k mod p mod q */
573 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &rp, &ctx->G, &k, &ctx->P, NULL ) );
574 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &r, &rp, &ctx->Q ) );
575
576 /* now find s = (hash + xr)/k mod q */
577 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &xr, &ctx->X, &r ) );
578 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &xrh, &xr, &h ) );
579 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &xrhkq, &xrh, &kq ) );
580 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &s, &xrhkq, &ctx->Q ) );
581
582 MBEDTLS_MPI_CHK( dsa_signature_to_asn1( &r, &s, sig, slen ) );
583
584cleanup:
587 mbedtls_mpi_init( &rp );
588 mbedtls_mpi_init( &kq );
591 mbedtls_mpi_init( &xr );
592 mbedtls_mpi_init( &xrh );
593 mbedtls_mpi_init( &xrhkq );
595
596 return( ret );
597}
598
599/*
600 * Read and check signature
601 */
603 const unsigned char *hash, size_t hlen,
604 const unsigned char *sig, size_t slen )
605{
606 int ret;
607 unsigned char *p = (unsigned char *) sig;
608 const unsigned char *end = sig + slen;
609 size_t len, hashlen, qlen;
610 mbedtls_mpi r, s, h, w, hw, rw, u1, u2, gu1, yu2, u12, u12p, v, _rr;
611
612 DSA_VALIDATE_RET( ctx != NULL );
613 DSA_VALIDATE_RET( hash != NULL );
614 DSA_VALIDATE_RET( sig != NULL );
615
620 mbedtls_mpi_init( &hw );
624 mbedtls_mpi_init( &gu1 );
625 mbedtls_mpi_init( &yu2 );
626 mbedtls_mpi_init( &u12 );
627 mbedtls_mpi_init( &u12p );
629 mbedtls_mpi_init( &_rr );
630
631 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
633 {
635 goto cleanup;
636 }
637
638 if( p + len != end )
639 {
641 goto cleanup;
642 }
643
644 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
645 ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
646 {
648 goto cleanup;
649 }
650
651 if( mbedtls_mpi_cmp_int( &r, 0 ) <= 0 || mbedtls_mpi_cmp_mpi( &r, &ctx->Q ) >= 0 ||
652 mbedtls_mpi_cmp_int( &s, 0 ) <= 0 || mbedtls_mpi_cmp_mpi( &s, &ctx->Q ) >= 0 )
653 {
655 goto cleanup;
656 }
657
658 /* FIPS 186-4 4.7: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash' */
659 qlen = mbedtls_mpi_size( &ctx->Q );
660 hashlen = hlen;
661 if (hashlen > qlen) hashlen = qlen;
662
664
665 /* w = 1/s mod q */
667
668 /* u1 = h*w mod q */
670 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &hw, &ctx->Q ) );
671
672 /* u2 = r*w mod q */
675
676 /* v = g^u1 * y^u2 mod p mod q */
677 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &gu1, &ctx->G, &u1, &ctx->P, &_rr ) );
678 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &yu2, &ctx->Y, &u2, &ctx->P, &_rr ) );
679
680 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u12, &gu1, &yu2 ) );
681 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u12p, &u12, &ctx->P ) );
682 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &v, &u12p, &ctx->Q ) );
683
684 /* if r = v then it is verified */
685 if( mbedtls_mpi_cmp_mpi( &v, &r ) != 0 )
686 {
688 goto cleanup;
689 }
690
691cleanup:
698 mbedtls_mpi_init( &gu1 );
699 mbedtls_mpi_init( &yu2 );
700 mbedtls_mpi_init( &u12 );
701 mbedtls_mpi_init( &u12p );
703 mbedtls_mpi_free( &_rr );
704
705 return( ret );
706}
707
708#endif /* MBEDTLS_DSA_ALT */
709
710#if defined(MBEDTLS_SELF_TEST)
711
712static const char *dsa_test_p_hex = "F7E75FDC469067FFDC4E847C51F452DF27303F51D8F2E3E444924563740179E1";
713static const char *dsa_test_q_hex = "87E85B349454331564214218435B420E53368DB1";
714static const char *dsa_test_g_hex = "F7E75FDC469067FFDC4E847C51F452DF27303F51D8F2E3E444924563740179E1";
715static const char *dsa_test_x_hex = "20B4822143298349213489213498213498213948";
716static const char *dsa_test_y_hex = "154285095685091850198501985091850918509185091850918509185091850918509185091850918509185091850918509185091850918509185091850918509185";
717static const char *dsa_test_hash_hex = "A9993E364706816ABA3E25717850C26C9CD0D89D";
718
719/*
720 * Checkup routine
721 */
722int mbedtls_dsa_self_test( int verbose )
723{
724 int ret;
726 unsigned char sig[MBEDTLS_DSA_ASN_SIGNATURE_MAX_LEN];
727 size_t slen;
728 unsigned char hash[20];
729
730 mbedtls_dsa_init( &dsa );
731
732 if( verbose != 0 )
733 mbedtls_printf( " DSA key generation: " );
734
735 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &dsa.P, 16, dsa_test_p_hex ) );
736 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &dsa.Q, 16, dsa_test_q_hex ) );
737 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &dsa.G, 16, dsa_test_g_hex ) );
738 dsa.len = mbedtls_mpi_size( &dsa.P );
739
740 if( ( ret = mbedtls_dsa_genkey( &dsa, NULL, NULL ) ) != 0 )
741 {
742 if( verbose != 0 )
743 mbedtls_printf( "failed\n" );
744
745 ret = 1;
746 goto exit;
747 }
748
749 if( verbose != 0 )
750 mbedtls_printf( "passed\n DSA signature: " );
751
752 memcpy( hash, dsa_test_hash_hex, 20 );
753
754 if( ( ret = mbedtls_dsa_write_signature( &dsa, MBEDTLS_MD_SHA1, hash, 20, sig, &slen, NULL, NULL ) ) != 0 )
755 {
756 if( verbose != 0 )
757 mbedtls_printf( "failed\n" );
758
759 ret = 1;
760 goto exit;
761 }
762
763 if( verbose != 0 )
764 mbedtls_printf( "passed\n DSA verification: " );
765
766 if( ( ret = mbedtls_dsa_read_signature( &dsa, hash, 20, sig, slen ) ) != 0 )
767 {
768 if( verbose != 0 )
769 mbedtls_printf( "failed\n" );
770
771 ret = 1;
772 goto exit;
773 }
774
775 if( verbose != 0 )
776 mbedtls_printf( "passed\n\n" );
777
778exit:
779 mbedtls_dsa_free( &dsa );
780
781 return( ret );
782}
783
784#endif /* MBEDTLS_SELF_TEST */
785
786#endif /* MBEDTLS_DSA_C */
#define N
Definition: crc32.c:57
ASN.1 buffer writing functionality.
int mbedtls_asn1_write_tag(unsigned char **p, unsigned char *start, unsigned char tag)
Write an ASN.1 tag in ASN.1 format.
#define MBEDTLS_ASN1_CHK_ADD(g, f)
Definition: asn1write.h:60
int mbedtls_asn1_write_len(unsigned char **p, unsigned char *start, size_t len)
Write a length field in ASN.1 format.
int mbedtls_asn1_write_mpi(unsigned char **p, unsigned char *start, const mbedtls_mpi *X)
Write a arbitrary-precision number (MBEDTLS_ASN1_INTEGER) in ASN.1 format.
#define U(x)
Definition: wordpad.c:45
int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)
Import an MPI from an ASCII string.
int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a signed subtraction of MPIs: X = A - B.
int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
Perform a signed subtraction of an MPI and an integer: X = A - b.
int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
Perform a signed addition of an MPI and an integer: X = A + b.
int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Miller-Rabin primality test.
int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
Make a copy of an MPI.
int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
Modify a specific bit in an MPI.
size_t mbedtls_mpi_size(const mbedtls_mpi *X)
Return the total size of an MPI value in bytes.
int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR)
Perform a sliding-window exponentiation: X = A^E mod N.
int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a division with remainder of two MPIs: A = Q * B + R.
int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a signed addition of MPIs: X = A + B.
int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
Store integer value in MPI.
int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)
Import an MPI from unsigned big endian binary data.
int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)
Compare two MPIs.
int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a modular reduction. R = A mod B.
int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Fill an MPI with a number of random bytes.
void mbedtls_mpi_init(mbedtls_mpi *X)
Initialize an MPI context.
#define MBEDTLS_ERR_MPI_ALLOC_FAILED
Definition: bignum.h:72
int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
Perform a multiplication of two MPIs: X = A * B.
#define MBEDTLS_MPI_CHK(f)
Definition: bignum.h:74
int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
Compute the modular inverse: X = A^-1 mod N.
int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)
Get a specific bit from an MPI.
void mbedtls_mpi_free(mbedtls_mpi *X)
This function frees the components of an MPI context.
int mbedtls_mpi_write_binary(const mbedtls_mpi *X, unsigned char *buf, size_t buflen)
Export an MPI into unsigned big endian binary data of fixed size.
int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
Compare an MPI with an integer.
int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
Compute the greatest common divisor: G = gcd(A, B)
#define G(r, i, a, b, c, d)
Definition: blake2b-ref.c:117
#define NULL
Definition: types.h:112
#define W(I)
#define P(row, col)
static void cleanup(void)
Definition: main.c:1335
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
int mbedtls_dsa_set_group(mbedtls_dsa_context *ctx, const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G)
This function sets the DSA group parameters.
int mbedtls_dsa_pubkey_from_privkey(mbedtls_dsa_context *ctx)
This function derived public key from private key.
int mbedtls_dsa_verify(mbedtls_dsa_context *ctx, const unsigned char *hash, size_t hlen, const unsigned char *sig, size_t slen)
This function reads and verifies a DSA signature.
int mbedtls_dsa_check_pubkey(const mbedtls_dsa_context *ctx)
This function checks if the public key is valid.
int mbedtls_dsa_sign(mbedtls_dsa_context *ctx, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
This function computes the DSA signature of a message hash.
#define MBEDTLS_DSA_ASN_SIGNATURE_MAX_LEN
Definition: dsa.h:30
void mbedtls_dsa_init(mbedtls_dsa_context *ctx)
This function initializes a DSA context.
#define MBEDTLS_DSA_MAX_GROUP
Definition: dsa.h:33
int mbedtls_dsa_check_privkey(const mbedtls_dsa_context *ctx)
This function checks if the private key is valid.
int mbedtls_dsa_genkey(mbedtls_dsa_context *ctx, size_t group_size, size_t modulus_size, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
This function generates a DSA keypair.
#define MBEDTLS_ERR_DSA_VERIFY_FAILED
Definition: dsa.h:24
int mbedtls_dsa_check_pqg(const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G)
This function checks if the DSA group parameters are valid.
void mbedtls_dsa_free(mbedtls_dsa_context *ctx)
This function frees a DSA context.
#define MBEDTLS_ERR_DSA_BAD_INPUT_DATA
Definition: dsa.h:22
#define MBEDTLS_DSA_MAX_MODULUS
Definition: dsa.h:36
const GLdouble * v
Definition: gl.h:2040
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLboolean g
Definition: glext.h:6204
GLdouble GLdouble u2
Definition: glext.h:8308
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLdouble u1
Definition: glext.h:8308
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int mbedtls_asn1_get_mpi(unsigned char **p, const unsigned char *end, mbedtls_mpi *X)
Retrieve a MPI value from an integer ASN.1 tag. Updates the pointer to immediately behind the full ta...
#define MBEDTLS_ASN1_SEQUENCE
Definition: asn1.h:104
#define MBEDTLS_ASN1_CONSTRUCTED
Definition: asn1.h:114
int mbedtls_asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the tag. Check for the requested tag. Updates the pointer to immediately be...
#define X(b, s)
#define e
Definition: ke_i.h:82
#define c
Definition: ke_i.h:80
@ MBEDTLS_MD_SHA512
Definition: md.h:92
@ MBEDTLS_MD_SHA256
Definition: md.h:90
@ MBEDTLS_MD_SHA1
Definition: md.h:88
int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output)
This function calculates the message-digest of a buffer, with respect to a configurable message-diges...
unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
This function extracts the message-digest size from the message-digest information structure.
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int k
Definition: mpi.c:3369
void mbedtls_platform_zeroize(void *buf, size_t len)
Securely zeroize a buffer.
Definition: platform_util.c:98
Common and shared functions used by multiple modules in the Mbed TLS library.
#define rw
Definition: rosglue.h:38
#define verbose
Definition: rosglue.h:36
#define T(num)
Definition: thunks.c:311
#define mbedtls_md_info_from_type
Configuration options (set of defines)
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
#define mbedtls_free
Definition: platform.h:168
#define mbedtls_calloc
Definition: platform.h:169
#define exit(n)
Definition: config.h:202
static int gcd(int, int)
Definition: getopt.c:86
#define memset(x, y, z)
Definition: compat.h:39
Definition: polytest.cpp:36
DSA context structure.
Definition: dsa.h:46
mbedtls_mpi Q
Definition: dsa.h:49
size_t len
Definition: dsa.h:47
mbedtls_mpi P
Definition: dsa.h:48
mbedtls_mpi G
Definition: dsa.h:50
MPI structure.
Definition: bignum.h:211
#define mbedtls_printf
Definition: timing.c:57