acvpparser icon indicating copy to clipboard operation
acvpparser copied to clipboard

RSA Decrypt Primitive Sp800-56Br2 vector not supported

Open pkou0125 opened this issue 1 year ago • 1 comments

Hi Stephan,

Due to https://pages.nist.gov/ACVP/draft-celi-acvp-rsa.html#name-rsa-decryptionprimitive-sp8

acvp-parser currently supports [RSA Decryption Primitive 1.0] to calculate ciphertext to plaintext, e, n and testPassed results but I'm facing test vector running with revision SP800-56Br2 not supported issue. Is there any plan to support it?

I'm trying to make acvp-parser supports RSA decrypt with prime factor in OpenSSL(1.0.2k).

parser_rsa.c input & output definition:

	/* SP800-56Br2  Response */
	const struct json_entry rsa_decryption_primitive_testresult_entries[] = {
		{"pt",		{.data.buf = &rsa_decryption_primitive_vector.pt, WRITER_BIN},
			         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT},
	};

	const struct json_testresult rsa_decryption_primitive_testresult = SET_ARRAY(rsa_decryption_primitive_testresult_entries, &rsa_decryption_primitive_callbacks);

	/* SP800-56Br2  Request */
	const struct json_entry rsa_decryption_primitive_testresults_entries[] = {
		{"tcId",	{.data.integer = &rsa_decryption_primitive_vector.tcid, PARSER_UINT},
			         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT},
		{"ct",	{.data.buf = &rsa_decryption_primitive_vector.ct, PARSER_BIN},
			         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT},
		{"p",	{.data.buf = &rsa_decryption_primitive_vector.p, PARSER_BIN},
			         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT},
		{"q",	{.data.buf = &rsa_decryption_primitive_vector.q, PARSER_BIN},
			         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT},
		{"d",	{.data.buf = &rsa_decryption_primitive_vector.d, PARSER_BIN},
			         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT},
	};
	const struct json_array rsa_decryption_primitive_testresults = SET_ARRAY(rsa_decryption_primitive_testresults_entries, &rsa_decryption_primitive_testresult);

now I get input ct, p, q ,d and output with pt.

Define a new function to generate RSA structure with p, q, d as input:

static int openssl_rsa_keygen_en_new(struct buffer *ebuf, uint32_t modulus,
				 void **privkey, struct buffer *nbuf, struct buffer *dbuf, struct buffer *pbuf, struct buffer *qbuf)
{
	return openssl_rsa_keygen_internal(ebuf, modulus, (RSA **)privkey, nbuf,
					   dbuf, pbuf, qbuf);
}

My question here is focus on class openssl_rsa_keygen_internal. If I don't care other RSA test cases only need RSA DP result,

openssl_rsa_keygen_internal

        e = BN_bin2bn((const unsigned char *)ebuf->buf, (int)ebuf->len, e);
	CKNULL(e, -ENOMEM);
	p = BN_bin2bn((const unsigned char *)pbuf->buf, (int)pbuf->len, p);
	CKNULL(p, -ENOMEM);
	q = BN_bin2bn((const unsigned char *)qbuf->buf, (int)qbuf->len, q);
	CKNULL(q, -ENOMEM);
	d = BN_bin2bn((const unsigned char *)dbuf->buf, (int)dbuf->len, d);
	CKNULL(d, -ENOMEM);

	BN_CTX *ctx = BN_CTX_new();
        n = BN_new();

        ret = BN_mul(n, p, q, ctx);

        if (ret != 1) {
            printf("Error: failed to calculate n\n");
        return -1;
        }

	BN_CTX_free(ctx);

        if (rsa)
		RSA_free(rsa);

	rsa = RSA_new();
	CKNULL(rsa, -ENOMEM);

	CKINT_O_LOG(openssl_rsa_set0_key(rsa, n, e, d),
			"Assembly of RSA key failed\n");
	CKINT_O_LOG(openssl_rsa_set0_factors(rsa, p, q),
			"Assembly of RSA factors failed\n");

        if (RSA_check_key(rsa) != 1) {
		printf("Error: RSA key is invalid\n");
		ERR_print_errors_fp(stderr);
		/* handle the error */
	}

	if (outkey) {
		*outkey = rsa;
		rsa = NULL;
	}

Is there something I lost to calculate plaintext on it? or there's other function I can refer to?

Regards, Tony

pkou0125 avatar Apr 12 '23 06:04 pkou0125

