smuellerDD / acvpparser

ACVP Parser for invocation of cryptographic implementations using the ACVP JSON test vectors
https://www.chronox.de/acvpparser
Other
36 stars 27 forks source link

RSA Decrypt Primitive Sp800-56Br2 vector not supported #61

Closed pkou0125 closed 6 months ago

pkou0125 commented 1 year ago

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

smuellerDD commented 1 year ago

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