comparison libtomcrypt/src/pk/dsa/dsa_make_key.c @ 382:0cbe8f6dbf9e

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f) to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 02:41:05 +0000
parents 1b9e69c058d2
children f849a5ca2efc
comparison
equal deleted inserted replaced
379:b66a00272a90 382:0cbe8f6dbf9e
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org 9 * Tom St Denis, [email protected], http://libtomcrypt.com
10 */ 10 */
11 #include "tomcrypt.h" 11 #include "tomcrypt.h"
12 12
13 /** 13 /**
14 @file dsa_make_key.c 14 @file dsa_make_key.c
26 @param key [out] Where to store the created key 26 @param key [out] Where to store the created key
27 @return CRYPT_OK if successful, upon error this function will free all allocated memory 27 @return CRYPT_OK if successful, upon error this function will free all allocated memory
28 */ 28 */
29 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) 29 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
30 { 30 {
31 mp_int tmp, tmp2; 31 void *tmp, *tmp2;
32 int err, res; 32 int err, res;
33 unsigned char *buf; 33 unsigned char *buf;
34 34
35 LTC_ARGCHK(key != NULL); 35 LTC_ARGCHK(key != NULL);
36 LTC_ARGCHK(ltc_mp.name != NULL);
36 37
37 /* check prng */ 38 /* check prng */
38 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { 39 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
39 return err; 40 return err;
40 } 41 }
50 if (buf == NULL) { 51 if (buf == NULL) {
51 return CRYPT_MEM; 52 return CRYPT_MEM;
52 } 53 }
53 54
54 /* init mp_ints */ 55 /* init mp_ints */
55 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != MP_OKAY) { 56 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
56 err = mpi_to_ltc_error(err); 57 XFREE(buf);
57 goto LBL_ERR; 58 return err;
58 } 59 }
59 60
60 /* make our prime q */ 61 /* make our prime q */
61 if ((err = rand_prime(&key->q, group_size*8, prng, wprng)) != CRYPT_OK) { goto LBL_ERR; } 62 if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; }
62 63
63 /* double q */ 64 /* double q */
64 if ((err = mp_mul_2(&key->q, &tmp)) != MP_OKAY) { goto error; } 65 if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; }
65 66
66 /* now make a random string and multply it against q */ 67 /* now make a random string and multply it against q */
67 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { 68 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
68 err = CRYPT_ERROR_READPRNG; 69 err = CRYPT_ERROR_READPRNG;
69 goto LBL_ERR; 70 goto error;
70 } 71 }
71 72
72 /* force magnitude */ 73 /* force magnitude */
73 buf[0] |= 0xC0; 74 buf[0] |= 0xC0;
74 75
75 /* force even */ 76 /* force even */
76 buf[modulus_size - group_size - 1] &= ~1; 77 buf[modulus_size - group_size - 1] &= ~1;
77 78
78 if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size)) != MP_OKAY) { goto error; } 79 if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; }
79 if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY) { goto error; } 80 if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; }
80 if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY) { goto error; } 81 if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; }
81 82
82 /* now loop until p is prime */ 83 /* now loop until p is prime */
83 for (;;) { 84 for (;;) {
84 if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { goto LBL_ERR; } 85 if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { goto error; }
85 if (res == MP_YES) break; 86 if (res == LTC_MP_YES) break;
86 87
87 /* add 2q to p and 2 to tmp2 */ 88 /* add 2q to p and 2 to tmp2 */
88 if ((err = mp_add(&tmp, &key->p, &key->p)) != MP_OKAY) { goto error; } 89 if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; }
89 if ((err = mp_add_d(&tmp2, 2, &tmp2)) != MP_OKAY) { goto error; } 90 if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; }
90 } 91 }
91 92
92 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ 93 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
93 mp_set(&key->g, 1); 94 mp_set(key->g, 1);
94 95
95 do { 96 do {
96 if ((err = mp_add_d(&key->g, 1, &key->g)) != MP_OKAY) { goto error; } 97 if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; }
97 if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != MP_OKAY) { goto error; } 98 if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; }
98 } while (mp_cmp_d(&tmp, 1) == MP_EQ); 99 } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ);
99 100
100 /* at this point tmp generates a group of order q mod p */ 101 /* at this point tmp generates a group of order q mod p */
101 mp_exch(&tmp, &key->g); 102 mp_exch(tmp, key->g);
102 103
103 /* so now we have our DH structure, generator g, order q, modulus p 104 /* so now we have our DH structure, generator g, order q, modulus p
104 Now we need a random exponent [mod q] and it's power g^x mod p 105 Now we need a random exponent [mod q] and it's power g^x mod p
105 */ 106 */
106 do { 107 do {
107 if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { 108 if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) {
108 err = CRYPT_ERROR_READPRNG; 109 err = CRYPT_ERROR_READPRNG;
109 goto LBL_ERR; 110 goto error;
110 } 111 }
111 if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY) { goto error; } 112 if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { goto error; }
112 } while (mp_cmp_d(&key->x, 1) != MP_GT); 113 } while (mp_cmp_d(key->x, 1) != LTC_MP_GT);
113 if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY) { goto error; } 114 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; }
114 115
115 key->type = PK_PRIVATE; 116 key->type = PK_PRIVATE;
116 key->qord = group_size; 117 key->qord = group_size;
117
118 /* shrink the ram required */
119 if ((err = mp_shrink(&key->g)) != MP_OKAY) { goto error; }
120 if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error; }
121 if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error; }
122 if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; }
123 if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; }
124 118
125 #ifdef LTC_CLEAN_STACK 119 #ifdef LTC_CLEAN_STACK
126 zeromem(buf, MDSA_DELTA); 120 zeromem(buf, MDSA_DELTA);
127 #endif 121 #endif
128 122
129 err = CRYPT_OK; 123 err = CRYPT_OK;
130 goto done; 124 goto done;
131 error: 125 error:
132 err = mpi_to_ltc_error(err); 126 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
133 LBL_ERR:
134 mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL);
135 done: 127 done:
136 mp_clear_multi(&tmp, &tmp2, NULL); 128 mp_clear_multi(tmp, tmp2, NULL);
137
138 XFREE(buf); 129 XFREE(buf);
139 return err; 130 return err;
140 } 131 }
141 132
142 #endif 133 #endif
143 134
144 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */ 135 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */
145 /* $Revision: 1.4 $ */ 136 /* $Revision: 1.10 $ */
146 /* $Date: 2005/06/11 05:45:35 $ */ 137 /* $Date: 2006/12/04 03:18:43 $ */