Codebase list libcryptx-perl / 1957543
DSA fix - key validation Karel Miko 6 years ago
5 changed file(s) with 153 addition(s) and 64 deletion(s). Raw diff Collapse all Expand all
3232 $p =~ s/^0x//;
3333 $q =~ s/^0x//;
3434 $g =~ s/^0x//;
35 return $self->_generate_key_pqg($p, $q, $g);
35 $p = "0$p" if length($p) % 2;
36 $q = "0$q" if length($q) % 2;
37 $g = "0$g" if length($g) % 2;
38 return $self->_generate_key_pqg(pack("H*",$p), pack("H*",$q), pack("H*",$g));
3639 }
3740 elsif (@_ == 1 && ref $_[0] eq 'SCALAR') {
3841 my $data = ${$_[0]};
510510 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
511511 int dsa_verify_key(dsa_key *key, int *stat);
512512 #ifdef LTC_SOURCE
513 int dsa_int_validate_key(dsa_key *key, int *stat);
513 int dsa_int_validate_xy(dsa_key *key, int *stat);
514 int dsa_int_validate_pqg(dsa_key *key, int *stat);
515 int dsa_int_validate_primes(dsa_key *key, int *stat);
514516 #endif
515517 int dsa_shared_secret(void *private_key, void *base,
516518 dsa_key *public_key,
2626 const unsigned char *g, unsigned long glen,
2727 dsa_key *key)
2828 {
29 int err;
29 int err, stat;
3030
3131 LTC_ARGCHK(p != NULL);
3232 LTC_ARGCHK(q != NULL);
4949 err = CRYPT_INVALID_PACKET;
5050 goto LBL_ERR;
5151 }
52
53 /* do only a quick validation, without primality testing */
54 if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) { goto LBL_ERR; }
55 if (stat == 0) {
56 err = CRYPT_INVALID_ARG;
57 goto LBL_ERR;
58 }
59
5260 return CRYPT_OK;
5361
5462 LBL_ERR:
8997 if ((err = mp_read_unsigned_bin(key->y, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
9098 }
9199
92 /* do only a quick validation, without primality testing */
93 if ((err = dsa_int_validate_key(key, &stat)) != CRYPT_OK) { goto LBL_ERR; }
100 if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK) { goto LBL_ERR; }
94101 if (stat == 0) {
95102 err = CRYPT_INVALID_ARG;
96103 goto LBL_ERR;
2727 */
2828 int dsa_verify_key(dsa_key *key, int *stat)
2929 {
30 int res, err;
30 int err;
3131
32 err = dsa_int_validate_primes(key, stat);
33 if (err != CRYPT_OK || *stat == 0) return err;
34
35 err = dsa_int_validate_pqg(key, stat);
36 if (err != CRYPT_OK || *stat == 0) return err;
37
38 return dsa_int_validate_xy(key, stat);
39 }
40
41 /**
42 Non-complex part (no primality testing) of the validation
43 of DSA params (p, q, g)
44
45 @param key The key to validate
46 @param stat [out] Result of test, 1==valid, 0==invalid
47 @return CRYPT_OK if successful
48 */
49 int dsa_int_validate_pqg(dsa_key *key, int *stat)
50 {
51 void *tmp1, *tmp2;
52 int err;
53
54 *stat = 0;
3255 LTC_ARGCHK(key != NULL);
3356 LTC_ARGCHK(stat != NULL);
3457
35 /* default to an invalid key */
58 /* FIPS 186-4 chapter 4.1: 1 < g < p */
59 if (mp_cmp_d(key->g, 1) != LTC_MP_GT || mp_cmp(key->g, key->p) != LTC_MP_LT) {
60 return CRYPT_OK;
61 }
62
63 if ((err = mp_init_multi(&tmp1, &tmp2, NULL)) != CRYPT_OK) { return err; }
64
65 /* FIPS 186-4 chapter 4.1: q is a divisor of (p - 1) */
66 if ((err = mp_sub_d(key->p, 1, tmp1)) != CRYPT_OK) { goto error; }
67 if ((err = mp_div(tmp1, key->q, tmp1, tmp2)) != CRYPT_OK) { goto error; }
68 if (mp_iszero(tmp2) != LTC_MP_YES) {
69 err = CRYPT_OK;
70 goto error;
71 }
72
73 /* FIPS 186-4 chapter 4.1: g is a generator of a subgroup of order q in
74 * the multiplicative group of GF(p) - so we make sure that g^q mod p = 1
75 */
76 if ((err = mp_exptmod(key->g, key->q, key->p, tmp1)) != CRYPT_OK) { goto error; }
77 if (mp_cmp_d(tmp1, 1) != LTC_MP_EQ) {
78 err = CRYPT_OK;
79 goto error;
80 }
81
82 err = CRYPT_OK;
83 *stat = 1;
84 error:
85 mp_clear_multi(tmp1, tmp2, NULL);
86 return err;
87 }
88
89 /**
90 Primality testing of DSA params p and q
91
92 @param key The key to validate
93 @param stat [out] Result of test, 1==valid, 0==invalid
94 @return CRYPT_OK if successful
95 */
96 int dsa_int_validate_primes(dsa_key *key, int *stat)
97 {
98 int err, res;
99
36100 *stat = 0;
101 LTC_ARGCHK(key != NULL);
102 LTC_ARGCHK(stat != NULL);
37103
38 /* first make sure key->q and key->p are prime */
104 /* key->q prime? */
39105 if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) {
40106 return err;
41107 }
43109 return CRYPT_OK;
44110 }
45111
112 /* key->p prime? */
46113 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) {
47114 return err;
48115 }
50117 return CRYPT_OK;
51118 }
52119
53 return dsa_int_validate_key(key, stat);
120 *stat = 1;
121 return CRYPT_OK;
54122 }
55123
56124 /**
57 Non-complex part of the validation of a DSA key
58
59 This is the computation-wise 'non-complex' part of the
60 DSA key validation
125 Validation of a DSA key (x and y values)
61126
62127 @param key The key to validate
63128 @param stat [out] Result of test, 1==valid, 0==invalid
64129 @return CRYPT_OK if successful
65130 */
66 int dsa_int_validate_key(dsa_key *key, int *stat)
131 int dsa_int_validate_xy(dsa_key *key, int *stat)
67132 {
68 void *tmp, *tmp2;
69 int err;
133 void *tmp;
134 int err;
70135
136 *stat = 0;
71137 LTC_ARGCHK(key != NULL);
72138 LTC_ARGCHK(stat != NULL);
73139
74 /* default to an invalid key */
75 *stat = 0;
76
77 /* now make sure that g is not -1, 0 or 1 and <p */
78 if (mp_cmp_d(key->g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) {
79 return CRYPT_OK;
140 /* 1 < y < p-1 */
141 if ((err = mp_init(&tmp)) != CRYPT_OK) {
142 return err;
80143 }
81 if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; }
82 if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; }
83 if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) {
144 if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) {
145 goto error;
146 }
147 if (mp_cmp_d(key->y, 1) != LTC_MP_GT || mp_cmp(key->y, tmp) != LTC_MP_LT) {
84148 err = CRYPT_OK;
85149 goto error;
86150 }
87151
88 /* 1 < y < p-1 */
89 if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) {
90 err = CRYPT_OK;
91 goto error;
152 if (key->type == PK_PRIVATE) {
153 /* FIPS 186-4 chapter 4.1: 0 < x < q */
154 if (mp_cmp_d(key->x, 0) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT) {
155 err = CRYPT_OK;
156 goto error;
157 }
158 /* FIPS 186-4 chapter 4.1: y = g^x mod p */
159 if ((err = mp_exptmod(key->g, key->x, key->p, tmp)) != CRYPT_OK) {
160 goto error;
161 }
162 if (mp_cmp(tmp, key->y) != LTC_MP_EQ) {
163 err = CRYPT_OK;
164 goto error;
165 }
166 }
167 else {
168 /* with just a public key we cannot test y = g^x mod p therefore we
169 * only test that y^q mod p = 1, which makes sure y is in g^x mod p
170 */
171 if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) {
172 goto error;
173 }
174 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
175 err = CRYPT_OK;
176 goto error;
177 }
92178 }
93179
94 /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
95 if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; }
96 if (mp_iszero(tmp2) != LTC_MP_YES) {
97 err = CRYPT_OK;
98 goto error;
99 }
100
101 if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
102 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
103 err = CRYPT_OK;
104 goto error;
105 }
106
107 /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
108 if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; }
109 if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
110 err = CRYPT_OK;
111 goto error;
112 }
113
114 /* at this point we are out of tests ;-( */
115180 err = CRYPT_OK;
116181 *stat = 1;
117182 error:
118 mp_clear_multi(tmp, tmp2, NULL);
183 mp_clear(tmp);
119184 return err;
120185 }
186
121187 #endif
122188
123189 /* ref: $Format:%D$ */
141141 {
142142 my $k = Crypt::PK::DSA->new;
143143 $k->generate_key({
144 p => "0xA717676E57280B32123B22E3F5BABC9460FEEBD53CE9ECBA2060AAD0A7128A2EA25D049D0784B08E7B3C63A53F2764".
145 "2EA5B62B44F80BDF74828F9227FACDEAC50D8698AE12722F58F52087564466FA92A38ED6158B5437A4382D7E460D".
146 "41F3FA9B7BD0808E2DDD93529F6CAD397B9287313CFE2A0F913079E86EA0FE55D2620750A57419158EDAC4BB7C97".
147 "2B7C20756C503FBBBC84EE39D0C72298CA3F9B28CD14C640D459F160ADD615F4A24300F5832DE2A874776B94D158".
148 "F77BBD13D417F5A56BE043CD358D9B983B003DF4AE20EB43A358F391CBD75668AAE9A7633815FEE4DBFF0303D097".
149 "AA2BBA9BD7ADD5B75B40ED3F756516AAB46B66872187544B8D",
150 q => "0x81EA35142EDAC0B7A9CCBB4A0D29D16803792A1FC4FD4310682CD6C0FEFD3DC7",
151 g => "0x62160328C0B7F11AD92684E27A28BF5F79D936F968C6301E339D2F18FF86106736030F4287E588AD7A79F37E7340D1
152 E3CA1D89D320F2C2BA5FDC263990456C77FBE683D620A0BB0D49DB793E48C68710750163EF822129D32CC9254218DD
153 74F2E07ACE3B51115837A6336E1CC567862651E911D5FF36D775FE600436BC21FC92076544D813C2437502FD5AC728
154 C1BCBFEA216DFC4B544D39F6D3BC301D7409EDA84A4CFDC7E3D1BB4C37A9E9D27A25ED55630119DBBC4D79E052F1A2
155 CBF5F121531DE33C1FAF2D97930E45A08DE816477711685B4D673041A4D75C8D613091274B2E8766037E4EA973A65F
156 912D74319649E698A019ADEEC66567E9D05A135E8A",
144 p => "A5903F7DF15D5C0769797820".
145 "6CFEED0113CD1C15298198E9".
146 "1F2231135A7BC42568BE8F8D".
147 "357B7EE9AD4E99F9F628EA2C".
148 "9294425FA1C7732253D478CD".
149 "1E242FA81B12C2A9ADB46D14".
150 "AC83875A2D8BF6A1DCF57EC6".
151 "4668DB3751358EB4F5A620A9".
152 "0F28C3D5F62DC1E85E3CC724".
153 "A12018B038FFA4B917AABC66".
154 "543BDD11784134CB",
155 q => "B3CA2D8B0823160915E6B73E".
156 "DD3B0015DFE1E897",
157 g => "5C9F25D69C86E8002BE04F56".
158 "90230BD008A816E7C8E9A96E".
159 "C0DBC630C62A8B42E41C8504".
160 "E682F52C02CDA74740CFA1A4".
161 "A608B8D827C5762EB69FED68".
162 "3D17DBC9050C16DEB9EC5A3E".
163 "02DF7B0E338AFFC01F878352".
164 "A2C82FB458F95DD60A7E23FE".
165 "322173F34F98452B0D16DCE2".
166 "23B15840F82B6AFCDFC6D848".
167 "9C5859DA0E4BE8B9",
157168 });
158169 ok($k, 'generate_key HASH');
159170 ok($k->is_private, 'is_private');