Codebase list libcryptx-perl / c55db11
LTC sync DSA new style Karel Miko 6 years ago
14 changed file(s) with 535 addition(s) and 333 deletion(s). Raw diff Collapse all Expand all
4646 PPCODE:
4747 {
4848 int rv;
49 unsigned char pbin[512], qbin[512], gbin[512], xbin[512], ybin[512];
50 unsigned long plen=sizeof(pbin), qlen=sizeof(qbin), glen=sizeof(gbin), xlen=sizeof(xbin), ylen=sizeof(ybin);
51
4952 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
50 rv = dsa_import_radix(16, p, q, g, x, y, &self->key);
51 if (rv != CRYPT_OK) croak("FATAL: dsa_import_radix failed: %s", error_to_string(rv));
53
54 if (p && strlen(p) > 0 && q && strlen(q) > 0 && g && strlen(g) > 0 && y && strlen(y) > 0) {
55 rv = radix_to_bin(p, 16, pbin, &plen);
56 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(p) failed: %s", error_to_string(rv));
57 rv = radix_to_bin(q, 16, qbin, &qlen);
58 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(q) failed: %s", error_to_string(rv));
59 rv = radix_to_bin(g, 16, gbin, &glen);
60 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(g) failed: %s", error_to_string(rv));
61 rv = dsa_set_pqg(pbin, plen, qbin, qlen, gbin, glen, &self->key);
62 if (rv != CRYPT_OK) croak("FATAL: dsa_set_pqg failed: %s", error_to_string(rv));
63
64 rv = radix_to_bin(y, 16, ybin, &ylen);
65 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(y) failed: %s", error_to_string(rv));
66 if (x && strlen(x) > 0) {
67 /* private */
68 rv = radix_to_bin(x, 16, xbin, &xlen);
69 if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(x) failed: %s", error_to_string(rv));
70 rv = dsa_set_key(ybin, ylen, xbin, xlen, &self->key);
71 if (rv != CRYPT_OK) croak("FATAL: dsa_set_key failed: %s", error_to_string(rv));
72 }
73 else {
74 /* public */
75 rv = dsa_set_key(ybin, ylen, NULL, 0, &self->key);
76 if (rv != CRYPT_OK) croak("FATAL: dsa_set_key failed: %s", error_to_string(rv));
77 }
78 }
79
5280 XPUSHs(ST(0)); /* return self */
5381 }
5482
6161 _import_hex(Crypt::PK::RSA self, char *N, char *e, char *d=NULL, char *p=NULL, char *q=NULL, char *dP=NULL, char *dQ=NULL, char *qP=NULL)
6262 PPCODE:
6363 {
64 int i, rv;
64 int rv;
6565 unsigned char Nbin[1024], ebin[128], dbin[1024], pbin[512], qbin[512], dPbin[512], dQbin[512], qPbin[512];
6666 unsigned long Nlen=sizeof(Nbin), elen=sizeof(ebin), dlen=sizeof(dbin), plen=sizeof(pbin),
6767 qlen=sizeof(qbin), dPlen=sizeof(dPbin), dQlen=sizeof(dQbin), qPlen=sizeof(qPbin);
8484 ltc/pk/asn1/der/utctime/der_length_utctime.o ltc/pk/asn1/der/utf8/der_decode_utf8_string.o \
8585 ltc/pk/asn1/der/utf8/der_encode_utf8_string.o ltc/pk/asn1/der/utf8/der_length_utf8_string.o \
8686 ltc/pk/dh/dh.o ltc/pk/dh/dh_static.o ltc/pk/dh/dh_sys.o ltc/pk/dsa/dsa_decrypt_key.o \
87 ltc/pk/dsa/dsa_encrypt_key.o ltc/pk/dsa/dsa_export.o ltc/pk/dsa/dsa_free.o ltc/pk/dsa/dsa_import.o \
88 ltc/pk/dsa/dsa_import_radix.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_shared_secret.o \
89 ltc/pk/dsa/dsa_sign_hash.o ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o \
90 ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o ltc/pk/ecc/ecc_ansi_x963_import.o \
91 ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_dp_clear.o ltc/pk/ecc/ecc_dp_fill_from_sets.o \
92 ltc/pk/ecc/ecc_dp_from_oid.o ltc/pk/ecc/ecc_dp_from_params.o ltc/pk/ecc/ecc_dp_init.o \
93 ltc/pk/ecc/ecc_dp_set.o ltc/pk/ecc/ecc_encrypt_key.o ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_full.o \
94 ltc/pk/ecc/ecc_export_raw.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o \
95 ltc/pk/ecc/ecc_import_full.o ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_raw.o \
96 ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_shared_secret.o ltc/pk/ecc/ecc_sign_hash.o \
97 ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ecc_verify_key.o ltc/pk/ecc/ltc_ecc_export_point.o \
98 ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point.o ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o \
99 ltc/pk/ecc/ltc_ecc_is_valid_idx.o ltc/pk/ecc/ltc_ecc_map.o ltc/pk/ecc/ltc_ecc_mul2add.o \
100 ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o ltc/pk/ecc/ltc_ecc_points.o \
101 ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \
87 ltc/pk/dsa/dsa_encrypt_key.o ltc/pk/dsa/dsa_export.o ltc/pk/dsa/dsa_free.o ltc/pk/dsa/dsa_generate_key.o \
88 ltc/pk/dsa/dsa_generate_pqg.o ltc/pk/dsa/dsa_import.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_set.o \
89 ltc/pk/dsa/dsa_set_pqg_dsaparam.o ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o \
90 ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o \
91 ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_dp_clear.o \
92 ltc/pk/ecc/ecc_dp_fill_from_sets.o ltc/pk/ecc/ecc_dp_from_oid.o ltc/pk/ecc/ecc_dp_from_params.o \
93 ltc/pk/ecc/ecc_dp_init.o ltc/pk/ecc/ecc_dp_set.o ltc/pk/ecc/ecc_encrypt_key.o ltc/pk/ecc/ecc_export.o \
94 ltc/pk/ecc/ecc_export_full.o ltc/pk/ecc/ecc_export_raw.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_size.o \
95 ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_full.o ltc/pk/ecc/ecc_import_pkcs8.o \
96 ltc/pk/ecc/ecc_import_raw.o ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_shared_secret.o \
97 ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ecc_verify_key.o \
98 ltc/pk/ecc/ltc_ecc_export_point.o ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point.o \
99 ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o ltc/pk/ecc/ltc_ecc_is_valid_idx.o ltc/pk/ecc/ltc_ecc_map.o \
100 ltc/pk/ecc/ltc_ecc_mul2add.o ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o \
101 ltc/pk/ecc/ltc_ecc_points.o ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \
102102 ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o ltc/pk/pkcs1/pkcs_1_oaep_decode.o \
103103 ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o ltc/pk/pkcs1/pkcs_1_pss_decode.o \
104104 ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o ltc/pk/pkcs1/pkcs_1_v1_5_encode.o \
9191 ltc/pk/asn1/der/utf8/der_encode_utf8_string.obj ltc/pk/asn1/der/utf8/der_length_utf8_string.obj \
9292 ltc/pk/dh/dh.obj ltc/pk/dh/dh_static.obj ltc/pk/dh/dh_sys.obj ltc/pk/dsa/dsa_decrypt_key.obj \
9393 ltc/pk/dsa/dsa_encrypt_key.obj ltc/pk/dsa/dsa_export.obj ltc/pk/dsa/dsa_free.obj \
94 ltc/pk/dsa/dsa_import.obj ltc/pk/dsa/dsa_import_radix.obj ltc/pk/dsa/dsa_make_key.obj \
94 ltc/pk/dsa/dsa_generate_key.obj ltc/pk/dsa/dsa_generate_pqg.obj ltc/pk/dsa/dsa_import.obj \
95 ltc/pk/dsa/dsa_make_key.obj ltc/pk/dsa/dsa_set.obj ltc/pk/dsa/dsa_set_pqg_dsaparam.obj \
9596 ltc/pk/dsa/dsa_shared_secret.obj ltc/pk/dsa/dsa_sign_hash.obj ltc/pk/dsa/dsa_verify_hash.obj \
9697 ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \
9798 ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_dp_clear.obj \
471471
472472 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
473473
474 int dsa_make_key_ex(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key, char* p_hex, char* q_hex, char* g_hex);
475
476 int dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g);
474 int dsa_set_pqg(const unsigned char *p, unsigned long plen,
475 const unsigned char *q, unsigned long qlen,
476 const unsigned char *g, unsigned long glen,
477 dsa_key *key);
478 int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamlen, dsa_key *key);
479 int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
480
481 int dsa_set_key(const unsigned char *pub, unsigned long publen,
482 const unsigned char *priv, unsigned long privlen,
483 dsa_key *key);
484 int dsa_generate_key(prng_state *prng, int wprng, dsa_key *key);
477485
478486 void dsa_free(dsa_key *key);
479487
502510 unsigned char *out, unsigned long *outlen,
503511 dsa_key *key);
504512
505 int dsa_import_radix(int radix, char *p, char *q, char *g, char *x, char *y, dsa_key *key);
506513 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
507514 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
508515 int dsa_verify_key(dsa_key *key, int *stat);
3434 unsigned char *expt, *skey;
3535 void *g_pub, *g_priv;
3636 unsigned long x, y;
37 int err, qbits;
37 int err;
3838
3939 LTC_ARGCHK(in != NULL);
4040 LTC_ARGCHK(out != NULL);
7272 return CRYPT_MEM;
7373 }
7474
75 /* make a random g_priv, g_pub = g^x pair */
76 qbits = mp_count_bits(key->q);
77 do {
78 if ((err = rand_bn_bits(g_priv, qbits, prng, wprng)) != CRYPT_OK) {
79 goto LBL_ERR;
80 }
81 /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
82 } while (mp_cmp_d(g_priv, 0) != LTC_MP_GT || mp_cmp(g_priv, key->q) != LTC_MP_LT);
75 /* make a random g_priv, g_pub = g^x pair
76 private key x should be in range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2)
77 */
78 if ((err = rand_bn_upto(g_priv, key->q, prng, wprng)) != CRYPT_OK) {
79 goto LBL_ERR;
80 }
8381
8482 /* compute y */
8583 if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
2121 void dsa_free(dsa_key *key)
2222 {
2323 LTC_ARGCHKVD(key != NULL);
24 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
24 mp_cleanup_multi(&key->y, &key->x, &key->q, &key->g, &key->p, NULL);
25 key->type = key->qord = 0;
2526 }
2627
2728 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10 /**
11 @file dsa_make_key.c
12 DSA implementation, generate a DSA key
13 */
14
15 #ifdef LTC_MDSA
16
17 /**
18 Create a DSA key
19 @param prng An active PRNG state
20 @param wprng The index of the PRNG desired
21 @param key [in/out] Where to store the created key
22 @return CRYPT_OK if successful.
23 */
24 int dsa_generate_key(prng_state *prng, int wprng, dsa_key *key)
25 {
26 int err;
27
28 LTC_ARGCHK(key != NULL);
29 LTC_ARGCHK(ltc_mp.name != NULL);
30
31 /* so now we have our DH structure, generator g, order q, modulus p
32 Now we need a random exponent [mod q] and it's power g^x mod p
33 */
34 /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
35 if ((err = rand_bn_upto(key->x, key->q, prng, wprng)) != CRYPT_OK) { return err; }
36 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { return err; }
37 key->type = PK_PRIVATE;
38
39 return CRYPT_OK;
40 }
41
42 #endif
43
44 /* ref: $Format:%D$ */
45 /* git commit: $Format:%H$ */
46 /* commit time: $Format:%ai$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10 /**
11 @file dsa_generate_pqg.c
12 DSA implementation - generate DSA parameters p, q & g
13 */
14
15 #ifdef LTC_MDSA
16
17 /**
18 Create DSA parameters (INTERNAL ONLY, not part of public API)
19 @param prng An active PRNG state
20 @param wprng The index of the PRNG desired
21 @param group_size Size of the multiplicative group (octets)
22 @param modulus_size Size of the modulus (octets)
23 @param p [out] bignum where generated 'p' is stored (must be initialized by caller)
24 @param q [out] bignum where generated 'q' is stored (must be initialized by caller)
25 @param g [out] bignum where generated 'g' is stored (must be initialized by caller)
26 @return CRYPT_OK if successful, upon error this function will free all allocated memory
27 */
28 static int _dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g)
29 {
30 unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
31 int err, res, mr_tests_q, mr_tests_p, found_p, found_q, hash;
32 unsigned char *wbuf, *sbuf, digest[MAXBLOCKSIZE];
33 void *t2L1, *t2N1, *t2q, *t2seedlen, *U, *W, *X, *c, *h, *e, *seedinc;
34
35 /* check size */
36 if (group_size >= LTC_MDSA_MAX_GROUP || group_size < 1 || group_size >= modulus_size) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 /* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
41 *
42 * L = The desired length of the prime p (in bits e.g. L = 1024)
43 * N = The desired length of the prime q (in bits e.g. N = 160)
44 * seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
45 * outlen = The bit length of Hash function
46 *
47 * 1. Check that the (L, N)
48 * 2. If (seedlen <N), then return INVALID.
49 * 3. n = ceil(L / outlen) - 1
50 * 4. b = L- 1 - (n * outlen)
51 * 5. domain_parameter_seed = an arbitrary sequence of seedlen bits
52 * 6. U = Hash (domain_parameter_seed) mod 2^(N-1)
53 * 7. q = 2^(N-1) + U + 1 - (U mod 2)
54 * 8. Test whether or not q is prime as specified in Appendix C.3
55 * 9. If qis not a prime, then go to step 5.
56 * 10. offset = 1
57 * 11. For counter = 0 to (4L- 1) do {
58 * For j=0 to n do {
59 * Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
60 * }
61 * W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
62 * X = W + 2^(L-1) Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
63 * c = X mod 2*q
64 * p = X - (c - 1) Comment: p ~ 1 (mod 2*q)
65 * If (p >= 2^(L-1)) {
66 * Test whether or not p is prime as specified in Appendix C.3.
67 * 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
68 * }
69 * offset = offset + n + 1 Comment: Increment offset
70 * }
71 */
72
73 seedbytes = group_size;
74 L = modulus_size * 8;
75 N = group_size * 8;
76
77 /* XXX-TODO no Lucas test */
78 #ifdef LTC_MPI_HAS_LUCAS_TEST
79 /* M-R tests (when followed by one Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
80 mr_tests_p = (L <= 2048) ? 3 : 2;
81 if (N <= 160) { mr_tests_q = 19; }
82 else if (N <= 224) { mr_tests_q = 24; }
83 else { mr_tests_q = 27; }
84 #else
85 /* M-R tests (without Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
86 if (L <= 1024) { mr_tests_p = 40; }
87 else if (L <= 2048) { mr_tests_p = 56; }
88 else { mr_tests_p = 64; }
89
90 if (N <= 160) { mr_tests_q = 40; }
91 else if (N <= 224) { mr_tests_q = 56; }
92 else { mr_tests_q = 64; }
93 #endif
94
95 if (N <= 256) {
96 hash = register_hash(&sha256_desc);
97 }
98 else if (N <= 384) {
99 hash = register_hash(&sha384_desc);
100 }
101 else if (N <= 512) {
102 hash = register_hash(&sha512_desc);
103 }
104 else {
105 return CRYPT_INVALID_ARG; /* group_size too big */
106 }
107
108 if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; }
109 outbytes = hash_descriptor[hash].hashsize;
110
111 n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;
112
113 if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL) { err = CRYPT_MEM; goto cleanup3; }
114 if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; }
115
116 err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL);
117 if (err != CRYPT_OK) { goto cleanup1; }
118
119 if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; }
120 /* t2L1 = 2^(L-1) */
121 if ((err = mp_2expt(t2N1, N-1)) != CRYPT_OK) { goto cleanup; }
122 /* t2N1 = 2^(N-1) */
123 if ((err = mp_2expt(t2seedlen, seedbytes*8)) != CRYPT_OK) { goto cleanup; }
124 /* t2seedlen = 2^seedlen */
125
126 for(found_p=0; !found_p;) {
127 /* q */
128 for(found_q=0; !found_q;) {
129 if (prng_descriptor[wprng].read(sbuf, seedbytes, prng) != seedbytes) { err = CRYPT_ERROR_READPRNG; goto cleanup; }
130 i = outbytes;
131 if ((err = hash_memory(hash, sbuf, seedbytes, digest, &i)) != CRYPT_OK) { goto cleanup; }
132 if ((err = mp_read_unsigned_bin(U, digest, outbytes)) != CRYPT_OK) { goto cleanup; }
133 if ((err = mp_mod(U, t2N1, U)) != CRYPT_OK) { goto cleanup; }
134 if ((err = mp_add(t2N1, U, q)) != CRYPT_OK) { goto cleanup; }
135 if (!mp_isodd(q)) mp_add_d(q, 1, q);
136 if ((err = mp_prime_is_prime(q, mr_tests_q, &res)) != CRYPT_OK) { goto cleanup; }
137 if (res == LTC_MP_YES) found_q = 1;
138 }
139
140 /* p */
141 if ((err = mp_read_unsigned_bin(seedinc, sbuf, seedbytes)) != CRYPT_OK) { goto cleanup; }
142 if ((err = mp_add(q, q, t2q)) != CRYPT_OK) { goto cleanup; }
143 for(counter=0; counter < 4*L && !found_p; counter++) {
144 for(j=0; j<=n; j++) {
145 if ((err = mp_add_d(seedinc, 1, seedinc)) != CRYPT_OK) { goto cleanup; }
146 if ((err = mp_mod(seedinc, t2seedlen, seedinc)) != CRYPT_OK) { goto cleanup; }
147 /* seedinc = (seedinc+1) % 2^seed_bitlen */
148 if ((i = mp_unsigned_bin_size(seedinc)) > seedbytes) { err = CRYPT_INVALID_ARG; goto cleanup; }
149 zeromem(sbuf, seedbytes);
150 if ((err = mp_to_unsigned_bin(seedinc, sbuf + seedbytes-i)) != CRYPT_OK) { goto cleanup; }
151 i = outbytes;
152 err = hash_memory(hash, sbuf, seedbytes, wbuf+(n-j)*outbytes, &i);
153 if (err != CRYPT_OK) { goto cleanup; }
154 }
155 if ((err = mp_read_unsigned_bin(W, wbuf, (n+1)*outbytes)) != CRYPT_OK) { goto cleanup; }
156 if ((err = mp_mod(W, t2L1, W)) != CRYPT_OK) { goto cleanup; }
157 if ((err = mp_add(W, t2L1, X)) != CRYPT_OK) { goto cleanup; }
158 if ((err = mp_mod(X, t2q, c)) != CRYPT_OK) { goto cleanup; }
159 if ((err = mp_sub_d(c, 1, p)) != CRYPT_OK) { goto cleanup; }
160 if ((err = mp_sub(X, p, p)) != CRYPT_OK) { goto cleanup; }
161 if (mp_cmp(p, t2L1) != LTC_MP_LT) {
162 /* p >= 2^(L-1) */
163 if ((err = mp_prime_is_prime(p, mr_tests_p, &res)) != CRYPT_OK) { goto cleanup; }
164 if (res == LTC_MP_YES) {
165 found_p = 1;
166 }
167 }
168 }
169 }
170
171 /* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
172 * 1. e = (p - 1)/q
173 * 2. h = any integer satisfying: 1 < h < (p - 1)
174 * h could be obtained from a random number generator or from a counter that changes after each use
175 * 3. g = h^e mod p
176 * 4. if (g == 1), then go to step 2.
177 *
178 */
179
180 if ((err = mp_sub_d(p, 1, e)) != CRYPT_OK) { goto cleanup; }
181 if ((err = mp_div(e, q, e, c)) != CRYPT_OK) { goto cleanup; }
182 /* e = (p - 1)/q */
183 i = mp_count_bits(p);
184 do {
185 do {
186 if ((err = rand_bn_bits(h, i, prng, wprng)) != CRYPT_OK) { goto cleanup; }
187 } while (mp_cmp(h, p) != LTC_MP_LT || mp_cmp_d(h, 2) != LTC_MP_GT);
188 if ((err = mp_sub_d(h, 1, h)) != CRYPT_OK) { goto cleanup; }
189 /* h is randon and 1 < h < (p-1) */
190 if ((err = mp_exptmod(h, e, p, g)) != CRYPT_OK) { goto cleanup; }
191 } while (mp_cmp_d(g, 1) == LTC_MP_EQ);
192
193 err = CRYPT_OK;
194 cleanup:
195 mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL);
196 cleanup1:
197 XFREE(sbuf);
198 cleanup2:
199 XFREE(wbuf);
200 cleanup3:
201 return err;
202 }
203
204 /**
205 Generate DSA parameters p, q & g
206 @param prng An active PRNG state
207 @param wprng The index of the PRNG desired
208 @param group_size Size of the multiplicative group (octets)
209 @param modulus_size Size of the modulus (octets)
210 @param key [out] Where to store the created key
211 @return CRYPT_OK if successful.
212 */
213 int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
214 {
215 int err;
216
217 LTC_ARGCHK(key != NULL);
218 LTC_ARGCHK(ltc_mp.name != NULL);
219
220 /* init mp_ints */
221 if ((err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL)) != CRYPT_OK) {
222 return err;
223 }
224 /* generate params */
225 err = _dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
226 if (err != CRYPT_OK) {
227 goto cleanup;
228 }
229
230 key->qord = group_size;
231
232 return CRYPT_OK;
233
234 cleanup:
235 dsa_free(key);
236 return err;
237 }
238
239 #endif
240
241 /* ref: $Format:%D$ */
242 /* git commit: $Format:%H$ */
243 /* commit time: $Format:%ai$ */
124124
125125 return CRYPT_OK;
126126 LBL_ERR:
127 mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL);
127 dsa_free(key);
128128 return err;
129129 }
130130
+0
-65
src/ltc/pk/dsa/dsa_import_radix.c less more
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10 /**
11 Import DSA public or private key from raw numbers
12 @param radix the radix the numbers are represented in (2-64, 16 = hexadecimal)
13 @param p DSA's p in radix representation
14 @param q DSA's q in radix representation
15 @param g DSA's g in radix representation
16 @param x DSA's x in radix representation (only private key, NULL for public key)
17 @param y DSA's y in radix representation
18 @param key [out] the destination for the imported key
19 @return CRYPT_OK if successful, upon error allocated memory is freed
20 */
21
22 #ifdef LTC_MDSA
23
24 int dsa_import_radix(int radix, char *p, char *q, char *g, char *x, char *y, dsa_key *key)
25 {
26 int err;
27
28 LTC_ARGCHK(p != NULL);
29 LTC_ARGCHK(q != NULL);
30 LTC_ARGCHK(g != NULL);
31 LTC_ARGCHK(y != NULL);
32 LTC_ARGCHK(ltc_mp.name != NULL);
33
34 /* init key */
35 err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
36 if (err != CRYPT_OK) return err;
37
38 if ((err = mp_read_radix(key->p , p , radix)) != CRYPT_OK) { goto LBL_ERR; }
39 if ((err = mp_read_radix(key->q , q , radix)) != CRYPT_OK) { goto LBL_ERR; }
40 if ((err = mp_read_radix(key->g , g , radix)) != CRYPT_OK) { goto LBL_ERR; }
41 if ((err = mp_read_radix(key->y , y , radix)) != CRYPT_OK) { goto LBL_ERR; }
42 if (x && strlen(x) > 0) {
43 key->type = PK_PRIVATE;
44 if ((err = mp_read_radix(key->x , x , radix)) != CRYPT_OK) { goto LBL_ERR; }
45 }
46 else {
47 key->type = PK_PUBLIC;
48 }
49
50 key->qord = mp_unsigned_bin_size(key->q);
51
52 if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
53 (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) {
54 err = CRYPT_INVALID_PACKET;
55 goto LBL_ERR;
56 }
57 return CRYPT_OK;
58
59 LBL_ERR:
60 mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL);
61 return err;
62 }
63
64 #endif
99
1010 /**
1111 @file dsa_make_key.c
12 DSA implementation, generate a DSA key, Tom St Denis
12 DSA implementation, generate a DSA key
1313 */
1414
1515 #ifdef LTC_MDSA
1616
1717 /**
18 Create DSA parameters
19 @param prng An active PRNG state
20 @param wprng The index of the PRNG desired
21 @param group_size Size of the multiplicative group (octets)
22 @param modulus_size Size of the modulus (octets)
23 @param p [out] bignum where generated 'p' is stored (must be initialized by caller)
24 @param q [out] bignum where generated 'q' is stored (must be initialized by caller)
25 @param g [out] bignum where generated 'g' is stored (must be initialized by caller)
26 @return CRYPT_OK if successful, upon error this function will free all allocated memory
27 */
28 int dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g)
29 {
30 unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
31 int err, res, mr_tests_q, mr_tests_p, found_p, found_q, hash;
32 unsigned char *wbuf, *sbuf, digest[MAXBLOCKSIZE];
33 void *t2L1, *t2N1, *t2q, *t2seedlen, *U, *W, *X, *c, *h, *e, *seedinc;
34
35 /* check size */
36 if (group_size >= LTC_MDSA_MAX_GROUP || group_size < 1 || group_size >= modulus_size) {
37 return CRYPT_INVALID_ARG;
38 }
39
40 /* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
41 *
42 * L = The desired length of the prime p (in bits e.g. L = 1024)
43 * N = The desired length of the prime q (in bits e.g. N = 160)
44 * seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
45 * outlen = The bit length of Hash function
46 *
47 * 1. Check that the (L, N)
48 * 2. If (seedlen <N), then return INVALID.
49 * 3. n = ceil(L / outlen) - 1
50 * 4. b = L- 1 - (n * outlen)
51 * 5. domain_parameter_seed = an arbitrary sequence of seedlen bits
52 * 6. U = Hash (domain_parameter_seed) mod 2^(N-1)
53 * 7. q = 2^(N-1) + U + 1 - (U mod 2)
54 * 8. Test whether or not q is prime as specified in Appendix C.3
55 * 9. If qis not a prime, then go to step 5.
56 * 10. offset = 1
57 * 11. For counter = 0 to (4L- 1) do {
58 * For j=0 to n do {
59 * Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
60 * }
61 * W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
62 * X = W + 2^(L-1) Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
63 * c = X mod 2*q
64 * p = X - (c - 1) Comment: p ~ 1 (mod 2*q)
65 * If (p >= 2^(L-1)) {
66 * Test whether or not p is prime as specified in Appendix C.3.
67 * 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
68 * }
69 * offset = offset + n + 1 Comment: Increment offset
70 * }
71 */
72
73 seedbytes = group_size;
74 L = modulus_size * 8;
75 N = group_size * 8;
76
77 /* M-R tests (when followed by one Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
78 mr_tests_p = (L <= 2048) ? 3 : 2;
79 if (N <= 160) { mr_tests_q = 19; }
80 else if (N <= 224) { mr_tests_q = 24; }
81 else { mr_tests_q = 27; }
82
83 if (N <= 256) {
84 hash = register_hash(&sha256_desc);
85 }
86 else if (N <= 384) {
87 hash = register_hash(&sha384_desc);
88 }
89 else if (N <= 512) {
90 hash = register_hash(&sha512_desc);
91 }
92 else {
93 return CRYPT_INVALID_ARG; /* group_size too big */
94 }
95
96 if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; }
97 outbytes = hash_descriptor[hash].hashsize;
98
99 n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;
100
101 if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL) { err = CRYPT_MEM; goto cleanup3; }
102 if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; }
103
104 err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL);
105 if (err != CRYPT_OK) { goto cleanup1; }
106
107 if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; }
108 /* t2L1 = 2^(L-1) */
109 if ((err = mp_2expt(t2N1, N-1)) != CRYPT_OK) { goto cleanup; }
110 /* t2N1 = 2^(N-1) */
111 if ((err = mp_2expt(t2seedlen, seedbytes*8)) != CRYPT_OK) { goto cleanup; }
112 /* t2seedlen = 2^seedlen */
113
114 for(found_p=0; !found_p;) {
115 /* q */
116 for(found_q=0; !found_q;) {
117 if (prng_descriptor[wprng].read(sbuf, seedbytes, prng) != seedbytes) { err = CRYPT_ERROR_READPRNG; goto cleanup; }
118 i = outbytes;
119 if ((err = hash_memory(hash, sbuf, seedbytes, digest, &i)) != CRYPT_OK) { goto cleanup; }
120 if ((err = mp_read_unsigned_bin(U, digest, outbytes)) != CRYPT_OK) { goto cleanup; }
121 if ((err = mp_mod(U, t2N1, U)) != CRYPT_OK) { goto cleanup; }
122 if ((err = mp_add(t2N1, U, q)) != CRYPT_OK) { goto cleanup; }
123 if (!mp_isodd(q)) mp_add_d(q, 1, q);
124 if ((err = mp_prime_is_prime(q, mr_tests_q, &res)) != CRYPT_OK) { goto cleanup; } /* XXX-TODO rounds are ignored; no Lucas test */
125 if (res == LTC_MP_YES) found_q = 1;
126 }
127
128 /* p */
129 if ((err = mp_read_unsigned_bin(seedinc, sbuf, seedbytes)) != CRYPT_OK) { goto cleanup; }
130 if ((err = mp_add(q, q, t2q)) != CRYPT_OK) { goto cleanup; }
131 for(counter=0; counter < 4*L && !found_p; counter++) {
132 for(j=0; j<=n; j++) {
133 if ((err = mp_add_d(seedinc, 1, seedinc)) != CRYPT_OK) { goto cleanup; }
134 if ((err = mp_mod(seedinc, t2seedlen, seedinc)) != CRYPT_OK) { goto cleanup; }
135 /* seedinc = (seedinc+1) % 2^seed_bitlen */
136 if ((i = mp_unsigned_bin_size(seedinc)) > seedbytes) { err = CRYPT_INVALID_ARG; goto cleanup; }
137 zeromem(sbuf, seedbytes);
138 if ((err = mp_to_unsigned_bin(seedinc, sbuf + seedbytes-i)) != CRYPT_OK) { goto cleanup; }
139 i = outbytes;
140 err = hash_memory(hash, sbuf, seedbytes, wbuf+(n-j)*outbytes, &i);
141 if (err != CRYPT_OK) { goto cleanup; }
142 }
143 if ((err = mp_read_unsigned_bin(W, wbuf, (n+1)*outbytes)) != CRYPT_OK) { goto cleanup; }
144 if ((err = mp_mod(W, t2L1, W)) != CRYPT_OK) { goto cleanup; }
145 if ((err = mp_add(W, t2L1, X)) != CRYPT_OK) { goto cleanup; }
146 if ((err = mp_mod(X, t2q, c)) != CRYPT_OK) { goto cleanup; }
147 if ((err = mp_sub_d(c, 1, p)) != CRYPT_OK) { goto cleanup; }
148 if ((err = mp_sub(X, p, p)) != CRYPT_OK) { goto cleanup; }
149 if (mp_cmp(p, t2L1) != LTC_MP_LT) {
150 /* p >= 2^(L-1) */
151 if ((err = mp_prime_is_prime(p, mr_tests_p, &res)) != CRYPT_OK) { goto cleanup; } /* XXX-TODO rounds are ignored; no Lucas test */
152 if (res == LTC_MP_YES) {
153 found_p = 1;
154 }
155 }
156 }
157 }
158
159 /* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
160 * 1. e = (p - 1)/q
161 * 2. h = any integer satisfying: 1 < h < (p - 1)
162 * h could be obtained from a random number generator or from a counter that changes after each use
163 * 3. g = h^e mod p
164 * 4. if (g == 1), then go to step 2.
165 *
166 */
167
168 if ((err = mp_sub_d(p, 1, e)) != CRYPT_OK) { goto cleanup; }
169 if ((err = mp_div(e, q, e, c)) != CRYPT_OK) { goto cleanup; }
170 /* e = (p - 1)/q */
171 i = mp_count_bits(p);
172 do {
173 do {
174 if ((err = rand_bn_bits(h, i, prng, wprng)) != CRYPT_OK) { goto cleanup; }
175 } while (mp_cmp(h, p) != LTC_MP_LT || mp_cmp_d(h, 2) != LTC_MP_GT);
176 if ((err = mp_sub_d(h, 1, h)) != CRYPT_OK) { goto cleanup; }
177 /* h is randon and 1 < h < (p-1) */
178 if ((err = mp_exptmod(h, e, p, g)) != CRYPT_OK) { goto cleanup; }
179 } while (mp_cmp_d(g, 1) == LTC_MP_EQ);
180
181 err = CRYPT_OK;
182 cleanup:
183 mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL);
184 cleanup1:
185 XFREE(sbuf);
186 cleanup2:
187 XFREE(wbuf);
188 cleanup3:
189 return err;
190 }
191
192 /**
193 Create a DSA key (with given params)
18 Old-style creation of a DSA key
19419 @param prng An active PRNG state
19520 @param wprng The index of the PRNG desired
19621 @param group_size Size of the multiplicative group (octets)
19722 @param modulus_size Size of the modulus (octets)
19823 @param key [out] Where to store the created key
199 @param p_hex Hexadecimal string 'p'
200 @param q_hex Hexadecimal string 'q'
201 @param g_hex Hexadecimal string 'g'
202 @return CRYPT_OK if successful, upon error this function will free all allocated memory
203 */
204 int dsa_make_key_ex(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key, char* p_hex, char* q_hex, char* g_hex)
205 {
206 int err, qbits;
207
208 LTC_ARGCHK(key != NULL);
209
210 /* init mp_ints */
211 if ((err = mp_init_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
212 return err;
213 }
214
215 if (p_hex == NULL || q_hex == NULL || g_hex == NULL) {
216 /* generate params */
217 err = dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
218 if (err != CRYPT_OK) { goto cleanup; }
219 }
220 else {
221 /* read params */
222 if ((err = mp_read_radix(key->p, p_hex, 16)) != CRYPT_OK) { goto cleanup; }
223 if ((err = mp_read_radix(key->q, q_hex, 16)) != CRYPT_OK) { goto cleanup; }
224 if ((err = mp_read_radix(key->g, g_hex, 16)) != CRYPT_OK) { goto cleanup; }
225 /* XXX-TODO maybe do some validity check for p, q, g */
226 }
227
228 /* so now we have our DH structure, generator g, order q, modulus p
229 Now we need a random exponent [mod q] and it's power g^x mod p
230 */
231 qbits = mp_count_bits(key->q);
232 do {
233 if ((err = rand_bn_bits(key->x, qbits, prng, wprng)) != CRYPT_OK) { goto cleanup; }
234 /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
235 } while (mp_cmp_d(key->x, 0) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT);
236 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto cleanup; }
237 key->type = PK_PRIVATE;
238 key->qord = group_size;
239
240 return CRYPT_OK;
241
242 cleanup:
243 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
244 return err;
245 }
246
247 /**
248 Create a DSA key
249 @param prng An active PRNG state
250 @param wprng The index of the PRNG desired
251 @param group_size Size of the multiplicative group (octets)
252 @param modulus_size Size of the modulus (octets)
253 @param key [out] Where to store the created key
254 @return CRYPT_OK if successful, upon error this function will free all allocated memory
24 @return CRYPT_OK if successful.
25525 */
25626 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
25727 {
258 return dsa_make_key_ex(prng, wprng, group_size, modulus_size, key, NULL, NULL, NULL);
28 int err;
29
30 if ((err = dsa_generate_pqg(prng, wprng, group_size, modulus_size, key)) != CRYPT_OK) { return err; }
31 if ((err = dsa_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; }
32
33 return CRYPT_OK;
25934 }
26035
26136 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10
11 #ifdef LTC_MDSA
12
13 /**
14 Import DSA's p, q & g from raw numbers
15 @param p DSA's p in binary representation
16 @param plen The length of p
17 @param q DSA's q in binary representation
18 @param qlen The length of q
19 @param g DSA's g in binary representation
20 @param glen The length of g
21 @param key [out] the destination for the imported key
22 @return CRYPT_OK if successful.
23 */
24 int dsa_set_pqg(const unsigned char *p, unsigned long plen,
25 const unsigned char *q, unsigned long qlen,
26 const unsigned char *g, unsigned long glen,
27 dsa_key *key)
28 {
29 int err;
30
31 LTC_ARGCHK(p != NULL);
32 LTC_ARGCHK(q != NULL);
33 LTC_ARGCHK(g != NULL);
34 LTC_ARGCHK(key != NULL);
35 LTC_ARGCHK(ltc_mp.name != NULL);
36
37 /* init key */
38 err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
39 if (err != CRYPT_OK) return err;
40
41 if ((err = mp_read_unsigned_bin(key->p, (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; }
42 if ((err = mp_read_unsigned_bin(key->g, (unsigned char *)g , glen)) != CRYPT_OK) { goto LBL_ERR; }
43 if ((err = mp_read_unsigned_bin(key->q, (unsigned char *)q , qlen)) != CRYPT_OK) { goto LBL_ERR; }
44
45 key->qord = mp_unsigned_bin_size(key->q);
46
47 if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
48 (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) {
49 err = CRYPT_INVALID_PACKET;
50 goto LBL_ERR;
51 }
52 return CRYPT_OK;
53
54 LBL_ERR:
55 dsa_free(key);
56 return err;
57 }
58
59 /**
60 Import DSA public or private key from raw numbers
61 @param pub DSA's y (public key) in binary representation
62 @param publen The length of pub
63 @param priv DSA's x (private key) in binary representation (can be NULL when importing public key)
64 @param privlen The length of priv
65 @param key [out] the destination for the imported key
66 @return CRYPT_OK if successful.
67 */
68 int dsa_set_key(const unsigned char *pub, unsigned long publen,
69 const unsigned char *priv, unsigned long privlen,
70 dsa_key *key)
71 {
72 int err;
73
74 LTC_ARGCHK(key != NULL);
75 LTC_ARGCHK(key->x != NULL);
76 LTC_ARGCHK(key->y != NULL);
77 LTC_ARGCHK(key->p != NULL);
78 LTC_ARGCHK(key->g != NULL);
79 LTC_ARGCHK(key->q != NULL);
80 LTC_ARGCHK(ltc_mp.name != NULL);
81
82 if ((err = mp_read_unsigned_bin(key->y, (unsigned char *)pub , publen)) != CRYPT_OK) { goto LBL_ERR; }
83 if (priv != NULL) {
84 key->type = PK_PRIVATE;
85 if ((err = mp_read_unsigned_bin(key->x, (unsigned char *)priv , privlen)) != CRYPT_OK) { goto LBL_ERR; }
86 }
87 else {
88 key->type = PK_PUBLIC;
89 }
90
91 return CRYPT_OK;
92
93 LBL_ERR:
94 dsa_free(key);
95 return err;
96 }
97
98 #endif
99
100 /* ref: $Format:%D$ */
101 /* git commit: $Format:%H$ */
102 /* commit time: $Format:%ai$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10
11 #ifdef LTC_MDSA
12
13 /**
14 Import DSA's p, q & g from dsaparam
15
16 dsaparam data: openssl dsaparam -outform DER -out dsaparam.der 2048
17
18 @param dsaparam The DSA param DER encoded data
19 @param dsaparamlen The length of dhparam data
20 @param key [out] the destination for the imported key
21 @return CRYPT_OK if successful.
22 */
23 int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamlen,
24 dsa_key *key)
25 {
26 int err;
27
28 LTC_ARGCHK(dsaparam != NULL);
29 LTC_ARGCHK(key != NULL);
30 LTC_ARGCHK(ltc_mp.name != NULL);
31
32 /* init key */
33 err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
34 if (err != CRYPT_OK) return err;
35
36 if ((err = der_decode_sequence_multi(dsaparam, dsaparamlen,
37 LTC_ASN1_INTEGER, 1UL, key->p,
38 LTC_ASN1_INTEGER, 1UL, key->q,
39 LTC_ASN1_INTEGER, 1UL, key->g,
40 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
41 goto LBL_ERR;
42 }
43
44 key->qord = mp_unsigned_bin_size(key->q);
45
46 if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
47 (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) {
48 err = CRYPT_INVALID_PACKET;
49 goto LBL_ERR;
50 }
51 return CRYPT_OK;
52
53 LBL_ERR:
54 dsa_free(key);
55 return err;
56 }
57
58 #endif
59
60 /* ref: $Format:%D$ */
61 /* git commit: $Format:%H$ */
62 /* commit time: $Format:%ai$ */