static void bench_dsa_clear (void *p) { struct dsa_ctx *ctx = p; dsa_params_clear (&ctx->params); mpz_clear (ctx->pub); mpz_clear (ctx->key); dsa_signature_clear (&ctx->s); free (ctx->digest); free (ctx); }
int _dsa_validate_dss_g(struct dsa_params *pub, unsigned domain_seed_size, const uint8_t *domain_seed, unsigned index) { int ret; unsigned p_bits, q_bits; struct dsa_params pub2; mpz_t r; p_bits = mpz_sizeinbase(pub->p, 2); q_bits = mpz_sizeinbase(pub->q, 2); ret = _dsa_check_qp_sizes(q_bits, p_bits, 0); if (ret == 0) { return 0; } mpz_init(r); dsa_params_init(&pub2); mpz_set(pub2.p, pub->p); mpz_set(pub2.q, pub->q); /* verify g */ if (index > 255) { goto fail; } /* 2<= g <= p-1 */ mpz_set(r, pub->p); mpz_sub_ui(r, r, 1); if (mpz_cmp_ui(pub->g, 2) < 0 || mpz_cmp(pub->g, r) >= 0) { goto fail; } /* g^q == 1 mod p */ mpz_powm(r, pub->g, pub->q, pub->p); if (mpz_cmp_ui(r, 1) != 0) { goto fail; } /* repeat g generation */ ret = _dsa_generate_dss_g(&pub2, domain_seed_size, domain_seed, NULL, NULL, index); if (ret == 0) { goto fail; } if (mpz_cmp(pub->g, pub2.g) != 0) { goto fail; } /* everything looks ok */ ret = 1; goto finish; fail: ret = 0; finish: dsa_params_clear(&pub2); mpz_clear(r); return ret; }
int _dsa_validate_dss_pq(struct dsa_params *pub, struct dss_params_validation_seeds *cert) { int ret; unsigned p_bits, q_bits; struct dsa_params pub2; struct dss_params_validation_seeds cert2; mpz_t r, s; p_bits = mpz_sizeinbase(pub->p, 2); q_bits = mpz_sizeinbase(pub->q, 2); ret = _dsa_check_qp_sizes(q_bits, p_bits, 0); if (ret == 0) { return 0; } mpz_init(r); mpz_init(s); dsa_params_init(&pub2); nettle_mpz_set_str_256_u(s, cert->seed_length, cert->seed); /* firstseed < 2^(N-1) */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, q_bits - 1); if (mpz_cmp(s, r) < 0) { goto fail; } /* 2^N <= q */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, q_bits); if (mpz_cmp(r, pub->q) <= 0) { goto fail; } /* 2^L <= p */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, p_bits); if (mpz_cmp(r, pub->p) <= 0) { goto fail; } /* p-1 mod q != 0 */ mpz_set(r, pub->p); mpz_sub_ui(r, r, 1); mpz_mod(r, r, pub->q); if (mpz_cmp_ui(r, 0) != 0) { goto fail; } /* replay the construction */ ret = _dsa_generate_dss_pq(&pub2, &cert2, cert->seed_length, cert->seed, NULL, NULL, p_bits, q_bits); if (ret == 0) { goto fail; } if ((cert->pseed_length > 0 && cert->pseed_length != cert2.pseed_length) || (cert->qseed_length > 0 && cert->qseed_length != cert2.qseed_length) || (cert->pgen_counter > 0 && cert->pgen_counter != cert2.pgen_counter) || (cert->qgen_counter > 0 && cert->qgen_counter != cert2.qgen_counter) || (cert->qseed_length > 0 && memcmp(cert->qseed, cert2.qseed, cert2.qseed_length) != 0) || (cert->pseed_length > 0 && memcmp(cert->pseed, cert2.pseed, cert2.pseed_length) != 0)) { goto fail; } if (mpz_cmp(pub->q, pub2.q) != 0) { goto fail; } if (mpz_cmp(pub->p, pub2.p) != 0) { goto fail; } if (mpz_sizeinbase(s, 2) < q_bits - 1) { goto fail; } ret = 1; goto finish; fail: ret = 0; finish: dsa_params_clear(&pub2); mpz_clear(r); mpz_clear(s); return ret; }