diff options
Diffstat (limited to 'src/lib/libcrypto/dsa/dsa_gen.c')
-rw-r--r-- | src/lib/libcrypto/dsa/dsa_gen.c | 171 |
1 files changed, 66 insertions, 105 deletions
diff --git a/src/lib/libcrypto/dsa/dsa_gen.c b/src/lib/libcrypto/dsa/dsa_gen.c index b5e5ec06e5..2294a362d9 100644 --- a/src/lib/libcrypto/dsa/dsa_gen.c +++ b/src/lib/libcrypto/dsa/dsa_gen.c | |||
@@ -59,12 +59,18 @@ | |||
59 | #undef GENUINE_DSA | 59 | #undef GENUINE_DSA |
60 | 60 | ||
61 | #ifdef GENUINE_DSA | 61 | #ifdef GENUINE_DSA |
62 | /* Parameter generation follows the original release of FIPS PUB 186, | ||
63 | * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */ | ||
62 | #define HASH SHA | 64 | #define HASH SHA |
63 | #else | 65 | #else |
66 | /* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, | ||
67 | * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in | ||
68 | * FIPS PUB 180-1) */ | ||
64 | #define HASH SHA1 | 69 | #define HASH SHA1 |
65 | #endif | 70 | #endif |
66 | 71 | ||
67 | #ifndef NO_SHA | 72 | #ifndef NO_SHA |
73 | |||
68 | #include <stdio.h> | 74 | #include <stdio.h> |
69 | #include <time.h> | 75 | #include <time.h> |
70 | #include "cryptlib.h" | 76 | #include "cryptlib.h" |
@@ -74,8 +80,9 @@ | |||
74 | #include <openssl/rand.h> | 80 | #include <openssl/rand.h> |
75 | 81 | ||
76 | DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, | 82 | DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, |
77 | int *counter_ret, unsigned long *h_ret, void (*callback)(), | 83 | int *counter_ret, unsigned long *h_ret, |
78 | char *cb_arg) | 84 | void (*callback)(int, int, void *), |
85 | void *cb_arg) | ||
79 | { | 86 | { |
80 | int ok=0; | 87 | int ok=0; |
81 | unsigned char seed[SHA_DIGEST_LENGTH]; | 88 | unsigned char seed[SHA_DIGEST_LENGTH]; |
@@ -86,47 +93,63 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, | |||
86 | BN_MONT_CTX *mont=NULL; | 93 | BN_MONT_CTX *mont=NULL; |
87 | int k,n=0,i,b,m=0; | 94 | int k,n=0,i,b,m=0; |
88 | int counter=0; | 95 | int counter=0; |
89 | BN_CTX *ctx=NULL,*ctx2=NULL; | 96 | int r=0; |
97 | BN_CTX *ctx=NULL,*ctx2=NULL,*ctx3=NULL; | ||
90 | unsigned int h=2; | 98 | unsigned int h=2; |
91 | DSA *ret=NULL; | 99 | DSA *ret=NULL; |
92 | 100 | ||
93 | if (bits < 512) bits=512; | 101 | if (bits < 512) bits=512; |
94 | bits=(bits+63)/64*64; | 102 | bits=(bits+63)/64*64; |
95 | 103 | ||
104 | if (seed_len < 20) | ||
105 | seed_in = NULL; /* seed buffer too small -- ignore */ | ||
106 | if (seed_len > 20) | ||
107 | seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, | ||
108 | * but our internal buffers are restricted to 160 bits*/ | ||
96 | if ((seed_in != NULL) && (seed_len == 20)) | 109 | if ((seed_in != NULL) && (seed_len == 20)) |
97 | memcpy(seed,seed_in,seed_len); | 110 | memcpy(seed,seed_in,seed_len); |
98 | 111 | ||
99 | if ((ctx=BN_CTX_new()) == NULL) goto err; | 112 | if ((ctx=BN_CTX_new()) == NULL) goto err; |
100 | if ((ctx2=BN_CTX_new()) == NULL) goto err; | 113 | if ((ctx2=BN_CTX_new()) == NULL) goto err; |
114 | if ((ctx3=BN_CTX_new()) == NULL) goto err; | ||
101 | if ((ret=DSA_new()) == NULL) goto err; | 115 | if ((ret=DSA_new()) == NULL) goto err; |
102 | 116 | ||
103 | if ((mont=BN_MONT_CTX_new()) == NULL) goto err; | 117 | if ((mont=BN_MONT_CTX_new()) == NULL) goto err; |
104 | 118 | ||
105 | r0= &(ctx2->bn[0]); | 119 | BN_CTX_start(ctx2); |
106 | g= &(ctx2->bn[1]); | 120 | r0 = BN_CTX_get(ctx2); |
107 | W= &(ctx2->bn[2]); | 121 | g = BN_CTX_get(ctx2); |
108 | q= &(ctx2->bn[3]); | 122 | W = BN_CTX_get(ctx2); |
109 | X= &(ctx2->bn[4]); | 123 | q = BN_CTX_get(ctx2); |
110 | c= &(ctx2->bn[5]); | 124 | X = BN_CTX_get(ctx2); |
111 | p= &(ctx2->bn[6]); | 125 | c = BN_CTX_get(ctx2); |
112 | test= &(ctx2->bn[7]); | 126 | p = BN_CTX_get(ctx2); |
127 | test = BN_CTX_get(ctx2); | ||
113 | 128 | ||
114 | BN_lshift(test,BN_value_one(),bits-1); | 129 | BN_lshift(test,BN_value_one(),bits-1); |
115 | 130 | ||
116 | for (;;) | 131 | for (;;) |
117 | { | 132 | { |
118 | for (;;) | 133 | for (;;) /* find q */ |
119 | { | 134 | { |
135 | int seed_is_random; | ||
136 | |||
120 | /* step 1 */ | 137 | /* step 1 */ |
121 | if (callback != NULL) callback(0,m++,cb_arg); | 138 | if (callback != NULL) callback(0,m++,cb_arg); |
122 | 139 | ||
123 | if (!seed_len) | 140 | if (!seed_len) |
124 | RAND_bytes(seed,SHA_DIGEST_LENGTH); | 141 | { |
142 | RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH); | ||
143 | seed_is_random = 1; | ||
144 | } | ||
125 | else | 145 | else |
126 | seed_len=0; | 146 | { |
127 | 147 | seed_is_random = 0; | |
148 | seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ | ||
149 | } | ||
128 | memcpy(buf,seed,SHA_DIGEST_LENGTH); | 150 | memcpy(buf,seed,SHA_DIGEST_LENGTH); |
129 | memcpy(buf2,seed,SHA_DIGEST_LENGTH); | 151 | memcpy(buf2,seed,SHA_DIGEST_LENGTH); |
152 | /* precompute "SEED + 1" for step 7: */ | ||
130 | for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) | 153 | for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) |
131 | { | 154 | { |
132 | buf[i]++; | 155 | buf[i]++; |
@@ -142,10 +165,15 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, | |||
142 | /* step 3 */ | 165 | /* step 3 */ |
143 | md[0]|=0x80; | 166 | md[0]|=0x80; |
144 | md[SHA_DIGEST_LENGTH-1]|=0x01; | 167 | md[SHA_DIGEST_LENGTH-1]|=0x01; |
145 | if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) abort(); | 168 | if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err; |
146 | 169 | ||
147 | /* step 4 */ | 170 | /* step 4 */ |
148 | if (DSA_is_prime(q,callback,cb_arg) > 0) break; | 171 | r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random); |
172 | if (r > 0) | ||
173 | break; | ||
174 | if (r != 0) | ||
175 | goto err; | ||
176 | |||
149 | /* do a callback call */ | 177 | /* do a callback call */ |
150 | /* step 5 */ | 178 | /* step 5 */ |
151 | } | 179 | } |
@@ -155,16 +183,22 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, | |||
155 | 183 | ||
156 | /* step 6 */ | 184 | /* step 6 */ |
157 | counter=0; | 185 | counter=0; |
186 | /* "offset = 2" */ | ||
158 | 187 | ||
159 | n=(bits-1)/160; | 188 | n=(bits-1)/160; |
160 | b=(bits-1)-n*160; | 189 | b=(bits-1)-n*160; |
161 | 190 | ||
162 | for (;;) | 191 | for (;;) |
163 | { | 192 | { |
193 | if (callback != NULL && counter != 0) | ||
194 | callback(0,counter,cb_arg); | ||
195 | |||
164 | /* step 7 */ | 196 | /* step 7 */ |
165 | BN_zero(W); | 197 | BN_zero(W); |
198 | /* now 'buf' contains "SEED + offset - 1" */ | ||
166 | for (k=0; k<=n; k++) | 199 | for (k=0; k<=n; k++) |
167 | { | 200 | { |
201 | /* obtain "SEED + offset + k" by incrementing: */ | ||
168 | for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) | 202 | for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) |
169 | { | 203 | { |
170 | buf[i]++; | 204 | buf[i]++; |
@@ -174,7 +208,8 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, | |||
174 | HASH(buf,SHA_DIGEST_LENGTH,md); | 208 | HASH(buf,SHA_DIGEST_LENGTH,md); |
175 | 209 | ||
176 | /* step 8 */ | 210 | /* step 8 */ |
177 | if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) abort(); | 211 | if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) |
212 | goto err; | ||
178 | BN_lshift(r0,r0,160*k); | 213 | BN_lshift(r0,r0,160*k); |
179 | BN_add(W,W,r0); | 214 | BN_add(W,W,r0); |
180 | } | 215 | } |
@@ -194,23 +229,25 @@ DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, | |||
194 | if (BN_cmp(p,test) >= 0) | 229 | if (BN_cmp(p,test) >= 0) |
195 | { | 230 | { |
196 | /* step 11 */ | 231 | /* step 11 */ |
197 | if (DSA_is_prime(p,callback,cb_arg) > 0) | 232 | r = BN_is_prime_fasttest(p, DSS_prime_checks, callback, ctx3, cb_arg, 1); |
198 | goto end; | 233 | if (r > 0) |
234 | goto end; /* found it */ | ||
235 | if (r != 0) | ||
236 | goto err; | ||
199 | } | 237 | } |
200 | 238 | ||
201 | /* step 13 */ | 239 | /* step 13 */ |
202 | counter++; | 240 | counter++; |
241 | /* "offset = offset + n + 1" */ | ||
203 | 242 | ||
204 | /* step 14 */ | 243 | /* step 14 */ |
205 | if (counter >= 4096) break; | 244 | if (counter >= 4096) break; |
206 | |||
207 | if (callback != NULL) callback(0,counter,cb_arg); | ||
208 | } | 245 | } |
209 | } | 246 | } |
210 | end: | 247 | end: |
211 | if (callback != NULL) callback(2,1,cb_arg); | 248 | if (callback != NULL) callback(2,1,cb_arg); |
212 | 249 | ||
213 | /* We now need to gernerate g */ | 250 | /* We now need to generate g */ |
214 | /* Set r0=(p-1)/q */ | 251 | /* Set r0=(p-1)/q */ |
215 | BN_sub(test,p,BN_value_one()); | 252 | BN_sub(test,p,BN_value_one()); |
216 | BN_div(r0,NULL,test,q,ctx); | 253 | BN_div(r0,NULL,test,q,ctx); |
@@ -245,89 +282,13 @@ err: | |||
245 | if (h_ret != NULL) *h_ret=h; | 282 | if (h_ret != NULL) *h_ret=h; |
246 | } | 283 | } |
247 | if (ctx != NULL) BN_CTX_free(ctx); | 284 | if (ctx != NULL) BN_CTX_free(ctx); |
248 | if (ctx != NULL) BN_CTX_free(ctx2); | 285 | if (ctx2 != NULL) |
249 | if (mont != NULL) BN_MONT_CTX_free(mont); | ||
250 | return(ok?ret:NULL); | ||
251 | } | ||
252 | |||
253 | int DSA_is_prime(BIGNUM *w, void (*callback)(), char *cb_arg) | ||
254 | { | ||
255 | int ok= -1,j,i,n; | ||
256 | BN_CTX *ctx=NULL,*ctx2=NULL; | ||
257 | BIGNUM *w_1,*b,*m,*z,*tmp,*mont_1; | ||
258 | int a; | ||
259 | BN_MONT_CTX *mont=NULL; | ||
260 | |||
261 | if (!BN_is_bit_set(w,0)) return(0); | ||
262 | |||
263 | if ((ctx=BN_CTX_new()) == NULL) goto err; | ||
264 | if ((ctx2=BN_CTX_new()) == NULL) goto err; | ||
265 | if ((mont=BN_MONT_CTX_new()) == NULL) goto err; | ||
266 | |||
267 | m= &(ctx2->bn[2]); | ||
268 | b= &(ctx2->bn[3]); | ||
269 | z= &(ctx2->bn[4]); | ||
270 | w_1= &(ctx2->bn[5]); | ||
271 | tmp= &(ctx2->bn[6]); | ||
272 | mont_1= &(ctx2->bn[7]); | ||
273 | |||
274 | /* step 1 */ | ||
275 | n=50; | ||
276 | |||
277 | /* step 2 */ | ||
278 | if (!BN_sub(w_1,w,BN_value_one())) goto err; | ||
279 | for (a=1; !BN_is_bit_set(w_1,a); a++) | ||
280 | ; | ||
281 | if (!BN_rshift(m,w_1,a)) goto err; | ||
282 | |||
283 | BN_MONT_CTX_set(mont,w,ctx); | ||
284 | BN_to_montgomery(mont_1,BN_value_one(),mont,ctx); | ||
285 | BN_to_montgomery(w_1,w_1,mont,ctx); | ||
286 | for (i=1; i < n; i++) | ||
287 | { | 286 | { |
288 | /* step 3 */ | 287 | BN_CTX_end(ctx2); |
289 | BN_rand(b,BN_num_bits(w)-2/*-1*/,0,0); | 288 | BN_CTX_free(ctx2); |
290 | /* BN_set_word(b,0x10001L); */ | ||
291 | |||
292 | /* step 4 */ | ||
293 | j=0; | ||
294 | if (!BN_mod_exp_mont(z,b,m,w,ctx,mont)) goto err; | ||
295 | |||
296 | if (!BN_to_montgomery(z,z,mont,ctx)) goto err; | ||
297 | |||
298 | /* step 5 */ | ||
299 | for (;;) | ||
300 | { | ||
301 | if (((j == 0) && (BN_cmp(z,mont_1) == 0)) || | ||
302 | (BN_cmp(z,w_1) == 0)) | ||
303 | break; | ||
304 | |||
305 | /* step 6 */ | ||
306 | if ((j > 0) && (BN_cmp(z,mont_1) == 0)) | ||
307 | { | ||
308 | ok=0; | ||
309 | goto err; | ||
310 | } | ||
311 | |||
312 | j++; | ||
313 | if (j >= a) | ||
314 | { | ||
315 | ok=0; | ||
316 | goto err; | ||
317 | } | ||
318 | |||
319 | if (!BN_mod_mul_montgomery(z,z,z,mont,ctx)) goto err; | ||
320 | if (callback != NULL) callback(1,j,cb_arg); | ||
321 | } | ||
322 | } | 289 | } |
323 | 290 | if (ctx3 != NULL) BN_CTX_free(ctx3); | |
324 | ok=1; | 291 | if (mont != NULL) BN_MONT_CTX_free(mont); |
325 | err: | 292 | return(ok?ret:NULL); |
326 | if (ok == -1) DSAerr(DSA_F_DSA_IS_PRIME,ERR_R_BN_LIB); | ||
327 | BN_CTX_free(ctx); | ||
328 | BN_CTX_free(ctx2); | ||
329 | BN_MONT_CTX_free(mont); | ||
330 | |||
331 | return(ok); | ||
332 | } | 293 | } |
333 | #endif | 294 | #endif |