Migrating low level ec APIs from openssl1.1.1 to openssl3.0.7 high level EVP APIs

Tomas Mraz tomas at openssl.org
Thu Mar 30 16:46:01 UTC 2023


I do not see any issue with the pubkey import.

With the same private key and the same peer pubkey the computed shared
key should be exactly the same - if you drop the eciesKeyDerivationFn
from the legacy implementation it should produce the same shared key as
the new implementation.

Tomas Mraz

On Thu, 2023-03-30 at 21:56 +0530, Vishal Patil wrote:
> Thanks Tomas for pointing that out,  I have tried calling SHA512 on
> raw envelope however issue still persists.
> 
> I suspect public key import has issues. Could you please check if all
> necessary evp routines and parameters are present to get the public
> key from octet data?
> 
> Thanks 
> 
> On Thu, 30 Mar 2023, 12:20 Tomas Mraz, <tomas at openssl.org> wrote:
> > In the legacy method you've supplied the eciesKeyDerivationFn
> > function
> > to the ECDH_compute_key() which is applied after the raw shared
> > secret
> > from the ECDH is computed. The EVP_PKEY_derive() does not do that.
> > Do
> > not be confused with the KDF parameters - they apply only to the
> > X9.63
> > KDF if enabled but that is most probably a completely different KDF
> > from what you implement in the eciesKeyDerivationFn.
> > 
> > However that is no problem, you can just apply the
> > eciesKeyDerivationFn
> > on the output of the ECDH yourself. This is how the KDF is called
> > in
> > ECDH_compute_key():
> > https://github.com/openssl/openssl/blob/master/crypto/ec/ec_kmeth.c#L168
> > 
> > Tomas Mraz, OpenSSL
> > 
> > On Thu, 2023-03-30 at 01:30 +0530, Vishal Patil wrote:
> > > We are having some troubles converting some code from OpenSSL
> > > 1.1.x
> > > to OpenSSL 
> > > 3.0.7 APIs, to get rid of deprecation warnings, and hope someone
> > > may
> > > be able to 
> > > give us some hints in the right direction.
> > > 
> > > 
> > > Part1:  We are encrypting some text file with openssl3 commands 
> > > and extracting public part(ephdata) of provate key and appending
> > > it
> > > to encryptedfile.
> > > All openssl operations done using openssl(version 3.0.7) commands
> > > in
> > > bash script.
> > > 
> > > openssl ecparam -name secp521r1 -genkey -noout -out ephpri.pem
> > > openssl pkeyutl -derive -inkey ephpri.pem -peerkey ecpubkey.pem -
> > > out
> > > derive.bin
> > > ENVELOPE=$(openssl dgst -sha512 derive.bin | awk '{print $2}')
> > > AESKEY=$(echo $ENVELOPE | cut -c1-64)
> > > AESIV=$(echo $ENVELOPE | cut -c65-96)
> > > echo "AESKEY = $AESKEY"
> > > echo "AESIV  = $AESIV"
> > > # encrypt file.txt
> > > openssl enc -e -aes-256-ctr -in file.txt -out file.enc -K $AESKEY
> > > -iv
> > > $AESIV
> > > 
> > > #extract and append pub part of private-key
> > > # export public data of the ephemeral key
> > > openssl ec -in ephpri.pem -pubout -out ephdata.tmp -outform DER -
> > > conv_form compressed
> > > OFFSET=$(openssl asn1parse -inform DER -in ephdata.tmp | grep
> > > "BIT
> > > STRING" | awk -F ':' '{print $1}' | awk '{print $1}')
> > > OFFSET=$(expr $OFFSET + 3)
> > > dd if=ephdata.tmp of=ephdata bs=$OFFSET count=1024 skip=1
> > > append_file file.enc ephdata
> > > 
> > > Part2: We are processing the encrypted file on other peer using
> > > application which uses openssl3 APIs.
> > > 1) extraction of ephdata(pub part of key in part1) from encrypted
> > > file.
> > > 2) preparing public key from ephdata 
> > > 3) prearing hash using own private key and derived public key
> > > 4) deriving of AES keys from hash and decrypting encrypted file
> > > using
> > > the same.
> > > 
> > > Low level APIs: ( part2 decryption succeeds):
> > > 
> > > group = EC_GROUP_new_by_curve_name(NID_secp521r1);
> > > EC_GROUP_precompute_mult(group, nullptr)
> > > EC_GROUP_set_point_conversion_form(group,
> > > POINT_CONVERSION_COMPRESSED);
> > > 
> > > publicKey  = EC_KEY_new();
> > > EC_KEY_set_group(key, group)
> > > point = EC_POINT_new(group);
> > > EC_POINT_oct2point(group, point, data, length, nullptr)  // data
> > > is
> > > ephdata - derived in part1 
> > > EC_KEY_set_public_key( publicKey  , point)
> > > EC_POINT_free(point);
> > > EC_KEY_check_key( publicKey  ) // key is public key derived from
> > > ephdata
> > > 
> > > ECDH_compute_key(envelope,
> > >                          SHA512_DIGEST_LENGTH,
> > >                          EC_KEY_get0_public_key(publicKey),
> > >                          privateKey,
> > >                          eciesKeyDerivationFn)
> > > -----------------------------------------------------------------
> > > ----
> > > -----------------------------------------------------------------
> > > 
> > > Replaced with high level APIs ( part2 decryption fails) :
> > >    
> > > // ctx setting with named curve
> > >  nid = NID_secp521r1;
> > >     pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
> > >     EVP_PKEY_keygen_init(pctx)
> > >     EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid)
> > >     params[0] = OSSL_PARAM_construct_utf8_string("point-format",
> > > compressionState, 0);
> > >     params[1] = OSSL_PARAM_construct_end();
> > >     EVP_PKEY_CTX_set_params(pctx, params)
> > > 
> > > // public key derivation from pubdata from peer
> > >    dctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)
> > >    EVP_PKEY_fromdata_init(dctx)
> > >     //param struct for fromdata
> > >     OSSL_PARAM params[4];
> > >     char *secp521r1 = (char *)"secp521r1";
> > >     params[0] = OSSL_PARAM_construct_octet_string("pub", (void *)
> > > data, length);
> > >     params[1] = OSSL_PARAM_construct_utf8_string("group",
> > > secp521r1,
> > > 0);
> > >     char *compressionState = (char *)"compressed";
> > >     params[2] = OSSL_PARAM_construct_utf8_string("point-format",
> > > compressionState, 0);
> > >     params[3] = OSSL_PARAM_construct_end();
> > >     EVP_PKEY * public_key = nullptr;
> > >     EVP_PKEY_fromdata(dctx, &public_key   , EVP_PKEY_PUBLIC_KEY,
> > > params) 
> > > 
> > > // hash/envelope derivation 
> > > dctx = EVP_PKEY_CTX_new_from_pkey(NULL, d->privateKey, NULL);
> > > EVP_PKEY_derive_init(dctx)
> > > OSSL_PARAM params[4];
> > > unsigned int padding = 1;
> > > params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD,
> > > &padding);
> > > params[1] =
> > > OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
> > >                         (char*)"sha512", 0);
> > > params[2] =
> > > OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
> > >                         &length);
> > > params[3] = OSSL_PARAM_construct_end();
> > > EVP_PKEY_CTX_set_params(dctx, params)
> > > EVP_PKEY_derive_set_peer(dctx, publicKey)
> > > EVP_PKEY_derive(dctx, envelope, &length)
> > > 
> > > 
> > > Issue:
> > > If part2 application uses high level APIs, decryption of the file
> > > fails.
> > > However if part2 application uses low level APIs ( deprecated in
> > > openssl3) decryption succeeds.
> > > Issue could be either in publickey derivation from ephdata or
> > > hash.
> > > 
> > > 
> > > Thanks,
> > > 
> > 

-- 
Tomáš Mráz, OpenSSL



More information about the openssl-users mailing list