OpenSSL 3.0.0 APIs for creating an EVP_PKEY from a p256 private key octet string

Stephen Farrell stephen.farrell at cs.tcd.ie
Wed Mar 10 12:08:09 UTC 2021


Thanks Matt,

On 10/03/2021 09:12, Matt Caswell wrote:
> 
> 
> On 10/03/2021 00:53, Stephen Farrell wrote:
>>
>> Hiya,
>>
>> On 09/03/2021 03:09, Benjamin Kaduk wrote:
>>> I would have expected that the API should hide the differences
>>> other than the group name ... but these APIs are still pretty
>>> new to me, too.  If you can point me at your code I might have
>>> more to say.
>>
>> So again it's probably my fault but I'm still not seeing the
>> same behaviour for NIST and non-NIST curves. I made up what
>> I hope is a fairly simple bit of test code [1] so that might
>> help clarify where I'm wrong or (less likely) where a change
>> in the library might be useful.
>>
>> As I build the test code, the p256 cases seem to work, with
>> or without the public key, but both 25519 cases fail. In my
>> (still untidy:-) HPKE code EVP_PKEY_new_raw_private_key
>> for the non-NIST curves works, but not for NIST curves. So I
>> have an ok workaround, even if the fault's not mine, which
>> it of course probably is:-)
> 
> Hi Stephen
> 
> There are two important things to understand that your code was not 
> quite handling correctly:
> 
> 1) X25519/X448/ED25519/ED448 are treated as different key types to 
> "traditional" EC. They really are very different things: different OIDs, 
> different standards, different file formats, different key formats etc. 
> So while the "traditional" EC curves have the key type "EC", we have 
> separate key types of "X25519", "X448", "ED25519" and "ED448"
> 
> 2) The type of the parameters is dependent on the key type. So a private 
> key in "EC" is an integer. But a private key for "X25519" is an octet 
> string.

I had tried all those, but not in the right combination,
so thanks! My test code works now with your changes. (It's
still at [1] and feel free to use as an example if that's
useful.)

It seems a pity that one has to special case in two ways
there (both keytype and groupname) but I can live with it,

Thanks again,
S.

[1] https://github.com/sftcd/happykey/blob/master/test2evp.c

> 
> Refer to:
> 
> https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-EC.html
> https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-X25519.html
> 
> 
> I made these changes to your test code to get it to work:
> 
> $ diff -u test2evp.c test2evp2.c
> --- test2evp.c    2021-03-10 08:47:59.467451154 +0000
> +++ test2evp2.c    2021-03-10 09:03:47.258657721 +0000
> @@ -29,6 +29,7 @@
>   #include <openssl/core_names.h>
> 
>   int bufs2evp(
> +        const char *keytype,
>           char *groupname,
>           unsigned char *privbuf, size_t privbuflen,
>           unsigned char *pubuf, size_t pubuflen,
> @@ -41,38 +42,38 @@
>       OSSL_PARAM_BLD *param_bld=NULL;;
>       OSSL_PARAM *params = NULL;
> 
> -    priv = BN_bin2bn(privbuf, privbuflen, NULL);
> -    if (!priv) {
> -        erv=__LINE__; goto err;
> -    }
>       param_bld = OSSL_PARAM_BLD_new();
>       if (!param_bld) {
>           erv=__LINE__; goto err;
>       }
>       if (pubuf && pubuflen>0) {
> -        if (OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", 
> groupname,0)!=1) {
> -            erv=__LINE__; goto err;
> -        }
> -        if (OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)!=1) {
> -            erv=__LINE__; goto err;
> -        }
>           if (OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", pubuf, 
> pubuflen)!=1) {
>               erv=__LINE__; goto err;
>           }
>           params = OSSL_PARAM_BLD_to_param(param_bld);
> -    } else {
> -        if (OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", 
> groupname,0)!=1) {
> +    }
> +    if (groupname != NULL && OSSL_PARAM_BLD_push_utf8_string(param_bld, 
> "group", groupname,0)!=1) {
> +        erv=__LINE__; goto err;
> +    }
> +    if (strcmp(keytype, "EC") == 0) {
> +        priv = BN_bin2bn(privbuf, privbuflen, NULL);
> +        if (!priv) {
>               erv=__LINE__; goto err;
> -        }
> +        }
>           if (OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)!=1) {
>               erv=__LINE__; goto err;
>           }
> -        params = OSSL_PARAM_BLD_to_param(param_bld);
> +    } else {
> +        if (OSSL_PARAM_BLD_push_octet_string(param_bld, "priv", 
> privbuf, privbuflen)!=1) {
> +            erv=__LINE__; goto err;
> +        }
>       }
> +    params = OSSL_PARAM_BLD_to_param(param_bld);
> +
>       if (!params) {
>           erv=__LINE__; goto err;
>       }
> -    ctx = EVP_PKEY_CTX_new_from_name(NULL,"EC", NULL);
> +    ctx = EVP_PKEY_CTX_new_from_name(NULL,keytype, NULL);
>       if (ctx == NULL) {
>           erv=__LINE__; goto err;
>       }
> @@ -167,7 +168,7 @@
>        * First do a p-256 one that works, then an x25519 one that does not.
>        */
> 
> -    rv=bufs2evp("P-256",nprivbuf,nprivlen,npubbuf,npublen,&retkey);
> +    rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,npubbuf,npublen,&retkey);
>       if (rv==1) {
>           printf("P-256 with key pair worked\n");
>       } else {
> @@ -175,7 +176,7 @@
>       }
>       EVP_PKEY_free(retkey);retkey=NULL;
> 
> -    rv=bufs2evp("P-256",nprivbuf,nprivlen,NULL,0,&retkey);
> +    rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,NULL,0,&retkey);
>       if (rv==1) {
>           printf("P-256 with just private key worked\n");
>       } else {
> @@ -183,7 +184,7 @@
>       }
>       EVP_PKEY_free(retkey);retkey=NULL;
> 
> -    rv=bufs2evp("X25519",xprivbuf,xprivlen,xpubbuf,xpublen,&retkey);
> +    rv=bufs2evp("X25519",NULL,xprivbuf,xprivlen,xpubbuf,xpublen,&retkey);
>       if (rv==1) {
>           printf("X25519 with key pair worked\n");
>       } else {
> @@ -191,7 +192,7 @@
>       }
>       EVP_PKEY_free(retkey);retkey=NULL;
> 
> -    rv=bufs2evp("X25519",xprivbuf,xprivlen,NULL,0,&retkey);
> +    rv=bufs2evp("X25519",NULL,xprivbuf,xprivlen,NULL,0,&retkey);
>       if (rv==1) {
>           printf("X25519 with just private key worked\n");
>       } else {
> 
> 
> Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x5AB2FAF17B172BEA.asc
Type: application/pgp-keys
Size: 10689 bytes
Desc: not available
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20210310/6dd0af58/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20210310/6dd0af58/attachment.sig>


More information about the openssl-users mailing list