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