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

2021-03-10 Thread Matt Caswell




On 10/03/2021 12:08, Stephen Farrell wrote:

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


For X25519 you can actually pass a groupname of "x25519" through if you 
want to keep everything consistent. But it's not strictly necessary 
since that is the only group supported by that keytype.


Matt



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

2021-03-10 Thread Stephen Farrell


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 +
+++ test2evp2.c    2021-03-10 09:03:47.258657721 +
@@ -29,6 +29,7 @@
  #include 

  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,);
+    rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,npubbuf,npublen,);
  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,);
+    rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,NULL,0,);
  if (rv==1) {
  printf("P-256 with just private key worked\n");
  } else {
@@ -183,7 +184,7 @@
  }
  

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

2021-03-10 Thread Matt Caswell




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.


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 +
+++ test2evp2.c 2021-03-10 09:03:47.258657721 +
@@ -29,6 +29,7 @@
 #include 

 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,);
+rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,npubbuf,npublen,);
 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,);
+rv=bufs2evp("EC","P-256",nprivbuf,nprivlen,NULL,0,);
 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,);
+rv=bufs2evp("X25519",NULL,xprivbuf,xprivlen,xpubbuf,xpublen,);
 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,);
+rv=bufs2evp("X25519",NULL,xprivbuf,xprivlen,NULL,0,);
 if (rv==1) {
 printf("X25519 with just private key worked\n");
   

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

2021-03-09 Thread Tomas Mraz
On Wed, 2021-03-10 at 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:-)

Not sure if there are any other issues, but the public key parameter
should be "encoded-pub-key" AFAIK.

Tomas Mraz




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

2021-03-09 Thread Stephen Farrell


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:-)

Cheers,
S.

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


OpenPGP_0x5AB2FAF17B172BEA.asc
Description: application/pgp-keys


OpenPGP_signature
Description: OpenPGP digital signature


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

2021-03-09 Thread Stephen Farrell


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.


Will check it out some more, tidy the code up and get back
later/tomorrow,

Cheers,
S.


OpenPGP_0x5AB2FAF17B172BEA.asc
Description: application/pgp-keys


OpenPGP_signature
Description: OpenPGP digital signature


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

2021-03-08 Thread Benjamin Kaduk via openssl-users
On Tue, Mar 09, 2021 at 02:44:20AM +, Stephen Farrell wrote:
> 
> Hiya,
> 
> On 08/03/2021 02:37, Benjamin Kaduk wrote:
> > Hi Stephen :)
> > 
> > The API you'll want to use is EVP_PKEY_fromdata(); there's
> > a stubbed out example of using it to make an EVP_PKEY with
> > EC group parameters at
> > https://github.com/openssl/openssl/issues/14258#issuecomment-783351031
> > but the translation to also specify OSSL_PKEY_PARAM_PRIV_KEY
> > (and possibly OSSL_PKEY_PARAM_PUB_KEY; I forget if you need
> > to pass both) should be fairly straightforward.
> 
> Thanks for that! I worked around a few things and still need
> to tidy-up but got things working that way without any more
> deprecation warnings.
> 
> > 
> > Let us know if you run into trouble with that route.
> 
> One outstanding issue is that I still need different code
> paths for NIST curves vs. 25519 & 448 - is that just me
> (quite likely:-) or should these new APIs hide differences
> between those different curves?

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.


-Ben


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

2021-03-08 Thread Stephen Farrell


Hiya,

On 08/03/2021 02:37, Benjamin Kaduk wrote:

Hi Stephen :)

The API you'll want to use is EVP_PKEY_fromdata(); there's
a stubbed out example of using it to make an EVP_PKEY with
EC group parameters at
https://github.com/openssl/openssl/issues/14258#issuecomment-783351031
but the translation to also specify OSSL_PKEY_PARAM_PRIV_KEY
(and possibly OSSL_PKEY_PARAM_PUB_KEY; I forget if you need
to pass both) should be fairly straightforward.


Thanks for that! I worked around a few things and still need
to tidy-up but got things working that way without any more
deprecation warnings.



Let us know if you run into trouble with that route.


One outstanding issue is that I still need different code
paths for NIST curves vs. 25519 & 448 - is that just me
(quite likely:-) or should these new APIs hide differences
between those different curves?

Thanks again,
S.




-Ben

