Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i2d_PublicKey() fails with -1 for DILITHIUM2 key while using OQS provider with OpenSSL 3.2.1 #562

Open
vk18anubhav opened this issue Nov 3, 2024 · 6 comments · May be fixed by #597
Open
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@vk18anubhav
Copy link

Discussed in https://github.com/orgs/open-quantum-safe/discussions/1968

Originally posted by vk18anubhav October 30, 2024
Hi Team,

I am generating a DILITHIUM2 key in my code using OpenSSL 3.2.1 by loading OQS provider as following

EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = (EVP_PKEY_CTX *)NULL;

pkey = EVP_PKEY_new();

ctx = EVP_PKEY_CTX_new_from_name(libctx, "dilithium2", NULL);

EVP_PKEY_keygen_init(ctx);

EVP_PKEY_keygen(ctx, &pkey);

While converting the key to DER format using i2d_PublicKey() , it fails with -1 while i2d_PrivateKey() succeeds.

len = i2d_PublicKey(pkey, NULL); // First call itself fails

if(len < buffer->len)
buffer->len = i2d_PublicKey(pkey, buffer); // This also fails 

I tried debugging the issue by putting breakpoints on i2d_PublicKey(), i2d_PrivateKey() and sharing observations

int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
{
    if (evp_pkey_is_provided(a)) {
        static const struct type_and_structure_st output_info[] = {
            { "DER", "type-specific" },
            { "blob", NULL },    /* for EC */
            { NULL, }
        };
 
        return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp);
    }

int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
{
    if (evp_pkey_is_provided(a)) {
        static const struct type_and_structure_st output_info[] = {
            { "DER", "type-specific" },
            { "DER", "PrivateKeyInfo" },
            { NULL, }
        };
 
        return i2d_provided(a, EVP_PKEY_KEYPAIR, output_info, pp);
    }

  • i2d_provided() calls OSSL_ENCODER_CTX_new_for_pkey(), OSSL_ENCODER_to_data() in loop for members of output_info
  • OSSL_ENCODER_CTX_new_for_pkey () was using oqsprovider for getting libctx
  • OSSL_ENCODER_to_data() returns doing nothing for output_type= DER, output_structure= "type-specific" for both private and public key.
  • OSSL_ENCODER_to_data() succeeds for next output_type= DER, output_structure= “PrivateKeyInfo" while it fails for output_type= blob, output_structure= NULL for public key and returns with -1

Can you please review on how I can resolve this ?

@SWilson4
Copy link
Member

SWilson4 commented Nov 4, 2024

I think this issue is better suited to oqs-provider—we don't implement any encoding logic in liboqs. Transferring it to that project.

@SWilson4 SWilson4 transferred this issue from open-quantum-safe/liboqs Nov 4, 2024
@baentsch
Copy link
Member

baentsch commented Nov 7, 2024

I am not seeing anything oqsprovider specific in this question: This should be asked in an OpenSSL forum (or maybe is an FAQ there). For validation, could you please use a non-PQ algorithm in your test code and see whether that works as you expect @vk18anubhav ?

@wbeck10
Copy link

wbeck10 commented Nov 11, 2024

The problem is missing encoder for type-specific key.
Using the OpenSSL API "i2d_PublicKey" with an created dilithium2 pkey will fail because a "der + type-specific" decoder will be queried in the OQSProvider but this encoder is not available.
I see in encode_key2any.c comment out type-specific encoder function like
key_to_type_specific_der_bio. It seems for some reason, this type-specific encoder was deactivated or work in progress?
It is important to be able to convert a pkey into a der hex string.

OpenSSL i2d_PublicKey has following code party:
int i2d_PublicKey(const EVP_PKEY *a, unsigned char *pp)
{
if (evp_pkey_is_provided(a)) {
static const struct type_and_structure_st output_info[] = {
{ "DER", "type-specific" },
{ "blob", NULL }, /
for EC */
{ NULL, }
};

    return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp);
}

...
}

@baentsch baentsch added enhancement New feature or request help wanted Extra attention is needed labels Nov 11, 2024
@baentsch
Copy link
Member

I see in encode_key2any.c comment out type-specific encoder function like
key_to_type_specific_der_bio.

Thanks for pointing this out, @wbeck10 . This completely escaped my attention and I wonder why the provider could be used for such a long time (this is 3 year old code) without anyone noticing. As I'm a bit pressed for time, tagging this issue asking the community for help (removing the comment, adding probably missing logic and tests).

@wbeck10p
Copy link

I might can help you out here.
I'm working on a commit to get this working.

@wbeck10
Copy link

wbeck10 commented Dec 18, 2024

Pull request created:
#596

@wbeck10 wbeck10 linked a pull request Dec 20, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
Status: Todo
5 participants