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 |
