Codebase list libcryptx-perl / 6d2813f
Enhance Crypt::PK::DH (#10) Crypt::PK::DH - accept base/prime values Lance Kinley authored 7 years ago karel-m committed 7 years ago
12 changed file(s) with 791 addition(s) and 89 deletion(s). Raw diff Collapse all Expand all
1616 RETVAL
1717
1818 void
19 generate_key(Crypt::PK::DH self, int key_size=256)
19 _generate_key(Crypt::PK::DH self, int key_size=256)
2020 PPCODE:
2121 {
2222 int rv;
3030 }
3131
3232 void
33 _generate_key_ex(Crypt::PK::DH self, SV * g, SV * p)
34 PPCODE:
35 {
36 int rv;
37 STRLEN p_len = 0;
38 STRLEN g_len = 0;
39 unsigned char *p_ptr=NULL;
40 unsigned char *g_ptr=NULL;
41
42 p_ptr = (unsigned char *)SvPVbyte(p, p_len);
43 g_ptr = (unsigned char *)SvPVbyte(g, g_len);
44
45 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
46 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
47 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
48 /* gen the key */
49 rv = dh_make_key_ex(&self->yarrow_prng_state, self->yarrow_prng_index, (const char *) g_ptr, (const char *) p_ptr, &self->key);
50 if (rv != CRYPT_OK) croak("FATAL: dh_make_key_ex failed: %s", error_to_string(rv));
51 XPUSHs(ST(0)); /* return self */
52 }
53
54 void
3355 _import(Crypt::PK::DH self, SV * key_data)
3456 PPCODE:
3557 {
4163 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
4264 rv = dh_import(data, (unsigned long)data_len, &self->key);
4365 if (rv != CRYPT_OK) croak("FATAL: dh_import failed: %s", error_to_string(rv));
66 XPUSHs(ST(0)); /* return self */
67 }
68
69 void
70 _import_raw(Crypt::PK::DH self, SV * raw_key, int type, char * g, char * p)
71 PPCODE:
72 {
73 int rv;
74 unsigned char *data=NULL;
75 STRLEN data_len=0;
76
77 data = (unsigned char *)SvPVbyte(raw_key, data_len);
78 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
79 /* public */
80 if (type == 0) {
81 rv = dh_import_raw(data, (unsigned long)data_len, PK_PUBLIC, g, p, &self->key);
82 if (rv != CRYPT_OK) croak("FATAL: dh_import_raw failed: %s", error_to_string(rv));
83 }
84 /* private */
85 else if (type == 1) {
86 rv = dh_import_raw(data, (unsigned long)data_len, PK_PRIVATE, g, p, &self->key);
87 if (rv != CRYPT_OK) croak("FATAL: dh_import_raw failed: %s", error_to_string(rv));
88 }
89 else {
90 croak("FATAL: import_raw invalid type '%d'", type);
91 }
92
4493 XPUSHs(ST(0)); /* return self */
4594 }
4695
94143 else{
95144 not_used = hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
96145 }
97 /* =====> name */
98 snprintf(buf, sizeof(buf), "DH-%d", dh_get_size(&self->key)*8);
99 not_used = hv_store(rv_hash, "name", 4, newSVpv(buf, strlen(buf)), 0);
146 /* =====> p */
147 siz = (self->key.prime) ? mp_unsigned_bin_size(self->key.prime) : 0;
148 if (siz>10000) {
149 croak("FATAL: key2hash failed - 'p' too big number");
150 }
151 if (siz>0) {
152 mp_tohex(self->key.prime, buf);
153 not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
154 }
155 else {
156 not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
157 }
158
159 /* =====> g */
160 siz = (self->key.base) ? mp_unsigned_bin_size(self->key.base) : 0;
161 if (siz>10000) {
162 croak("FATAL: key2hash failed - 'g' too big number");
163 }
164 if (siz>0) {
165 mp_tohex(self->key.base, buf);
166 not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
167 }
168 else {
169 not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
170 }
100171 /* =====> size */
101172 not_used = hv_store(rv_hash, "size", 4, newSViv(dh_get_size(&self->key)), 0);
102173 /* =====> type */
106177 OUTPUT:
107178 RETVAL
108179
180 SV*
181 params2hash(Crypt::PK::DH self)
182 PREINIT:
183 HV *rv_hash;
184 long siz;
185 char buf[20001];
186 SV **not_used;
187 CODE:
188 if (self->key.type == -1) XSRETURN_UNDEF;
189 rv_hash = newHV();
190 /* =====> p */
191 siz = (self->key.prime) ? mp_unsigned_bin_size(self->key.prime) : 0;
192 if (siz>10000) {
193 croak("FATAL: key2hash failed - 'p' too big number");
194 }
195 if (siz>0) {
196 mp_tohex(self->key.prime, buf);
197 not_used = hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
198 }
199 else {
200 not_used = hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
201 }
202
203 /* =====> g */
204 siz = (self->key.base) ? mp_unsigned_bin_size(self->key.base) : 0;
205 if (siz>10000) {
206 croak("FATAL: key2hash failed - 'g' too big number");
207 }
208 if (siz>0) {
209 mp_tohex(self->key.base, buf);
210 not_used = hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
211 }
212 else {
213 not_used = hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
214 }
215 if (not_used) not_used = NULL; /* just silence the warning: variable 'not_used' set but not used */
216 RETVAL = newRV_noinc((SV*)rv_hash);
217 OUTPUT:
218 RETVAL
219
109220 SV *
110221 export_key(Crypt::PK::DH self, char * type)
111222 CODE:
112223 {
113224 int rv;
114 unsigned char out[4096];
115225 unsigned long int out_len = 4096;
226 unsigned char out[out_len];
116227
117228 RETVAL = newSVpvn(NULL, 0); /* undef */
118229 if (strnEQ(type, "private", 7)) {
139250 int rv, hash_id;
140251 unsigned char *data_ptr=NULL;
141252 STRLEN data_len=0;
142 unsigned char buffer[1024];
143253 unsigned long buffer_len = 1024;
254 unsigned char buffer[buffer_len];
144255
145256 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
146257
162273 int rv;
163274 unsigned char *data_ptr=NULL;
164275 STRLEN data_len=0;
165 unsigned char buffer[1024];
166276 unsigned long buffer_len = 1024;
277 unsigned char buffer[buffer_len];
167278
168279 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
169280
170281 rv = dh_decrypt_key(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
171 if (rv != CRYPT_OK) croak("FATAL: dh_decrypt_key_ex failed: %s", error_to_string(rv));
282 if (rv != CRYPT_OK) croak("FATAL: dh_decrypt_key failed: %s", error_to_string(rv));
172283 RETVAL = newSVpvn((char*)buffer, buffer_len);
173284 }
174285 OUTPUT:
181292 int rv;
182293 unsigned char *data_ptr=NULL;
183294 STRLEN data_len=0;
184 unsigned char buffer[1024];
185295 unsigned long buffer_len = 1024;
296 unsigned char buffer[buffer_len];
186297
187298 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
188299
189300 rv = dh_sign_hash(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
190301 &self->yarrow_prng_state, self->yarrow_prng_index,
191302 &self->key);
192 if (rv != CRYPT_OK) croak("FATAL: dh_sign_hash_ex failed: %s", error_to_string(rv));
303 if (rv != CRYPT_OK) croak("FATAL: dh_sign_hash failed: %s", error_to_string(rv));
193304 RETVAL = newSVpvn((char*)buffer, buffer_len);
194305 }
195306 OUTPUT:
220331 CODE:
221332 {
222333 int rv;
223 unsigned char buffer[1024];
224334 unsigned long buffer_len = 1024;
335 unsigned char buffer[buffer_len];
225336
226337 rv = dh_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
227338 if (rv != CRYPT_OK) croak("FATAL: dh_shared_secret failed: %s", error_to_string(rv));
230341 OUTPUT:
231342 RETVAL
232343
344 SV *
345 export_key_raw(Crypt::PK::DH self, char * type)
346 CODE:
347 {
348 int rv, len;
349 unsigned long buffer_len = 1024;
350 unsigned char buffer[buffer_len];
351 void *key;
352
353 RETVAL = newSVpvn(NULL, 0); /* undef */
354 if (strnEQ(type, "private", 7)) {
355 key = self->key.x;
356 }
357 else if (strnEQ(type, "public", 6)) {
358 key = self->key.y;
359 }
360 else {
361 croak("FATAL: export_key_raw: invalid type '%s'", type);
362 }
363
364 len = (unsigned long)mp_unsigned_bin_size(key);
365 if (buffer_len < len) {
366 croak("FATAL: %s", error_to_string(CRYPT_BUFFER_OVERFLOW));
367 }
368 rv = mp_to_unsigned_bin(key, buffer);
369 if (rv != CRYPT_OK) croak("FATAL: %s", error_to_string(rv));
370 RETVAL = newSVpvn((char*)buffer, len);
371 }
372 OUTPUT:
373 RETVAL
374
375 int
376 _is_pubkey_valid(Crypt::PK::DH self);
377 CODE:
378 {
379 int rv, i, bits_set = 0;
380 mp_int one, two, p1, *y;
381 mp_digit digit;
382
383 if ((rv = mp_init_multi(&one, &two, &p1, NULL)) != MP_OKAY) {
384 croak("FATAL: %s", error_to_string(rv));
385 }
386
387 y = self->key.y;
388 mp_set(&one, 1);
389 mp_set(&two, 2);
390
391 /* p1 = p-1 */
392 if ((rv = mp_sub(self->key.prime, &one, &p1)) != MP_OKAY) {
393 croak("FATAL: %s", error_to_string(rv));
394 }
395 /* valid public key cannot be negative */
396 if (y->sign == MP_NEG) {
397 RETVAL = 0;
398 }
399 /* valid public key != 1 */
400 else if (mp_cmp(y, &one) == MP_EQ) {
401 RETVAL = 0;
402 }
403 /* public key cannot be > p-1 */
404 else if (mp_cmp(y, &p1) == MP_GT) {
405 RETVAL = 0;
406 }
407 /* if base == 2, public must have more than one bit set */
408 else if (mp_cmp(self->key.base, &two) == MP_EQ) {
409 for (i = 0; i < y->used; i++) {
410 digit = y->dp[i];
411 while (digit > ((mp_digit) 0)) {
412 if (digit & ((mp_digit) 1))
413 bits_set++;
414 digit >>= ((mp_digit) 1);
415 }
416 }
417 if (bits_set > 1)
418 RETVAL = 1;
419 else RETVAL = 0;
420 }
421 else RETVAL = 1;
422 }
423 OUTPUT:
424 RETVAL
425
233426 void
234427 DESTROY(Crypt::PK::DH self)
235428 CODE:
1010 use Carp;
1111 use CryptX;
1212 use Crypt::Digest 'digest_data';
13 use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64);
13 use Crypt::Misc qw(read_rawfile);
14
15 my %DH_PARAMS = (
16 ike768 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
17 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
18 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
19 'E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF'
20 },
21 ike1024 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
22 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
23 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
24 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
25 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381'.
26 'FFFFFFFFFFFFFFFF'
27 },
28 ike1536 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
29 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
30 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
31 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
32 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'.
33 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'.
34 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'.
35 '670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF'
36 },
37 ike2048 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
38 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
39 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
40 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
41 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'.
42 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'.
43 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'.
44 '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'.
45 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'.
46 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'.
47 '15728E5A8AACAA68FFFFFFFFFFFFFFFF'
48 },
49 ike3072 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
50 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
51 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
52 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
53 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'.
54 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'.
55 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'.
56 '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'.
57 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'.
58 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'.
59 '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'.
60 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'.
61 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'.
62 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'.
63 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'.
64 '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'
65 },
66 ike4096 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
67 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
68 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
69 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
70 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'.
71 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'.
72 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'.
73 '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'.
74 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'.
75 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'.
76 '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'.
77 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'.
78 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'.
79 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'.
80 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'.
81 '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'.
82 '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'.
83 '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'.
84 '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'.
85 '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'.
86 '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199'.
87 'FFFFFFFFFFFFFFFF'
88 },
89 ike6144 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
90 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
91 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
92 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
93 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'.
94 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'.
95 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'.
96 '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'.
97 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'.
98 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'.
99 '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'.
100 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'.
101 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'.
102 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'.
103 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'.
104 '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'.
105 '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'.
106 '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'.
107 '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'.
108 '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'.
109 '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'.
110 '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'.
111 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'.
112 '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'.
113 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'.
114 '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'.
115 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'.
116 '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'.
117 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'.
118 '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'.
119 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'.
120 '12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'
121 },
122 ike8192 => { g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'.
123 '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'.
124 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'.
125 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'.
126 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'.
127 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'.
128 '83655D23DCA3AD961C62F356208552BB9ED529077096966D'.
129 '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'.
130 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'.
131 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'.
132 '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'.
133 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'.
134 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'.
135 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'.
136 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'.
137 '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'.
138 '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'.
139 '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'.
140 '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'.
141 '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'.
142 '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'.
143 '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'.
144 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'.
145 '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'.
146 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'.
147 '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'.
148 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'.
149 '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'.
150 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'.
151 '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'.
152 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'.
153 '12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4'.
154 '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300'.
155 '741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568'.
156 '3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9'.
157 '22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B'.
158 '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A'.
159 '062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36'.
160 '4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1'.
161 'B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92'.
162 '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47'.
163 '9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71'.
164 '60C980DD98EDD3DFFFFFFFFFFFFFFFFF'
165 }
166 );
14167
15168 sub new {
16169 my ($class, $f) = @_;
36189 return $self->_import($data);
37190 }
38191
192 sub import_key_raw {
193 my ($self, $raw_bytes, $type, $param) = @_;
194 my ($g, $p, $x, $y);
195
196 if (ref $param eq 'HASH') {
197 $g = $param->{g} or croak "FATAL: 'g' param not specified";
198 $p = $param->{p} or croak "FATAL: 'p' param not specified";
199 $g =~ s/^0x//;
200 $p =~ s/^0x//;
201 } elsif (my $dhparam = $DH_PARAMS{$param}) {
202 $g = $dhparam->{g};
203 $p = $dhparam->{p};
204 } else {
205 croak "FATAL: invalid parameter";
206 }
207
208 if ($type eq 'private') {
209 $type = 1;
210 } elsif ($type eq 'public') {
211 $type = 0;
212 } else {
213 croak "FATAL: invalid key type '$type'";
214 }
215 my $rv = $self->_import_raw($raw_bytes, $type, $g, $p);
216 croak "FATAL: invalid public key" unless $self->_is_pubkey_valid;
217 return $rv;
218 }
219
39220 sub encrypt {
40221 my ($self, $data, $hash_name) = @_;
41222 $hash_name = Crypt::Digest::_trans_digest_name($hash_name||'SHA1');
69250 sub verify_hash {
70251 my ($self, $sig, $data_hash) = @_;
71252 return $self->_verify($sig, $data_hash);
253 }
254
255 sub generate_key {
256 my ($key,$param) = @_;
257
258 if (!ref $param) {
259 if (my $dhparam = $DH_PARAMS{$param}) {
260 $param = $dhparam;
261 } else {
262 croak "FATAL: invalid key length" unless ($param >= 96 || $param <= 512);
263 return $key->_generate_key($param);
264 }
265 }
266 my $g = $param->{g} or croak "FATAL: 'g' param not specified";
267 my $p = $param->{p} or croak "FATAL: 'p' param not specified";
268 $g =~ s/^0x//;
269 $p =~ s/^0x//;
270 return $key->_generate_key_ex($g, $p);
72271 }
73272
74273 ### FUNCTIONS
162361 #Key generation
163362 my $pk = Crypt::PK::DH->new();
164363 $pk->generate_key(128);
364 my $private = $pk->export_key('private');
365 my $public = $pk->export_key('public');
366
367 or
368
369 my $pk = Crypt::PK::DH->new();
370 $pk->generate_key('ike2048');
371 my $private = $pk->export_key('private');
372 my $public = $pk->export_key('public');
373
374 or
375
376 my $pk = Crypt::PK::DH->new();
377 $pk->generate_key({ p => $p, g => $g });
165378 my $private = $pk->export_key('private');
166379 my $public = $pk->export_key('public');
167380
207420 # 384 => DH-3072
208421 # 512 => DH-4096
209422
423 $pk->generate_key($name)
424 ### $name corresponds to values defined in RFC7296 and RFC3526
425 # ike768 => 768-bit MODP (Group 1)
426 # ike1024 => 1024-bit MODP (Group 2)
427 # ike1536 => 1536-bit MODP (Group 5)
428 # ike2048 => 2048-bit MODP (Group 14)
429 # ike3072 => 3072-bit MODP (Group 15)
430 # ike4096 => 4096-bit MODP (Group 16)
431 # ike6144 => 6144-bit MODP (Group 17)
432 # ike8192 => 8192-bit MODP (Group 18)
433
434 $pk->generate_key($param_hash)
435 ## $param_hash is { g => $g, p => $p }
436 ## where $g is the generator (base) in a hex string and $p is the prime in a hex string
437
210438 =head2 import_key
211439
212440 Loads private or public key (exported by L</export_key>).
215443 #or
216444 $pk->import_key(\$buffer_containing_key);
217445
446 =head2 import_key_raw
447
448 $pk->import_key_raw($raw_bytes, $type, $params)
449 ### $raw_bytes is a binary string containing the key
450 ### $type is either 'private' or 'public'
451 ### $param is either a name ('ike2038') or hash containing the p,g values { g=>$g, p=>$p }
452 ### in hex strings
453
218454 =head2 export_key
219455
220456 my $private = $pk->export_key('private');
221457 #or
222458 my $public = $pk->export_key('public');
459
460 =head2 export_key_raw
461
462 $raw_bytes = $dh->export_key_raw('public')
463 #or
464 $raw_bytes = $dh->export_key_raw('private')
223465
224466 =head2 encrypt
225467
295537 {
296538 type => 0, # integer: 1 .. private, 0 .. public
297539 size => 256, # integer: key size in bytes
298 name => "DH-2048", # internal libtomcrypt name
299540 x => "FBC1062F73B9A17BB8473A2F5A074911FA7F20D28FB...", #private key
300541 y => "AB9AAA40774D3CD476B52F82E7EE2D8A8D40CD88BF4...", #public key
542 g => "2", # generator/base
543 p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime
544 }
545
546 =head2 params2hash
547
548 my $params = $pk->params2hash;
549
550 # returns hash like this (or undef if no key loaded):
551 {
552 g => "2", # generator/base
553 p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime
301554 }
302555
303556 =head1 FUNCTIONS
175175 int idx, type;
176176 void *x;
177177 void *y;
178 void *base;
179 void *prime;
178180 } dh_key;
179181
180182 int dh_compat_test(void);
182184 int dh_get_size(dh_key *key);
183185
184186 int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key);
187 int dh_make_key_ex(prng_state *prng, int wprng, const char *g, const char *p, dh_key *key);
188 int dh_make_key_ex_main(prng_state *prng, int wprng, dh_key *key);
185189 void dh_free(dh_key *key);
186190
187191 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key);
188192 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key);
193 int dh_import_raw(unsigned char *in, unsigned long inlen, int type,
194 const char *base, const char *prime, dh_key *key);
189195
190196 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
191197 unsigned char *out, unsigned long *outlen);
9494 int dh_get_size(dh_key *key)
9595 {
9696 LTC_ARGCHK(key != NULL);
97 if (key->idx == SUPPLIED_PRIME) {
98 return mp_unsigned_bin_size(key->prime);
99 }
97100 if (dh_is_valid_idx(key->idx) == 1) {
98101 return sets[key->idx].size;
99102 } else {
111114 */
112115 int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
113116 {
114 unsigned char *buf;
115117 unsigned long x;
116 void *p, *g;
117118 int err;
118
119 LTC_ARGCHK(key != NULL);
120
121 /* good prng? */
122 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
123 return err;
124 }
125119
126120 /* find key size */
127121 for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
135129 }
136130 key->idx = x;
137131
132 if ((err = mp_init_multi(&key->base, &key->prime, NULL)) != CRYPT_OK) {
133 goto error;
134 }
135 if ((err = mp_read_radix(key->base, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; }
136 if ((err = mp_read_radix(key->prime, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
137 return dh_make_key_ex_main(prng, wprng, key);
138 error:
139 mp_clear_multi(key->base, key->prime, NULL);
140 return err;
141 }
142
143 /**
144 Make a DH key [private key pair] from provided base and prime
145 @param prng An active PRNG state
146 @param wprng The index for the PRNG you desire to use
147 @param keysize The key size (octets) desired
148 @param base The base (generator) to create the key from
149 @param prime The prime to create the key from
150 @param key [out] Where the newly created DH key will be stored
151 @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically.
152 */
153 int dh_make_key_ex(prng_state *prng, int wprng, const char *base, const char *prime, dh_key *key)
154 {
155 int err;
156
157 LTC_ARGCHK(base != NULL);
158 LTC_ARGCHK(prime != NULL);
159 LTC_ARGCHK(key != NULL);
160
161 /* good prng? */
162 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
163 return err;
164 }
165
166 if ((err = mp_init_multi(&key->base, &key->prime, NULL)) != CRYPT_OK) {
167 goto error;
168 }
169 if ((err = mp_read_radix(key->base, base, 16)) != CRYPT_OK) { goto error; }
170 if ((err = mp_read_radix(key->prime, prime, 16)) != CRYPT_OK) { goto error; }
171 key->idx = SUPPLIED_PRIME;
172 return dh_make_key_ex_main(prng, wprng, key);
173 error:
174 mp_clear_multi(key->base, key->prime, NULL);
175 return err;
176 }
177
178
179 int dh_make_key_ex_main(prng_state *prng, int wprng, dh_key *key)
180 {
181 unsigned char *buf;
182 int err, keysize;
183
184 LTC_ARGCHK(key != NULL);
185 LTC_ARGCHK(key->prime != NULL);
186 LTC_ARGCHK(key->base != NULL);
187
188 /* init parameters */
189 if ((err = mp_init_multi(&key->x, &key->y, NULL)) != CRYPT_OK) {
190 goto error;
191 }
192
193 keysize = dh_get_size(key);
194 if (keysize < 96) {
195 return CRYPT_INVALID_KEYSIZE;
196 }
197
138198 /* allocate buffer */
139199 buf = XMALLOC(keysize);
140200 if (buf == NULL) {
142202 }
143203
144204 /* make up random string */
145 if ( rng_make_prng( keysize, wprng, prng, NULL) != CRYPT_OK) {
146 err = CRYPT_ERROR_READPRNG;
205 if ( (err = rng_make_prng( keysize, wprng, prng, NULL)) != CRYPT_OK) {
206 /*err = CRYPT_ERROR_READPRNG;*/
147207 goto error2;
148208 }
149209
152212 goto error2;
153213 }
154214
155 /* init parameters */
156 if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != CRYPT_OK) {
157 goto error;
158 }
159
160 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error; }
161 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
162
163215 /* load the x value */
164 if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; }
165 if ((err = mp_exptmod(g, key->x, p, key->y)) != CRYPT_OK) { goto error; }
216 if ((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) { goto error; }
217 if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto error; }
166218 key->type = PK_PRIVATE;
167219
168220 /* free up ram */
169221 err = CRYPT_OK;
170222 goto done;
171223 error:
172 mp_clear_multi(key->x, key->y, NULL);
224 mp_clear_multi(key->base, key->prime, key->x, key->y, NULL);
173225 done:
174 mp_clear_multi(p, g, NULL);
175226 error2:
176227 #ifdef LTC_CLEAN_STACK
177228 zeromem(buf, keysize);
187238 void dh_free(dh_key *key)
188239 {
189240 LTC_ARGCHKVD(key != NULL);
241 if ( key->base ) {
242 mp_clear( key->base );
243 key->base = NULL;
244 }
245 if ( key->prime ) {
246 mp_clear( key->prime );
247 key->prime = NULL;
248 }
190249 if ( key->x ) {
191 mp_clear( key->x );
192 key->x = NULL;
250 mp_clear( key->x );
251 key->x = NULL;
193252 }
194253 if ( key->y ) {
195 mp_clear( key->y );
196 key->y = NULL;
254 mp_clear( key->y );
255 key->y = NULL;
197256 }
198257 }
199258
228287
229288 /* header */
230289 out[y++] = type;
231 out[y++] = (unsigned char)(sets[key->idx].size / 8);
290 out[y++] = key->idx == SUPPLIED_PRIME ?
291 SUPPLIED_PRIME :
292 (unsigned char)(sets[key->idx].size / 8);
232293
233294 /* export y */
234295 OUTPUT_BIGNUM(key->y, out, y, z);
237298 /* export x */
238299 OUTPUT_BIGNUM(key->x, out, y, z);
239300 }
301 /* export g and p */
302 if (key->idx == SUPPLIED_PRIME) {
303 OUTPUT_BIGNUM(key->base, out, y, z);
304 OUTPUT_BIGNUM(key->prime, out, y, z);
305 }
240306
241307 /* store header */
242308 packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY);
244310 /* store len */
245311 *outlen = y;
246312 return CRYPT_OK;
313 }
314
315 /**
316 Import a DH key from a binary string
317 @param in The string to read
318 @param inlen The length of the input packet
319 @param type The type of key. PK_PRIVATE or PK_PUBLIC
320 @param base The base (generator) in hex string
321 @param prime The prime in hex string
322 @param key [out] Where to import the key to
323 @return CRYPT_OK if successful, on error all allocated memory is freed automatically
324 */
325 int dh_import_raw(unsigned char *in, unsigned long inlen, int type,
326 const char *base, const char *prime, dh_key *key)
327 {
328 int err;
329
330 LTC_ARGCHK(in != NULL);
331 LTC_ARGCHK(base != NULL);
332 LTC_ARGCHK(prime != NULL);
333 LTC_ARGCHK(key != NULL);
334
335 if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
336 goto error;
337 }
338 if ((err = mp_read_radix(key->base, base, 16)) != CRYPT_OK) { goto error; }
339 if ((err = mp_read_radix(key->prime, prime, 16)) != CRYPT_OK) { goto error; }
340 key->idx = SUPPLIED_PRIME;
341
342 if (type == PK_PRIVATE) {
343 /* load the x value */
344 if ((err = mp_read_unsigned_bin(key->x, in, inlen)) != CRYPT_OK) { goto error; }
345 if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto error; }
346 key->type = PK_PRIVATE;
347 } else {
348 /* load the y value */
349 if ((err = mp_read_unsigned_bin(key->y, in, inlen)) != CRYPT_OK) { goto error; }
350 key->type = PK_PUBLIC;
351 mp_clear(key->x);
352 key->x = NULL;
353 }
354 key->idx = SUPPLIED_PRIME;
355 return CRYPT_OK;
356 error:
357 mp_clear_multi(key->y, key->x, key->base, key->prime, NULL);
358 return err;
247359 }
248360
249361 /**
255367 */
256368 int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
257369 {
258 unsigned long x, y, s;
370 long x, y, s;
259371 int err;
260372
261373 LTC_ARGCHK(in != NULL);
272384 }
273385
274386 /* init */
275 if ((err = mp_init_multi(&key->x, &key->y, NULL)) != CRYPT_OK) {
387 if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
276388 return err;
277389 }
278390
283395 key->type = (int)in[y++];
284396
285397 /* key size in bytes */
286 s = (unsigned long)in[y++] * 8;
287
288 for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
289 if (sets[x].size == 0) {
290 err = CRYPT_INVALID_KEYSIZE;
291 goto error;
292 }
293 key->idx = (int)x;
398 s = (int)in[y++];
399
400 if (s == SUPPLIED_PRIME) {
401 /* key from provided p,g values */
402 key->idx = SUPPLIED_PRIME;
403 } else {
404 s *= 8;
405 for (x = 0; (s > sets[x].size) && (sets[x].size != 0); x++);
406 if (sets[x].size == 0) {
407 err = CRYPT_INVALID_KEYSIZE;
408 goto error;
409 }
410 key->idx = (int)x;
411 if ((err = mp_read_radix(key->base, (char *)sets[x].base, 64)) != CRYPT_OK) { goto error; }
412 if ((err = mp_read_radix(key->prime, (char *)sets[x].prime, 64)) != CRYPT_OK) { goto error; }
413 }
294414
295415 /* type check both values */
296416 if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
309429
310430 if (key->type == PK_PRIVATE) {
311431 INPUT_BIGNUM(key->x, in, x, y, inlen);
432 /* if idx = SUPPLIED_PRIME then prime is not from static table */
433 }
434 if (key->idx == SUPPLIED_PRIME) {
435 INPUT_BIGNUM(key->base, in, x, y, inlen);
436 INPUT_BIGNUM(key->prime, in, x, y, inlen);
312437 }
313438
314439 /* eliminate private key if public */
319444
320445 return CRYPT_OK;
321446 error:
322 mp_clear_multi(key->y, key->x, NULL);
447 mp_clear_multi(key->y, key->x, key->base, key->prime, NULL);
323448 return err;
324449 }
325450
334459 int dh_shared_secret(dh_key *private_key, dh_key *public_key,
335460 unsigned char *out, unsigned long *outlen)
336461 {
337 void *tmp, *p;
462 void *tmp;
338463 unsigned long x;
339464 int err;
340465
354479 }
355480
356481 /* compute y^x mod p */
357 if ((err = mp_init_multi(&tmp, &p, NULL)) != CRYPT_OK) {
482 if ((err = mp_init(&tmp)) != CRYPT_OK) {
358483 return err;
359484 }
360485
361 if ((err = mp_read_radix(p, (char *)sets[private_key->idx].prime, 64)) != CRYPT_OK) { goto error; }
362 if ((err = mp_exptmod(public_key->y, private_key->x, p, tmp)) != CRYPT_OK) { goto error; }
486 if ((err = mp_exptmod(public_key->y, private_key->x, private_key->prime, tmp)) != CRYPT_OK) { goto error; }
363487
364488 /* enough space for output? */
365489 x = (unsigned long)mp_unsigned_bin_size(tmp);
373497 goto done;
374498 error:
375499 done:
376 mp_clear_multi(p, tmp, NULL);
500 mp_clear(tmp);
377501 return err;
378502 }
379503
151151 {
152152 int x;
153153
154 if (n == SUPPLIED_PRIME)
155 return 1;
154156 for (x = 0; sets[x].size; x++);
155157 if ((n < 0) || (n >= x)) {
156158 return 0;
6868 y += x; \
6969 }
7070
71 #define SUPPLIED_PRIME 255
72
7173 static void packet_store_header (unsigned char *dst, int section, int subsection)
7274 {
7375 LTC_ARGCHKVD(dst != NULL);
7777 }
7878
7979 /* make a random key and export the public copy */
80 if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
80 pubkey.idx = key->idx;
81 if ((err = mp_init_multi(&pubkey.base, &pubkey.prime, NULL)) != CRYPT_OK) {
82 goto LBL_ERR;
83 }
84 if ((err = mp_copy(key->base, pubkey.base)) != CRYPT_OK) { goto LBL_ERR; }
85 if ((err = mp_copy(key->prime, pubkey.prime)) != CRYPT_OK) { goto LBL_ERR; }
86 if ((err = dh_make_key_ex_main(prng, wprng, &pubkey)) != CRYPT_OK) {
8187 goto LBL_ERR;
8288 }
8389
306312 unsigned char *out, unsigned long *outlen,
307313 prng_state *prng, int wprng, dh_key *key)
308314 {
309 void *a, *b, *k, *m, *g, *p, *p1, *tmp;
315 void *a, *b, *k, *m, *p1, *tmp;
310316 unsigned char *buf;
311317 unsigned long x, y;
312318 int err;
337343 * since the order of the group is prime
338344 * we need not check if gcd(k, r) is 1
339345 */
340 if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) !=
341 (unsigned long)(sets[key->idx].size)) {
346 if (prng_descriptor[wprng].read(buf, dh_get_size(key), prng) !=
347 (unsigned long)(dh_get_size(key))) {
342348 err = CRYPT_ERROR_READPRNG;
343349 goto LBL_ERR_1;
344350 }
345351
346352 /* init bignums */
347 if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != CRYPT_OK) {
348 goto LBL_ERR;
349 }
350
351 /* load k and m */
352 if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
353 if ((err = mp_read_unsigned_bin(k, buf, sets[key->idx].size)) != CRYPT_OK) { goto LBL_ERR; }
354
355 /* load g, p and p1 */
356 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto LBL_ERR; }
357 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto LBL_ERR; }
358 if ((err = mp_sub_d(p, 1, p1)) != CRYPT_OK) { goto LBL_ERR; }
359 if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto LBL_ERR; } /* p1 = (p-1)/2 */
360
353 if ((err = mp_init_multi(&a, &b, &k, &m, &p1, &tmp, NULL)) != CRYPT_OK) {
354 goto LBL_ERR;
355 }
356
357 /* load k, m and p1 */
358 if ((err = mp_read_unsigned_bin(m, (unsigned char *)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
359 if ((err = mp_read_unsigned_bin(k, buf, dh_get_size(key))) != CRYPT_OK) { goto LBL_ERR; }
360 if ((err = mp_sub_d(key->prime, 1, p1)) != CRYPT_OK) { goto LBL_ERR; }
361 if ((err = mp_div_2(p1, p1)) != CRYPT_OK) { goto LBL_ERR; } /* p1 = (p-1)/2 */
361362 /* now get a = g^k mod p */
362 if ((err = mp_exptmod(g, k, p, a)) != CRYPT_OK) { goto LBL_ERR; }
363 if ((err = mp_exptmod(key->base, k, key->prime, a)) != CRYPT_OK) { goto LBL_ERR; }
363364
364365 /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
365 if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto LBL_ERR; } /* k = 1/k mod p1 */
366 if ((err = mp_invmod(k, p1, k)) != CRYPT_OK) { goto LBL_ERR; } /* k = 1/k mod p1 */
366367 if ((err = mp_mulmod(a, key->x, p1, tmp)) != CRYPT_OK) { goto LBL_ERR; } /* tmp = xa */
367368 if ((err = mp_submod(m, tmp, p1, tmp)) != CRYPT_OK) { goto LBL_ERR; } /* tmp = M - xa */
368369 if ((err = mp_mulmod(k, tmp, p1, b)) != CRYPT_OK) { goto LBL_ERR; } /* b = (M - xa)/k */
399400
400401 err = CRYPT_OK;
401402 LBL_ERR:
402 mp_clear_multi(tmp, p1, g, p, m, k, b, a, NULL);
403 mp_clear_multi(tmp, p1, m, k, b, a, NULL);
403404 LBL_ERR_1:
404405
405406 XFREE(buf);
448449 y = PACKET_SIZE;
449450
450451 /* init all bignums */
451 if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != CRYPT_OK) {
452 if ((err = mp_init_multi(&a, &b, &m, &tmp, NULL)) != CRYPT_OK) {
452453 return err;
453454 }
454455
456457 INPUT_BIGNUM(a, sig, x, y, siglen);
457458 INPUT_BIGNUM(b, sig, x, y, siglen);
458459
459 /* load p and g */
460 if ((err = mp_read_radix(p, sets[key->idx].prime, 64)) != CRYPT_OK) { goto error1; }
461 if ((err = mp_read_radix(g, sets[key->idx].base, 64)) != CRYPT_OK) { goto error1; }
462
463460 /* load m */
464461 if ((err = mp_read_unsigned_bin(m, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error1; }
465462
466463 /* find g^m mod p */
467 if ((err = mp_exptmod(g, m, p, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */
464 if ((err = mp_exptmod(key->base, m, key->prime, m)) != CRYPT_OK) { goto error1; } /* m = g^m mod p */
468465
469466 /* find y^a * a^b */
470 if ((err = mp_exptmod(key->y, a, p, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */
471 if ((err = mp_exptmod(a, b, p, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */
472 if ((err = mp_mulmod(a, tmp, p, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */
467 if ((err = mp_exptmod(key->y, a, key->prime, tmp)) != CRYPT_OK) { goto error1; } /* tmp = y^a mod p */
468 if ((err = mp_exptmod(a, b, key->prime, a)) != CRYPT_OK) { goto error1; } /* a = a^b mod p */
469 if ((err = mp_mulmod(a, tmp, key->prime, a)) != CRYPT_OK) { goto error1; } /* a = y^a * a^b mod p */
473470
474471 /* y^a * a^b == g^m ??? */
475472 if (mp_cmp(a, m) == 0) {
482479 error1:
483480 error:
484481 done:
485 mp_clear_multi(tmp, m, g, p, b, a, NULL);
482 mp_clear_multi(tmp, m, b, a, NULL);
486483 return err;
487484 }
488485
00 use strict;
11 use warnings;
2 use Test::More tests => 28;
2 use Test::More tests => 74;
33
44 use Crypt::PK::DH qw(dh_encrypt dh_decrypt dh_sign_message dh_verify_message dh_sign_hash dh_verify_hash dh_shared_secret);
55
2626 }
2727
2828 {
29 my $k;
30
31 $k = Crypt::PK::DH->new('t/data/cryptx_priv_dh_pg1.bin');
32 ok($k, 'load cryptx_priv_dh_pg1.bin');
33 ok($k->is_private, 'is_private cryptx_priv_dh_pg1.bin');
34 is($k->size, 256, 'size');
35 is(uc($k->key2hash->{x}), '29BB37065071D1C23AE0D8C555E24E5E546954B985260ECC6A1A21252FCFD2D633B0580F6A00B80ED75123EC37A3E784F888EE026C1034CD930CA58464EB6A59A090D1113855AFA48C9A79631E2534D7F33FAD4DC8FF48E88C865E517B67DAD4B40D64BD67CBFE52F56FBC6764D0629E5EFF63351AF19FF398375BDCE22FBDF3A044DAB2B6EAAA44D1A78F4FF74088175E6B5F184222F116F4C6188547F90B0ADCA3255EA7148CB57E5E852E79F438F995CFC3AC79A01D2C329C0750D55FDADCC6FAF6D6850892EEC073FD77CC7F98D8D317D402E2A89E4161001DAEF43DAC0F386E48870D457FB12CC5B70E6F5719609631CB8B439DB6D2F04CF8A774678F68', 'key2hash');
36
37 $k = Crypt::PK::DH->new('t/data/cryptx_priv_dh_pg2.bin');
38 ok($k, 'load cryptx_priv_dh_pg2.bin');
39 ok($k->is_private, 'is_private cryptx_priv_dh_pg2.bin');
40
41 $k = Crypt::PK::DH->new('t/data/cryptx_pub_dh_pg1.bin');
42 ok($k, 'load cryptx_pub_dh_pg1.bin');
43 ok(!$k->is_private, 'is_private cryptx_pub_dh_pg1.bin');
44
45 $k = Crypt::PK::DH->new('t/data/cryptx_pub_dh_pg2.bin');
46 ok($k, 'load cryptx_pub_dh_pg2.bin');
47 ok(!$k->is_private, 'is_private cryptx_pub_dh_pg2.bin');
48 }
49
50 {
2951 my $pr1 = Crypt::PK::DH->new;
3052 $pr1->import_key('t/data/cryptx_priv_dh1.bin');
3153 my $pu1 = Crypt::PK::DH->new;
5072 my $pu2 = Crypt::PK::DH->new;
5173 $pu2->import_key('t/data/cryptx_pub_dh2.bin');
5274
75 my $ss1 = $pr1->shared_secret($pu2);
76 my $ss2 = $pr2->shared_secret($pu1);
77 is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret');
78 }
79
80 {
81 my $pr1 = Crypt::PK::DH->new;
82 $pr1->import_key('t/data/cryptx_priv_dh_pg1.bin');
83 my $pu1 = Crypt::PK::DH->new;
84 $pu1->import_key('t/data/cryptx_pub_dh_pg1.bin');
85
86 my $ct = $pu1->encrypt("secret message");
87 my $pt = $pr1->decrypt($ct);
88 ok(length $ct > 100, 'encrypt ' . length($ct));
89 is($pt, "secret message", 'decrypt');
90
91 my $sig = $pr1->sign_message("message");
92 ok(length $sig > 60, 'sign_message ' . length($sig));
93 ok($pu1->verify_message($sig, "message"), 'verify_message');
94
95 my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd");
96 $sig = $pr1->sign_hash($hash, 'SHA1');
97 ok(length $sig > 60, 'sign_hash ' . length($sig));
98 ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash');
99
100 my $pr2 = Crypt::PK::DH->new;
101 $pr2->import_key('t/data/cryptx_priv_dh_pg2.bin');
102 my $pu2 = Crypt::PK::DH->new;
103 $pu2->import_key('t/data/cryptx_pub_dh_pg2.bin');
104
105 my $ss1 = $pr1->shared_secret($pu2);
106 my $ss2 = $pr2->shared_secret($pu1);
107 is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret');
108 }
109
110 {
111 my $pr1 = Crypt::PK::DH->new;
112 $pr1->import_key_raw(pack('H*','5F7EF8D4F7D80C2D88ADADDFE57F4F4DC578259E3B5F42D82838D5905FF6D2BECDC489452D3F5807EF4E2361821089DDC9B27198D79E9C22EE249318688FE250CCC69E49C5F985777405A76264C5EF0D83AEA1C368B1E1A48DC0E04D6E0C884F0C95A3949B29A05437A6179E7AADCC4D095A55C03046296C02AA9991EFD17745615726D52B8B8A12DAC7218265DBB4B760176C27E644AD2EC15B238980326BE1B27D5AC28EA2B2DC5F24FD6A315CA2193A23370B130B541D54C470AD91BE20ECD697B01C2DAEE00E0027A9EBD2D87404E20ADE1DE3B92798928B837AC5EFB305C168823D362A1162C7A709A70E6619F01AF113E316376B3561F88AC2B6F647B2'),'private','ike2048');
113 my $pu1 = Crypt::PK::DH->new;
114 $pu1->import_key_raw(pack('H*','4B9ECB56202EDBC6578072A4519EBE625DE8972877462240F62393C59A6C04AA159E56505156E7DF645FF6EC588E0778A96B78B26A0793D90A4B5C5EC4C61EA69D21C630843ACC2BFD3864CD9DA9600BA8F1B7D8542B01F7251AA3AC257C7AC65A1D2BCF51A8E3E67D9544599B0956710E2B052CDA9B565CDD121CC123364B480E9E7E2237D3D6B5B1E200C7BF858C54CCD3175736DB28336210A16F8F0ACEC08847EF7905FAB7E97E626CFD13CBDF167441FEEB72CB6E7407DFC59F03249F79312A94DA89B1D61196B41E90C08D2C801FD7BEA02A47A1CDA1581F57BA700C1BCDDE6338718E19079055194CAF176D85464957D405B04CC3DD9756C211E11BF2'),'public','ike2048');
115 ok($pr1, 'import_key_raw private1');
116 ok($pu1, 'import_key_raw public1');
117 ok($pr1->is_private, 'is_private private1');
118 ok(!$pu1->is_private, 'is_private public1');
119 is(uc(unpack('H*',$pr1->export_key_raw('private'))),'5F7EF8D4F7D80C2D88ADADDFE57F4F4DC578259E3B5F42D82838D5905FF6D2BECDC489452D3F5807EF4E2361821089DDC9B27198D79E9C22EE249318688FE250CCC69E49C5F985777405A76264C5EF0D83AEA1C368B1E1A48DC0E04D6E0C884F0C95A3949B29A05437A6179E7AADCC4D095A55C03046296C02AA9991EFD17745615726D52B8B8A12DAC7218265DBB4B760176C27E644AD2EC15B238980326BE1B27D5AC28EA2B2DC5F24FD6A315CA2193A23370B130B541D54C470AD91BE20ECD697B01C2DAEE00E0027A9EBD2D87404E20ADE1DE3B92798928B837AC5EFB305C168823D362A1162C7A709A70E6619F01AF113E316376B3561F88AC2B6F647B2');
120 is(uc(unpack('H*',$pr1->export_key_raw('public'))),'4B9ECB56202EDBC6578072A4519EBE625DE8972877462240F62393C59A6C04AA159E56505156E7DF645FF6EC588E0778A96B78B26A0793D90A4B5C5EC4C61EA69D21C630843ACC2BFD3864CD9DA9600BA8F1B7D8542B01F7251AA3AC257C7AC65A1D2BCF51A8E3E67D9544599B0956710E2B052CDA9B565CDD121CC123364B480E9E7E2237D3D6B5B1E200C7BF858C54CCD3175736DB28336210A16F8F0ACEC08847EF7905FAB7E97E626CFD13CBDF167441FEEB72CB6E7407DFC59F03249F79312A94DA89B1D61196B41E90C08D2C801FD7BEA02A47A1CDA1581F57BA700C1BCDDE6338718E19079055194CAF176D85464957D405B04CC3DD9756C211E11BF2');
121 is(uc(unpack('H*',$pu1->export_key_raw('public'))),'4B9ECB56202EDBC6578072A4519EBE625DE8972877462240F62393C59A6C04AA159E56505156E7DF645FF6EC588E0778A96B78B26A0793D90A4B5C5EC4C61EA69D21C630843ACC2BFD3864CD9DA9600BA8F1B7D8542B01F7251AA3AC257C7AC65A1D2BCF51A8E3E67D9544599B0956710E2B052CDA9B565CDD121CC123364B480E9E7E2237D3D6B5B1E200C7BF858C54CCD3175736DB28336210A16F8F0ACEC08847EF7905FAB7E97E626CFD13CBDF167441FEEB72CB6E7407DFC59F03249F79312A94DA89B1D61196B41E90C08D2C801FD7BEA02A47A1CDA1581F57BA700C1BCDDE6338718E19079055194CAF176D85464957D405B04CC3DD9756C211E11BF2');
122
123 my $ct = $pu1->encrypt("secret message");
124 my $pt = $pr1->decrypt($ct);
125 ok(length $ct > 100, 'encrypt ' . length($ct));
126 is($pt, "secret message", 'decrypt');
127
128 my $sig = $pr1->sign_message("message");
129 ok(length $sig > 60, 'sign_message ' . length($sig));
130 ok($pu1->verify_message($sig, "message"), 'verify_message');
131
132 my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd");
133 $sig = $pr1->sign_hash($hash, 'SHA1');
134 ok(length $sig > 60, 'sign_hash ' . length($sig));
135 ok($pu1->verify_hash($sig, $hash, 'SHA1'), 'verify_hash');
136
137 my $pr2 = Crypt::PK::DH->new;
138 $pr2->import_key_raw(pack('H*','473156C909EBB0A6F61F707CDDD7E6401BFDE22BC57B8D3CCC30C4CD3FF7678CCD9B022167AA774786F367FE5B5924A3C1E09AA71264F94E7ABA87FFA888913BB9592613F8AD87FBE82E99064B00CE3294CFD410BCFB4C88A46F5F8532633458C317DF40F395C2F08A822D84BF4291A1A63DE1F6D0F460DB81C685ADD0F26262307823227C17B4671BCF74A6337738BB4596337644656A060F1BB109640878D23F56E493719D6EF60FEA7AC85123CFB6E476392789AC1FE4F4CA371DB2863192ADE424F3EFDEE52D4CB445B99B10566A4B6F6DC813C265DC0052D710AEAA0969392BD478A46AB9C7A0E2FA27964A759938904FCEFAC4CE061C9927764AAB57DC'),'private','ike2048');
139 my $pu2 = Crypt::PK::DH->new;
140 $pu2->import_key_raw(pack('H*','774A01FF19C1603040DFBB5C8A44F11CE8719F757C2AF6B2921EDDDEF27F77D5F2DAF9539BCBCB30F80D76E054C489C9E6533051767E6220539C871F23D3B6F80D84037A6FBAB3AE6AF8F214A60A816D6F0F6C3F31801DCD6EA771F41A2A5618BC333D650F46F22FEA81A94F4E00CD05B83F8FE257A2607E62519D9BF8B8C96D0587FB2BCEC8D18DDCF66EBBB8A56623953531EE27C68C8C37E6413FD2C98339F491A0472E5D4DFADC7BF30E89A2CE2081EE3CF9F9B0FFCD902A3021CAC14A4AD7E00F6202C8A9AB93BF96E33838FB9178DC8A8F995ABD81F28F5A137A78E813ABD185498A3A50CB3021CF58BE9D0200C19928AA097D306ABAD9874E0F217482'),'public','ike2048');
141
53142 my $ss1 = $pr1->shared_secret($pu2);
54143 my $ss2 = $pr2->shared_secret($pu1);
55144 is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret');
62151 ok($k->is_private, 'is_private');
63152 ok($k->export_key('private'), 'export_key_pem pri');
64153 ok($k->export_key('public'), 'export_key_pem pub');
154 }
155
156 {
157 my $k = Crypt::PK::DH->new;
158 $k->generate_key({g => 2, p => 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'});
159 ok($k, 'generate_key');
160 ok($k->is_private, 'is_private');
161 ok($k->export_key('private'), 'export_key_pem pri gp');
162 ok($k->export_key('public'), 'export_key_pem pub gp');
163 }
164
165 {
166 my $k = Crypt::PK::DH->new;
167 $k->generate_key('ike2048');
168 ok($k, 'generate_key');
169 ok($k->is_private, 'is_private');
170 ok($k->export_key('private'), 'export_key_pem pri ike2048');
171 ok($k->export_key('public'), 'export_key_pem pub ike2048');
65172 }
66173
67174 {
81188 my $ss2 = dh_shared_secret('t/data/cryptx_priv_dh2.bin', 't/data/cryptx_pub_dh1.bin');
82189 is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret');
83190 }
191
192 {
193 my $ct = dh_encrypt('t/data/cryptx_pub_dh_pg1.bin', 'test string');
194 ok($ct, 'dh_encrypt');
195 my $pt = dh_decrypt('t/data/cryptx_priv_dh_pg1.bin', $ct);
196 ok($pt, 'dh_decrypt');
197 my $sig = dh_sign_message('t/data/cryptx_priv_dh_pg1.bin', 'test string');
198 ok($sig, 'dh_sign_message');
199 ok(dh_verify_message('t/data/cryptx_pub_dh_pg1.bin', $sig, 'test string'), 'dh_verify_message');
200 my $hash = pack("H*","04624fae618e9ad0c5e479f62e1420c71fff34dd");
201 $sig = dh_sign_hash('t/data/cryptx_priv_dh_pg1.bin', $hash, 'SHA1');
202 ok($sig, 'dh_sign_hash');
203 ok(dh_verify_hash('t/data/cryptx_pub_dh_pg1.bin', $sig, $hash, 'SHA1'), 'dh_verify_hash');
204
205 my $ss1 = dh_shared_secret('t/data/cryptx_priv_dh_pg1.bin', 't/data/cryptx_pub_dh_pg2.bin');
206 my $ss2 = dh_shared_secret('t/data/cryptx_priv_dh_pg2.bin', 't/data/cryptx_pub_dh_pg1.bin');
207 is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret');
208 }