acvpparser icon indicating copy to clipboard operation
acvpparser copied to clipboard

DSA PQGGen gMode not supports CANONICAL generation mode

Open pkou0125 opened this issue 1 year ago • 1 comments

Hi Stephan,

I wanna add a function for openssl to about DSA PQGGen with verifiable canonical generation of the generator g.

backend_openssl.c: add a condition to call new function when parsed flags with dsa pqg gen & canonical mode.

static int openssl_dsa_pqg(struct dsa_pqg_data *data, flags_t parsed_flags)
{
	parsed_flags &= ~FLAG_OP_GDT;
	if (parsed_flags ==
	    (FLAG_OP_DSA_TYPE_PQGGEN | FLAG_OP_DSA_PROBABLE_PQ_GEN))
		return openssl_dsa_pq_gen(data, parsed_flags);
	else if (parsed_flags ==
		(FLAG_OP_DSA_TYPE_PQGGEN | FLAG_OP_DSA_CANONICAL_G_GEN))
		return openssl_dsa_g_gen_new(data, parsed_flags);
	else if (parsed_flags ==
		 (FLAG_OP_DSA_TYPE_PQGVER | FLAG_OP_DSA_PROBABLE_PQ_GEN))
		return openssl_dsa_pq_ver(data, parsed_flags);
	else if (parsed_flags ==
		 (FLAG_OP_DSA_TYPE_PQGGEN | FLAG_OP_DSA_UNVERIFIABLE_G_GEN))
		return openssl_dsa_g_gen(data, parsed_flags);
	else if (parsed_flags ==
		 (FLAG_OP_DSA_TYPE_PQGVER | FLAG_OP_DSA_UNVERIFIABLE_G_GEN))
		return openssl_dsa_pqg_ver(data, parsed_flags);
	else {
		logger(LOGGER_WARN,
		       "Unknown DSA PQG generation / verification definition (parsed flags: %" PRIu64 ")\n",
		       parsed_flags);
		return -EINVAL;
	}
}

Copy openssl_dsa_g_gen and get g_canon_index, put index into FIPS_dsa_builtin_paramgen2.

static int openssl_dsa_g_gen_new(struct dsa_pqg_data *data, flags_t parsed_flags)
{
	DSA *dsa = NULL;
	int ret = 0, pqg_consumed = 0;
	const EVP_MD *md = NULL;
	BIGNUM *p = NULL, *q = NULL, *g = NULL;
	const BIGNUM *g_gen;
	unsigned long h;
	int counter;
	unsigned char seed[1024];

	(void)parsed_flags;

	dsa = DSA_new();
	CKNULL_LOG(dsa, -ENOMEM, "DSA_new() failed\n");

	CKINT(left_pad_buf(&data->P, data->L / 8));
	CKINT(left_pad_buf(&data->Q, data->N / 8));

	logger(LOGGER_DEBUG, "L = %u\n", data->L);
	logger(LOGGER_DEBUG, "N = %u\n", data->N);

	logger_binary(LOGGER_DEBUG, data->P.buf, data->P.len, "P");
	logger_binary(LOGGER_DEBUG, data->Q.buf, data->Q.len, "Q");
	logger_binary(LOGGER_DEBUG, data->g_canon_index.buf, data->g_canon_index.len, "idx");

	int index = (int)data->g_canon_index.buf[0];

	p = BN_bin2bn((const unsigned char *)data->P.buf, (int)data->P.len,
		      NULL);
	CKNULL_LOG(p, -ENOMEM, "BN_bin2bn() failed\n");

	q = BN_bin2bn((const unsigned char *)data->Q.buf, (int)data->Q.len,
		      NULL);
	CKNULL_LOG(q, -ENOMEM, "BN_bin2bn() failed\n");

	g = BN_new();
	CKNULL_LOG(g, -ENOMEM, "BN_new() failed\n");

	CKINT_O_LOG(openssl_dsa_set0_pqg(dsa, p, q, g),
		    "DSA_set0_pqg failed\n");
	pqg_consumed = 1;

	logger(LOGGER_DEBUG, "hash = %" PRIu64 "\n", data->cipher);
	CKINT(openssl_md_convert(data->cipher & ACVP_HASHMASK, &md));

	CKINT_O_LOG(FIPS_dsa_builtin_paramgen2(dsa, data->L, data->N, md,
					       NULL, 0, index, seed, &counter, &h,
					       NULL),
		    "FIPS_dsa_generate_pq() failed %s\n",
		    ERR_error_string(ERR_get_error(), NULL));

	openssl_dsa_get0_pqg(dsa, NULL, NULL, &g_gen);
	CKINT(openssl_bn2buffer(g_gen, &data->G));

	logger_binary(LOGGER_DEBUG, data->G.buf, data->G.len, "G");

	ret = 0;

out:
	if (dsa)
		DSA_free(dsa);
	if (!pqg_consumed && p)
		BN_free(p);
	if (!pqg_consumed && q)
		BN_free(q);
	if (!pqg_consumed && g)
		BN_free(g);

	return ret;
}

Please correct me if there's anything wrong from my changes. Same question that how to support dsa pqg verify for canonical mode?

