Loading CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Add support for canonical generation of DSA parameter 'g'. See FIPS 186-3 A.2.3. *) Add support for HMAC DRBG from SP800-90. Update algorithm and POST to handle HMAC cases. [Steve Henson] Loading crypto/dsa/dsa_gen.c +107 −11 Original line number Diff line number Diff line Loading @@ -452,11 +452,11 @@ int fips_check_dsa_prng(DSA *dsa, size_t L, size_t N) int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=-1; unsigned char *seed = NULL; unsigned char *seed = NULL, *seed_tmp = NULL; unsigned char md[EVP_MAX_MD_SIZE]; int mdsize; BIGNUM *r0,*W,*X,*c,*test; Loading @@ -466,8 +466,11 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, int counter=0; int r=0; BN_CTX *ctx=NULL; EVP_MD_CTX mctx; unsigned int h=2; EVP_MD_CTX_init(&mctx); #ifdef OPENSSL_FIPS if(FIPS_selftest_failed()) { Loading Loading @@ -497,7 +500,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, seed = OPENSSL_malloc(seed_len); if (!seed) if (seed_out) seed_tmp = seed_out; else seed_tmp = OPENSSL_malloc(seed_len); if (!seed || !seed_tmp) goto err; if (seed_in) Loading @@ -513,12 +521,24 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); /* if p, q already supplied generate g only */ if (ret->p && ret->q) { p = ret->p; q = ret->q; memcpy(seed_tmp, seed, seed_len); goto g_only; } else { p = BN_CTX_get(ctx); q = BN_CTX_get(ctx); } if (!BN_lshift(test,BN_value_one(),L-1)) goto err; for (;;) Loading Loading @@ -648,21 +668,50 @@ end: if(!BN_GENCB_call(cb, 2, 1)) goto err; g_only: /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test,p,BN_value_one())) goto err; if (!BN_div(r0,NULL,test,q,ctx)) goto err; if (!BN_set_word(test,h)) goto err; if (idx < 0) { if (!BN_set_word(test,h)) goto err; } else h = 1; if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; for (;;) { static const unsigned char ggen[4] = {0x67,0x67,0x65,0x6e}; if (idx >= 0) { md[0] = idx & 0xff; md[1] = (h >> 8) & 0xff; md[2] = h & 0xff; if (!EVP_DigestInit_ex(&mctx, evpmd, NULL)) goto err; if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len)) goto err; if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen))) goto err; if (!EVP_DigestUpdate(&mctx, md, 3)) goto err; if (!EVP_DigestFinal_ex(&mctx, md, NULL)) goto err; if (!BN_bin2bn(md, mdsize, test)) goto err; } /* g=test^r0%p */ if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test,test,BN_value_one())) goto err; if (idx < 0 && !BN_add(test,test,BN_value_one())) goto err; h++; if ( idx >= 0 && h > 0xffff) goto err; } if(!BN_GENCB_call(cb, 3, 1)) Loading @@ -671,12 +720,18 @@ end: ok=1; err: if (ok == 1) { if (p != ret->p) { if(ret->p) BN_free(ret->p); if(ret->q) BN_free(ret->q); if(ret->g) BN_free(ret->g); ret->p=BN_dup(p); } if (q != ret->q) { if(ret->q) BN_free(ret->q); ret->q=BN_dup(q); } if(ret->g) BN_free(ret->g); ret->g=BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { Loading @@ -688,12 +743,53 @@ err: } if (seed) OPENSSL_free(seed); if (seed_out != seed_tmp) OPENSSL_free(seed_tmp); if(ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); EVP_MD_CTX_cleanup(&mctx); return ok; } int dsa_paramgen_check_g(DSA *dsa) { BN_CTX *ctx; BIGNUM *tmp; BN_MONT_CTX *mont = NULL; int rv = -1; ctx = BN_CTX_new(); if (!ctx) return -1; BN_CTX_start(ctx); if (BN_cmp(dsa->g, BN_value_one()) <= 0) return 0; if (BN_cmp(dsa->g, dsa->p) >= 0) return 0; tmp = BN_CTX_get(ctx); if (!tmp) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; if (!BN_MONT_CTX_set(mont,dsa->p,ctx)) goto err; /* Work out g^q mod p */ if (!BN_mod_exp_mont(tmp,dsa->g,dsa->q, dsa->p, ctx, mont)) goto err; if (!BN_cmp(tmp, BN_value_one())) rv = 1; else rv = 0; err: BN_CTX_end(ctx); if (mont) BN_MONT_CTX_free(mont); BN_CTX_free(ctx); return rv; } #endif crypto/dsa/dsa_locl.h +4 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int dsa_builtin_paramgen2(DSA *ret, size_t bits, size_t qbits, int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int dsa_paramgen_check_g(DSA *dsa); fips/dsa/fips_dssvs.c +39 −12 Original line number Diff line number Diff line Loading @@ -111,9 +111,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int dsa_builtin_paramgen2(DSA *ret, size_t bits, size_t qbits, int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); static void pqg(FILE *in, FILE *out) Loading Loading @@ -160,7 +160,7 @@ static void pqg(FILE *in, FILE *out) exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, seed, NULL, 0, -1, seed, &counter, &h, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); Loading Loading @@ -191,8 +191,8 @@ static void pqgver(FILE *in, FILE *out) DSA *dsa=NULL; int dsa2, L, N, part_test = 0; const EVP_MD *md = NULL; int seedlen=-1; unsigned char seed[1024]; int seedlen=-1, idxlen, idx = -1; unsigned char seed[1024], idtmp[1024]; while(fgets(buf,sizeof buf,in) != NULL) { Loading Loading @@ -221,7 +221,8 @@ static void pqgver(FILE *in, FILE *out) q=hex2bn(value); else if(!strcmp(keyword,"G")) g=hex2bn(value); else if(!strcmp(keyword,"Seed")) else if(!strcmp(keyword,"Seed") || !strcmp(keyword,"domain_parameter_seed")) { seedlen = hex2bin(value, seed); if (!dsa2 && seedlen != 20) Loading @@ -229,6 +230,18 @@ static void pqgver(FILE *in, FILE *out) fprintf(stderr, "Seed parse length error\n"); exit (1); } if (idx > 0) part_test = 1; } else if(!strcmp(keyword,"index")) { idxlen = hex2bin(value, idtmp); if (idxlen != 1) { fprintf(stderr, "Index value error\n"); exit (1); } idx = idtmp[0]; } else if(!strcmp(keyword,"c")) counter = atoi(buf+4); Loading @@ -243,6 +256,11 @@ static void pqgver(FILE *in, FILE *out) exit (1); } dsa = FIPS_dsa_new(); if (idx >= 0) { dsa->p = BN_dup(p); dsa->q = BN_dup(q); } if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, seed, seedlen, NULL, &counter2, &h2, NULL)) Loading @@ -251,13 +269,20 @@ static void pqgver(FILE *in, FILE *out) exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, seed, seedlen, NULL, seed, seedlen, idx, NULL, &counter2, &h2, NULL) < 0) { fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || if (idx >= 0) { if (BN_cmp(dsa->g, g)) fprintf(out, "Result = F\n"); else fprintf(out, "Result = P\n"); } else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || (!part_test && ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2))))) fprintf(out, "Result = F\n"); Loading @@ -273,9 +298,11 @@ static void pqgver(FILE *in, FILE *out) dsa = NULL; if (part_test) { if (idx == -1) fputs(buf,out); part_test = 0; } idx = -1; } } } Loading Loading @@ -436,7 +463,7 @@ static void keypair(FILE *in, FILE *out) fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1, NULL, NULL, NULL, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); Loading Loading @@ -493,7 +520,7 @@ static void siggen(FILE *in, FILE *out) fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1, NULL, NULL, NULL, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); Loading Loading
CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Add support for canonical generation of DSA parameter 'g'. See FIPS 186-3 A.2.3. *) Add support for HMAC DRBG from SP800-90. Update algorithm and POST to handle HMAC cases. [Steve Henson] Loading
crypto/dsa/dsa_gen.c +107 −11 Original line number Diff line number Diff line Loading @@ -452,11 +452,11 @@ int fips_check_dsa_prng(DSA *dsa, size_t L, size_t N) int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=-1; unsigned char *seed = NULL; unsigned char *seed = NULL, *seed_tmp = NULL; unsigned char md[EVP_MAX_MD_SIZE]; int mdsize; BIGNUM *r0,*W,*X,*c,*test; Loading @@ -466,8 +466,11 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, int counter=0; int r=0; BN_CTX *ctx=NULL; EVP_MD_CTX mctx; unsigned int h=2; EVP_MD_CTX_init(&mctx); #ifdef OPENSSL_FIPS if(FIPS_selftest_failed()) { Loading Loading @@ -497,7 +500,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, seed = OPENSSL_malloc(seed_len); if (!seed) if (seed_out) seed_tmp = seed_out; else seed_tmp = OPENSSL_malloc(seed_len); if (!seed || !seed_tmp) goto err; if (seed_in) Loading @@ -513,12 +521,24 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); /* if p, q already supplied generate g only */ if (ret->p && ret->q) { p = ret->p; q = ret->q; memcpy(seed_tmp, seed, seed_len); goto g_only; } else { p = BN_CTX_get(ctx); q = BN_CTX_get(ctx); } if (!BN_lshift(test,BN_value_one(),L-1)) goto err; for (;;) Loading Loading @@ -648,21 +668,50 @@ end: if(!BN_GENCB_call(cb, 2, 1)) goto err; g_only: /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test,p,BN_value_one())) goto err; if (!BN_div(r0,NULL,test,q,ctx)) goto err; if (!BN_set_word(test,h)) goto err; if (idx < 0) { if (!BN_set_word(test,h)) goto err; } else h = 1; if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; for (;;) { static const unsigned char ggen[4] = {0x67,0x67,0x65,0x6e}; if (idx >= 0) { md[0] = idx & 0xff; md[1] = (h >> 8) & 0xff; md[2] = h & 0xff; if (!EVP_DigestInit_ex(&mctx, evpmd, NULL)) goto err; if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len)) goto err; if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen))) goto err; if (!EVP_DigestUpdate(&mctx, md, 3)) goto err; if (!EVP_DigestFinal_ex(&mctx, md, NULL)) goto err; if (!BN_bin2bn(md, mdsize, test)) goto err; } /* g=test^r0%p */ if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test,test,BN_value_one())) goto err; if (idx < 0 && !BN_add(test,test,BN_value_one())) goto err; h++; if ( idx >= 0 && h > 0xffff) goto err; } if(!BN_GENCB_call(cb, 3, 1)) Loading @@ -671,12 +720,18 @@ end: ok=1; err: if (ok == 1) { if (p != ret->p) { if(ret->p) BN_free(ret->p); if(ret->q) BN_free(ret->q); if(ret->g) BN_free(ret->g); ret->p=BN_dup(p); } if (q != ret->q) { if(ret->q) BN_free(ret->q); ret->q=BN_dup(q); } if(ret->g) BN_free(ret->g); ret->g=BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { Loading @@ -688,12 +743,53 @@ err: } if (seed) OPENSSL_free(seed); if (seed_out != seed_tmp) OPENSSL_free(seed_tmp); if(ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); EVP_MD_CTX_cleanup(&mctx); return ok; } int dsa_paramgen_check_g(DSA *dsa) { BN_CTX *ctx; BIGNUM *tmp; BN_MONT_CTX *mont = NULL; int rv = -1; ctx = BN_CTX_new(); if (!ctx) return -1; BN_CTX_start(ctx); if (BN_cmp(dsa->g, BN_value_one()) <= 0) return 0; if (BN_cmp(dsa->g, dsa->p) >= 0) return 0; tmp = BN_CTX_get(ctx); if (!tmp) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; if (!BN_MONT_CTX_set(mont,dsa->p,ctx)) goto err; /* Work out g^q mod p */ if (!BN_mod_exp_mont(tmp,dsa->g,dsa->q, dsa->p, ctx, mont)) goto err; if (!BN_cmp(tmp, BN_value_one())) rv = 1; else rv = 0; err: BN_CTX_end(ctx); if (mont) BN_MONT_CTX_free(mont); BN_CTX_free(ctx); return rv; } #endif
crypto/dsa/dsa_locl.h +4 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int dsa_builtin_paramgen2(DSA *ret, size_t bits, size_t qbits, int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int dsa_paramgen_check_g(DSA *dsa);
fips/dsa/fips_dssvs.c +39 −12 Original line number Diff line number Diff line Loading @@ -111,9 +111,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); int dsa_builtin_paramgen2(DSA *ret, size_t bits, size_t qbits, int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, unsigned char *seed_out, int idx, unsigned char *seed_out, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); static void pqg(FILE *in, FILE *out) Loading Loading @@ -160,7 +160,7 @@ static void pqg(FILE *in, FILE *out) exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, seed, NULL, 0, -1, seed, &counter, &h, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); Loading Loading @@ -191,8 +191,8 @@ static void pqgver(FILE *in, FILE *out) DSA *dsa=NULL; int dsa2, L, N, part_test = 0; const EVP_MD *md = NULL; int seedlen=-1; unsigned char seed[1024]; int seedlen=-1, idxlen, idx = -1; unsigned char seed[1024], idtmp[1024]; while(fgets(buf,sizeof buf,in) != NULL) { Loading Loading @@ -221,7 +221,8 @@ static void pqgver(FILE *in, FILE *out) q=hex2bn(value); else if(!strcmp(keyword,"G")) g=hex2bn(value); else if(!strcmp(keyword,"Seed")) else if(!strcmp(keyword,"Seed") || !strcmp(keyword,"domain_parameter_seed")) { seedlen = hex2bin(value, seed); if (!dsa2 && seedlen != 20) Loading @@ -229,6 +230,18 @@ static void pqgver(FILE *in, FILE *out) fprintf(stderr, "Seed parse length error\n"); exit (1); } if (idx > 0) part_test = 1; } else if(!strcmp(keyword,"index")) { idxlen = hex2bin(value, idtmp); if (idxlen != 1) { fprintf(stderr, "Index value error\n"); exit (1); } idx = idtmp[0]; } else if(!strcmp(keyword,"c")) counter = atoi(buf+4); Loading @@ -243,6 +256,11 @@ static void pqgver(FILE *in, FILE *out) exit (1); } dsa = FIPS_dsa_new(); if (idx >= 0) { dsa->p = BN_dup(p); dsa->q = BN_dup(q); } if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, seed, seedlen, NULL, &counter2, &h2, NULL)) Loading @@ -251,13 +269,20 @@ static void pqgver(FILE *in, FILE *out) exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, seed, seedlen, NULL, seed, seedlen, idx, NULL, &counter2, &h2, NULL) < 0) { fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || if (idx >= 0) { if (BN_cmp(dsa->g, g)) fprintf(out, "Result = F\n"); else fprintf(out, "Result = P\n"); } else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || (!part_test && ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2))))) fprintf(out, "Result = F\n"); Loading @@ -273,9 +298,11 @@ static void pqgver(FILE *in, FILE *out) dsa = NULL; if (part_test) { if (idx == -1) fputs(buf,out); part_test = 0; } idx = -1; } } } Loading Loading @@ -436,7 +463,7 @@ static void keypair(FILE *in, FILE *out) fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1, NULL, NULL, NULL, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); Loading Loading @@ -493,7 +520,7 @@ static void siggen(FILE *in, FILE *out) fprintf(stderr, "Parameter Generation error\n"); exit(1); } if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1, NULL, NULL, NULL, NULL) <= 0) { fprintf(stderr, "Parameter Generation error\n"); Loading