1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10 */
11 #include "tomcrypt.h"
12
13 /**
14 @file dsa_verify_key.c
15 DSA implementation, verify a key, Tom St Denis
16 */
17
18 #ifdef MDSA
19
20 /**
21 Verify a DSA key for validity
22 @param key The key to verify
23 @param stat [out] Result of test, 1==valid, 0==invalid
24 @return CRYPT_OK if successful
25 */
dsa_verify_key(dsa_key * key,int * stat)26 int dsa_verify_key(dsa_key *key, int *stat)
27 {
28 void *tmp, *tmp2;
29 int res, err;
30
31 LTC_ARGCHK(key != NULL);
32 LTC_ARGCHK(stat != NULL);
33
34 /* default to an invalid key */
35 *stat = 0;
36
37 /* first make sure key->q and key->p are prime */
38 if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) {
39 return err;
40 }
41 if (res == 0) {
42 return CRYPT_OK;
43 }
44
45 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) {
46 return err;
47 }
48 if (res == 0) {
49 return CRYPT_OK;
50 }
51
52 /* now make sure that g is not -1, 0 or 1 and <p */
53 if (mp_cmp_d(key->g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) {
54 return CRYPT_OK;
55 }
56 if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; }
57 if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; }
58 if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) {
59 err = CRYPT_OK;
60 goto error;
61 }
62
63 /* 1 < y < p-1 */
64 if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) {
65 err = CRYPT_OK;
66 goto error;
67 }
68
69 /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
70 if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; }
71 if (mp_iszero(tmp2) != LTC_MP_YES) {
72 err = CRYPT_OK;
73 goto error;
74 }
75
76 if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
77 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
78 err = CRYPT_OK;
79 goto error;
80 }
81
82 /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
83 if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
84 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
85 err = CRYPT_OK;
86 goto error;
87 }
88
89 /* at this point we are out of tests ;-( */
90 err = CRYPT_OK;
91 *stat = 1;
92 error:
93 mp_clear_multi(tmp, tmp2, NULL);
94 return err;
95 }
96 #endif
97
98 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_key.c,v $ */
99 /* $Revision: 1.6 $ */
100 /* $Date: 2006/12/04 03:18:43 $ */
101