Am Mittwoch, 12. April 2023, 08:52:40 CEST schrieb pkou0125:

Hi pkou0125,

Hi Stephan,

Due to https://pages.nist.gov/ACVP/draft-celi-acvp-rsa.html#name-rsa-decryptionpri mitive-sp8

acvp-parser currently supports [RSA Decryption Primitive 1.0] to calculate ciphertext to plaintext, e, n and testPassed results but I'm facing test vector running with revision SP800-56Br2 not supported issue. Is there any plan to support it?

In general, yes.

I'm trying to make acvp-parser supports RSA decrypt with prime factor.

parser_rsa.c input & output definition:

	/* SP800-56Br2  Response */
	const struct json_entry rsa_decryption_primitive_testresult_entries[] = 

{

  {"pt",		{.data.buf = &rsa_decryption_primitive_vector.pt, 

WRITER_BIN},

  	         FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | 

FLAG_OP_AFT},

};

const struct json_testresult rsa_decryption_primitive_testresult = SET_ARRAY(rsa_decryption_primitive_testresult_entries, &rsa_decryption_primitive_callbacks);

/* SP800-56Br2 Request */ const struct json_entry rsa_decryption_primitive_testresults_entries[] = { {"tcId", {.data.integer = &rsa_decryption_primitive_vector.tcid, PARSER_UINT}, FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT}, {"ct", {.data.buf = &rsa_decryption_primitive_vector.ct, PARSER_BIN}, FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT}, {"p", {.data.buf = &rsa_decryption_primitive_vector.p, PARSER_BIN}, FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT}, {"q", {.data.buf = &rsa_decryption_primitive_vector.q, PARSER_BIN}, FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT}, {"d", {.data.buf = &rsa_decryption_primitive_vector.d, PARSER_BIN}, FLAG_OP_RSA_TYPE_COMPONENT_DEC_PRIMITIVE | FLAG_OP_AFT}, }; const struct json_array rsa_decryption_primitive_testresults = SET_ARRAY(rsa_decryption_primitive_testresults_entries, &rsa_decryption_primitive_testresult); ``` now I get input ct, p, q ,d and output with pt.

Looks good.

Define a new function to generate RSA structure with p, q, d as input:

static int openssl_rsa_keygen_en_new(struct buffer *ebuf, uint32_t modulus,
				 void **privkey, struct buffer *nbuf, struct buffer 

*dbuf, struct buffer

*pbuf, struct buffer *qbuf) { return openssl_rsa_keygen_internal(ebuf, modulus, (RSA **)privkey, nbuf, dbuf, pbuf, qbuf); }


My question here is focus on class openssl_rsa_keygen_internal.
If I don't care other RSA test cases only need RSA DP result,

openssl_rsa_keygen_internal
    e = BN_bin2bn((const unsigned char *)ebuf->buf, (int)ebuf->len, e);

CKNULL(e, -ENOMEM); p = BN_bin2bn((const unsigned char *)pbuf->buf, (int)pbuf->len, p); CKNULL(p, -ENOMEM); q = BN_bin2bn((const unsigned char *)qbuf->buf, (int)qbuf->len, q); CKNULL(q, -ENOMEM); d = BN_bin2bn((const unsigned char *)dbuf->buf, (int)dbuf->len, d); CKNULL(d, -ENOMEM);

BN_CTX *ctx = BN_CTX_new(); n = BN_new();

    ret = BN_mul(n, p, q, ctx);

    if (ret != 1) {
        printf("Error: failed to calculate n\n");
    return -1;
    }

BN_CTX_free(ctx);

    if (rsa)
  RSA_free(rsa);

rsa = RSA_new(); CKNULL(rsa, -ENOMEM);

CKINT_O_LOG(openssl_rsa_set0_key(rsa, n, e, d), "Assembly of RSA key failed\n"); CKINT_O_LOG(openssl_rsa_set0_factors(rsa, p, q), "Assembly of RSA factors failed\n");

    if (RSA_check_key(rsa) != 1) {
  printf("Error: RSA key is invalid\n");
  ERR_print_errors_fp(stderr);
  /* handle the error */

}

if (outkey) { *outkey = rsa; rsa = NULL; }


Is there something I lost to calculate plaintext on it? or there's other
function I can refer to?

What about openssl_rsa_create_pkey?

Regards, Tony

Ciao Stephan

smuellerDD avatar May 22 '23 06:05 smuellerDD