[openssl-users] EVP_PKEY_set1_EC_KEY seems to not set something that EVP_PKEY_derive needs

Ethan Rahn ethan.rahn at gmail.com
Sat Mar 11 18:38:14 UTC 2017


Hey Matt,

I'm using openssl-1.0.2j to do this.

After a lot of debugging and poking around, I realized that my initial
thoughts were not quite correct. Somewhere in trying to come up with an
example, I noticed that the problem actually appears to be the buffer I am
passing in..

If I use a char array, it will fail to derive the shared secret, if I use a
char* it will succeed. I'm not quite sure what is going on there, but I
have some code below that shows the issue:

static int deriveSharedSecret( EVP_PKEY *pkey, EVP_PKEY *peerkey,
                               char *sharedSecretHex ){
   /*
    * Generalized function to derive shared secret and return the hex
format of it.
    */
   unsigned char sharedSecret[ 4096 ] = {0};
   size_t sharedSecretLen = 0;

   // Now derive the Shared Secret
   EVP_PKEY_CTX *ctx;

   ctx = EVP_PKEY_CTX_new(pkey, NULL);
   if (!ctx){
      fprintf( stderr, "Failed to make EVP_PKEY ctx\n" );
      ERR_load_crypto_strings();
      ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
      return 0;
   }
   if (EVP_PKEY_derive_init(ctx) <= 0){
      fprintf( stderr, "Failed to init EVP_PKEY ctx\n" );
      ERR_load_crypto_strings();
      ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
      return 0;
   }
   if (EVP_PKEY_derive_set_peer(ctx, peerkey) <= 0) {
      fprintf( stderr, "Failed to set EVP_PKEY peer\n" );
      ERR_load_crypto_strings();
      ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
      return 0;
   }

   int secretLen = 2048;
   unsigned char *skey;

   /* Create the buffer */
   if(NULL == (skey = OPENSSL_malloc(secretLen))){
      fprintf( stderr, "Failed to malloc buffer for secret\n" );
      return;
   }

   /* Derive the shared secret */
   if(1 != (EVP_PKEY_derive(ctx, skey, &secretLen))){
      fprintf( stderr, "Failed to derive secret and place into buffer\n" );
      return;
   } else {
      fprintf( stderr, "Found the darn secret!\n" );
   }
   if (EVP_PKEY_derive(ctx, sharedSecret, &sharedSecretLen) <= 0){
      fprintf( stderr, "Failed to derive shared secret\n" );
      ERR_load_crypto_strings();
      ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
      return 0;
   } else {
      fprintf( stderr, "FOUND IT!!!!!\n" );
   }

   bin2hex( sharedSecret, sharedSecretHex, sharedSecretLen );
   return 1;
}



On Fri, Mar 10, 2017 at 1:44 PM, Matt Caswell <matt at openssl.org> wrote:

>
>
> On 10/03/17 20:58, Ethan Rahn wrote:
> > Hello Openssl-users,
> >
> > I'm trying to write some code that derives the shared secret for 2
> > elliptic curve keys ( i.e. does ECDH )
> >
> > I am doing the following to load up both the local and remote EC key (
> > code shown for local side ):
> >
> > EC_KEY* localEC = EC_KEY_new_by_curve_name( curveName );
> > EC_KEY_set_private_key( localEC, privateKeyLocal )
> > EC_KEY_set_public_key_affine_coordinates( localEC, publicXCoordLocal,
> > publicYCoordLocal )
> >
> > I check the return values for all of these, as well as EC_KEY_check_key
> > at the end. Everything returns non-zero, so I assume that it is good to
> > go. I then do the following to turn the EC_KEY into an EVP_PKEY for ECDH:
> >
> > pkey = EVP_PKEY_new();
> > EVP_PKEY_set1_EC_KEY( *pkey, localEC );
> >
> > The same is done for the remote EC, except that the private key is not
> > loaded up.
> >
> > Now this is where things get weird.
> >
> > I run code pretty similar to the example given here ( starting from
> > EVP_PKEY_CTX_new() since I already have the pkey and peerkey. (
> > https://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman ) and
> > it fails on the call to EVP_PKEY_derive()without an error message. I
> > tried running into under gdb() and it gets to ecdh_check() before it's
> > unable to fill in the ecdh_data structure, i.e. it returns it as NULL.
> >
> > If I use the example code to generate the local EVP_PKEY with a random
> > set of points on the correct curve, then run the following line, the key
> > derivation will work with the parameters I read in:
> > ( in this example, pkey is as in the example code, i.e. generated
> > randomly. pkey2 is the one I made via EVP_PKEY_set1_EC_KEY )
> >
> > EVP_PKEY_set1_EC_KEY( pkey, EVP_PKEY_get1_EC_KEY( pkey2 ) );
> >
> > It would appear that there is something that EVP_PKEY_set1_EC_KEY is not
> > setting, or perhaps that I need to add, but I'm unclear what that would
> > be. Does anyone on this list have any ideas?
>
> Which version of OpenSSL are you using?
>
> Can you provide a simple reproducer of the problem?
>
> Matt
>
> --
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20170311/f7b0d1e0/attachment.html>


More information about the openssl-users mailing list