Thanks, Tony

pkou0125 avatar Apr 12 '23 07:04 pkou0125

Am Mittwoch, 12. April 2023, 09:24:26 CEST schrieb pkou0125:

Hi pkou0125,

sorry for the delay.

Hi Stephan,

I wanna add a function for openssl to about DSA PQGGen with verifiable canonical generation of the generator g.

backend_openssl.c: add a condition to call new function when parsed flags with dsa pqg gen & canonical mode.

static int openssl_dsa_pqg(struct dsa_pqg_data *data, flags_t parsed_flags)
{
	parsed_flags &= ~FLAG_OP_GDT;
	if (parsed_flags ==
	    (FLAG_OP_DSA_TYPE_PQGGEN | FLAG_OP_DSA_PROBABLE_PQ_GEN))
		return openssl_dsa_pq_gen(data, parsed_flags);
	else if (parsed_flags ==
		(FLAG_OP_DSA_TYPE_PQGGEN | FLAG_OP_DSA_CANONICAL_G_GEN))
		return openssl_dsa_g_gen_new(data, parsed_flags);
	else if (parsed_flags ==
		 (FLAG_OP_DSA_TYPE_PQGVER | FLAG_OP_DSA_PROBABLE_PQ_GEN))
		return openssl_dsa_pq_ver(data, parsed_flags);
	else if (parsed_flags ==
		 (FLAG_OP_DSA_TYPE_PQGGEN | FLAG_OP_DSA_UNVERIFIABLE_G_GEN))
		return openssl_dsa_g_gen(data, parsed_flags);
	else if (parsed_flags ==
		 (FLAG_OP_DSA_TYPE_PQGVER | FLAG_OP_DSA_UNVERIFIABLE_G_GEN))
		return openssl_dsa_pqg_ver(data, parsed_flags);
	else {
		logger(LOGGER_WARN,
		       "Unknown DSA PQG generation / verification definition 

(parsed

flags: %" PRIu64 ")\n", parsed_flags); return -EINVAL; } }

Copy openssl_dsa_g_gen and get g_canon_index, put index into
FIPS_dsa_builtin_paramgen2.

static int openssl_dsa_g_gen_new(struct dsa_pqg_data *data, flags_t parsed_flags) { DSA *dsa = NULL; int ret = 0, pqg_consumed = 0; const EVP_MD *md = NULL; BIGNUM *p = NULL, *q = NULL, *g = NULL; const BIGNUM *g_gen; unsigned long h; int counter; unsigned char seed[1024];

(void)parsed_flags;

dsa = DSA_new(); CKNULL_LOG(dsa, -ENOMEM, "DSA_new() failed\n");

CKINT(left_pad_buf(&data->P, data->L / 8)); CKINT(left_pad_buf(&data->Q, data->N / 8));

logger(LOGGER_DEBUG, "L = %u\n", data->L); logger(LOGGER_DEBUG, "N = %u\n", data->N);

logger_binary(LOGGER_DEBUG, data->P.buf, data->P.len, "P"); logger_binary(LOGGER_DEBUG, data->Q.buf, data->Q.len, "Q"); logger_binary(LOGGER_DEBUG, data->g_canon_index.buf, data->g_canon_index.len, "idx");

int index = (int)data->g_canon_index.buf[0];

p = BN_bin2bn((const unsigned char *)data->P.buf, (int)data->P.len, NULL); CKNULL_LOG(p, -ENOMEM, "BN_bin2bn() failed\n");

q = BN_bin2bn((const unsigned char *)data->Q.buf, (int)data->Q.len, NULL); CKNULL_LOG(q, -ENOMEM, "BN_bin2bn() failed\n");

g = BN_new(); CKNULL_LOG(g, -ENOMEM, "BN_new() failed\n");

CKINT_O_LOG(openssl_dsa_set0_pqg(dsa, p, q, g), "DSA_set0_pqg failed\n"); pqg_consumed = 1;

logger(LOGGER_DEBUG, "hash = %" PRIu64 "\n", data->cipher); CKINT(openssl_md_convert(data->cipher & ACVP_HASHMASK, &md));

CKINT_O_LOG(FIPS_dsa_builtin_paramgen2(dsa, data->L, data->N, md, NULL, 0, index, seed, &counter, &h, NULL), "FIPS_dsa_generate_pq() failed %s\n", ERR_error_string(ERR_get_error(), NULL));

openssl_dsa_get0_pqg(dsa, NULL, NULL, &g_gen); CKINT(openssl_bn2buffer(g_gen, &data->G));

logger_binary(LOGGER_DEBUG, data->G.buf, data->G.len, "G");

ret = 0;

out: if (dsa) DSA_free(dsa); if (!pqg_consumed && p) BN_free(p); if (!pqg_consumed && q) BN_free(q); if (!pqg_consumed && g) BN_free(g);

return ret; }


Please correct me if there's anything wrong from my changes.
Same question that how to support dsa pqg verify for canonical mode?

The approach looks good.

Thanks, Tony

Ciao Stephan

smuellerDD avatar May 22 '23 06:05 smuellerDD