On Mon, Mar 08, 2021 at 02:23:36AM +, Stephen Farrell wrote:


Hiya,

My question: how does one setup an EVP_PKEY for a NIST
curve (e.g. p256) key pair when one has the private key
in an octet string using the latest OpenSSL 3.0.0 high
level APIs?

I'm trying to get rid of deprecation warnings from my
code for HPKE [1] when dealing with NIST curves using
the new (I guess?) OSSL_PARAM_* approach. I'm failing
at the moment;-)

So, given an octet string from a set of test vectors
(e.g. [2]) what's the proper way to setup an EVP_PKEY
for that to allow one to validate the test vectors?

Happy to try produce a stand-alone example for this
in the next few days if one doesn't exist (I've not
found one so far).

Thanks,
Stephen.

[1] 
https://github.com/sftcd/happykey/blob/7d52d34c516ab58ca1433004ff82b2a6a82eea4c/hpke.c#L1263
[2] https://github.com/cfrg/draft-irtf-cfrg-hpke


pub   RSA 4096/7B172BEA 2017-12-22 Stephen Farrell (2017) 


sub   RSA 4096/36CB8BB6 2017-12-22







OpenPGP_0x5AB2FAF17B172BEA.asc
Description: application/pgp-keys


OpenPGP_signature
Description: OpenPGP digital signature


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

2021-03-07 Thread Benjamin Kaduk via openssl-users
Hi Stephen :)

The API you'll want to use is EVP_PKEY_fromdata(); there's
a stubbed out example of using it to make an EVP_PKEY with
EC group parameters at
https://github.com/openssl/openssl/issues/14258#issuecomment-783351031
but the translation to also specify OSSL_PKEY_PARAM_PRIV_KEY
(and possibly OSSL_PKEY_PARAM_PUB_KEY; I forget if you need
to pass both) should be fairly straightforward.

Let us know if you run into trouble with that route.

-Ben

On Mon, Mar 08, 2021 at 02:23:36AM +, Stephen Farrell wrote:
> 
> Hiya,
> 
> My question: how does one setup an EVP_PKEY for a NIST
> curve (e.g. p256) key pair when one has the private key
> in an octet string using the latest OpenSSL 3.0.0 high
> level APIs?
> 
> I'm trying to get rid of deprecation warnings from my
> code for HPKE [1] when dealing with NIST curves using
> the new (I guess?) OSSL_PARAM_* approach. I'm failing
> at the moment;-)
> 
> So, given an octet string from a set of test vectors
> (e.g. [2]) what's the proper way to setup an EVP_PKEY
> for that to allow one to validate the test vectors?
> 
> Happy to try produce a stand-alone example for this
> in the next few days if one doesn't exist (I've not
> found one so far).
> 
> Thanks,
> Stephen.
> 
> [1] 
> https://github.com/sftcd/happykey/blob/7d52d34c516ab58ca1433004ff82b2a6a82eea4c/hpke.c#L1263
> [2] https://github.com/cfrg/draft-irtf-cfrg-hpke

pub   RSA 4096/7B172BEA 2017-12-22 Stephen Farrell (2017) 

> sub   RSA 4096/36CB8BB6 2017-12-22
> 





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

2021-03-07 Thread Stephen Farrell


Hiya,

My question: how does one setup an EVP_PKEY for a NIST
curve (e.g. p256) key pair when one has the private key
in an octet string using the latest OpenSSL 3.0.0 high
level APIs?

I'm trying to get rid of deprecation warnings from my
code for HPKE [1] when dealing with NIST curves using
the new (I guess?) OSSL_PARAM_* approach. I'm failing
at the moment;-)

So, given an octet string from a set of test vectors
(e.g. [2]) what's the proper way to setup an EVP_PKEY
for that to allow one to validate the test vectors?

Happy to try produce a stand-alone example for this
in the next few days if one doesn't exist (I've not
found one so far).

Thanks,
Stephen.

[1] 
https://github.com/sftcd/happykey/blob/7d52d34c516ab58ca1433004ff82b2a6a82eea4c/hpke.c#L1263

[2] https://github.com/cfrg/draft-irtf-cfrg-hpke


OpenPGP_0x5AB2FAF17B172BEA.asc
Description: application/pgp-keys


OpenPGP_signature
Description: OpenPGP digital signature