<div dir="ltr"><div dir="auto"><div>Thanks Tomas.</div><div dir="auto">The imported publicKey from octet data doesn't seem to be complete in new implementation ( I tried printing pem key in both cases after import)</div><div dir="auto">In New implementation key is exactly same as input octet data.</div><div>however in old implementation (using low level APIs) public key derived from octet data has some more contents along with input octet data.</div><div><br></div><div>----------------------------------------------------------------------------------------------------------<br></div><div>New implementation(high level APIs):</div><div>In importPublicKey , length=67, data= </div><div>3 0 cc e1 74 f0 ae 79 95 bc 39 62 6d 20 9a b9 88 8c c0 f1 d1 ae 77 44 f4 8f 65 52 25 2c 49 b9 5e 77 af 79 8a d cb a 93 b3 3d 37 b8 8d 4c 71 a6 78 2c 5f c0 52 15 8b 96 c1 5c 0 a4 25 41 a1 8 4d 59<br><br>key print(high APIs)...<br> Public-Key: (521 bit)<br> pub:<br>     03:00:cc:e1:74:f0:ae:79:95:bc:39:62:6d:20:9a:<br>     b9:88:8c:c0:f1:d1:ae:77:44:f4:8f:65:52:25:2c:<br>     49:b9:5e:77:af:79:8a:0d:cb:0a:93:b3:3d:37:b8:<br>     8d:4c:71:a6:78:2c:5f:c0:52:15:8b:96:c1:5c:00:<br>     a4:25:41:a1:08:4d:59<br></div>----------------------------------------------------------------------------------------------------------<div><br></div><div>Old implementation (low level APIs):</div><div>In importPublicKey , length=67, data= </div><div>2 1 37 88 37 3a 5e 21 19 fe 1 5d 9b 4f 4d 5c 7 7d c4 72 ae 1b 9f 5a 7b 1a 22 9c 21 f cf a5 c3 a9 94 20 e5 8c 72 55 25 6d a8 eb 1c ac d8 d7 12 6b 76 29 f2 ee 2 2f d6 1f e3 b1 20 2a 21 4 98 a1 a5<br></div><div><br></div><div>key print...                                                                                                                                                                     </div><div>Public-Key: (521 bit)                                                                                                                                                                   </div><div>pub:<br></div><div>04:0<b>1:37:88:37:3a:5e:21:19:fe:01:5d:9b:4f:4d:                                                                                                                                            5c:07:7d:c4:72:ae:1b:9f:5a:7b:1a:22:9c:21:0f:                                                                                                                                            cf:a5:c3:a9:94:20:e5:8c:72:55:25:6d:a8:eb:1c:                                                                                                                                            ac:d8:d7:12:6b:76:29:f2:ee:02:2f:d6:1f:e3:b1:                                                                                                                                            20:2a:21:04:98:a1:a5:01:dc:b9:90:ce:1e:14:bb:                                                                                                                                            7d:18:9f:e6:da:ae:03:7d:ca:22:f3:b5:4a:0a:ef:                                                                                                                                            e1:82:a5:</b>a1:61:c2:3a:b1:f8:82:bb:d7:6c:7f:ce:                                                                                                                                            05:e5:26:36:94:0f:d1:ff:17:87:44:a0:45:83:8f:                                                                                                                                           </div><div> d8:bc:b8:e8:88:c2:d4:22:6e:8e:2d:db:b8<br></div><div><br></div><div dir="auto"><div dir="auto"><div>If you notice then in old implementation public key has more data appended along with input octet.</div><div>And I think this is what missing in my new implementation, all the OSSL params being set basically not having any impact on deriving the key.</div></div><div dir="auto"><br></div><div dir="auto"><br></div>Regards,</div><div dir="auto">Vishal<br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Thu, 30 Mar 2023, 22:16 Tomas Mraz, <<a href="mailto:tomas@openssl.org" rel="noreferrer" target="_blank">tomas@openssl.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I do not see any issue with the pubkey import.<br>
<br>
With the same private key and the same peer pubkey the computed shared<br>
key should be exactly the same - if you drop the eciesKeyDerivationFn<br>
from the legacy implementation it should produce the same shared key as<br>
the new implementation.<br>
<br>
Tomas Mraz<br>
<br>
On Thu, 2023-03-30 at 21:56 +0530, Vishal Patil wrote:<br>
> Thanks Tomas for pointing that out,  I have tried calling SHA512 on<br>
> raw envelope however issue still persists.<br>
> <br>
> I suspect public key import has issues. Could you please check if all<br>
> necessary evp routines and parameters are present to get the public<br>
> key from octet data?<br>
> <br>
> Thanks <br>
> <br>
> On Thu, 30 Mar 2023, 12:20 Tomas Mraz, <<a href="mailto:tomas@openssl.org" rel="noreferrer noreferrer" target="_blank">tomas@openssl.org</a>> wrote:<br>
> > In the legacy method you've supplied the eciesKeyDerivationFn<br>
> > function<br>
> > to the ECDH_compute_key() which is applied after the raw shared<br>
> > secret<br>
> > from the ECDH is computed. The EVP_PKEY_derive() does not do that.<br>
> > Do<br>
> > not be confused with the KDF parameters - they apply only to the<br>
> > X9.63<br>
> > KDF if enabled but that is most probably a completely different KDF<br>
> > from what you implement in the eciesKeyDerivationFn.<br>
> > <br>
> > However that is no problem, you can just apply the<br>
> > eciesKeyDerivationFn<br>
> > on the output of the ECDH yourself. This is how the KDF is called<br>
> > in<br>
> > ECDH_compute_key():<br>
> > <a href="https://github.com/openssl/openssl/blob/master/crypto/ec/ec_kmeth.c#L168" rel="noreferrer noreferrer noreferrer" target="_blank">https://github.com/openssl/openssl/blob/master/crypto/ec/ec_kmeth.c#L168</a><br>
> > <br>
> > Tomas Mraz, OpenSSL<br>
> > <br>
> > On Thu, 2023-03-30 at 01:30 +0530, Vishal Patil wrote:<br>
> > > We are having some troubles converting some code from OpenSSL<br>
> > > 1.1.x<br>
> > > to OpenSSL <br>
> > > 3.0.7 APIs, to get rid of deprecation warnings, and hope someone<br>
> > > may<br>
> > > be able to <br>
> > > give us some hints in the right direction.<br>
> > > <br>
> > > <br>
> > > Part1:  We are encrypting some text file with openssl3 commands <br>
> > > and extracting public part(ephdata) of provate key and appending<br>
> > > it<br>
> > > to encryptedfile.<br>
> > > All openssl operations done using openssl(version 3.0.7) commands<br>
> > > in<br>
> > > bash script.<br>
> > > <br>
> > > openssl ecparam -name secp521r1 -genkey -noout -out ephpri.pem<br>
> > > openssl pkeyutl -derive -inkey ephpri.pem -peerkey ecpubkey.pem -<br>
> > > out<br>
> > > derive.bin<br>
> > > ENVELOPE=$(openssl dgst -sha512 derive.bin | awk '{print $2}')<br>
> > > AESKEY=$(echo $ENVELOPE | cut -c1-64)<br>
> > > AESIV=$(echo $ENVELOPE | cut -c65-96)<br>
> > > echo "AESKEY = $AESKEY"<br>
> > > echo "AESIV  = $AESIV"<br>
> > > # encrypt file.txt<br>
> > > openssl enc -e -aes-256-ctr -in file.txt -out file.enc -K $AESKEY<br>
> > > -iv<br>
> > > $AESIV<br>
> > > <br>
> > > #extract and append pub part of private-key<br>
> > > # export public data of the ephemeral key<br>
> > > openssl ec -in ephpri.pem -pubout -out ephdata.tmp -outform DER -<br>
> > > conv_form compressed<br>
> > > OFFSET=$(openssl asn1parse -inform DER -in ephdata.tmp | grep<br>
> > > "BIT<br>
> > > STRING" | awk -F ':' '{print $1}' | awk '{print $1}')<br>
> > > OFFSET=$(expr $OFFSET + 3)<br>
> > > dd if=ephdata.tmp of=ephdata bs=$OFFSET count=1024 skip=1<br>
> > > append_file file.enc ephdata<br>
> > > <br>
> > > Part2: We are processing the encrypted file on other peer using<br>
> > > application which uses openssl3 APIs.<br>
> > > 1) extraction of ephdata(pub part of key in part1) from encrypted<br>
> > > file.<br>
> > > 2) preparing public key from ephdata <br>
> > > 3) prearing hash using own private key and derived public key<br>
> > > 4) deriving of AES keys from hash and decrypting encrypted file<br>
> > > using<br>
> > > the same.<br>
> > > <br>
> > > Low level APIs: ( part2 decryption succeeds):<br>
> > > <br>
> > > group = EC_GROUP_new_by_curve_name(NID_secp521r1);<br>
> > > EC_GROUP_precompute_mult(group, nullptr)<br>
> > > EC_GROUP_set_point_conversion_form(group,<br>
> > > POINT_CONVERSION_COMPRESSED);<br>
> > > <br>
> > > publicKey  = EC_KEY_new();<br>
> > > EC_KEY_set_group(key, group)<br>
> > > point = EC_POINT_new(group);<br>
> > > EC_POINT_oct2point(group, point, data, length, nullptr)  // data<br>
> > > is<br>
> > > ephdata - derived in part1 <br>
> > > EC_KEY_set_public_key( publicKey  , point)<br>
> > > EC_POINT_free(point);<br>
> > > EC_KEY_check_key( publicKey  ) // key is public key derived from<br>
> > > ephdata<br>
> > > <br>
> > > ECDH_compute_key(envelope,<br>
> > >                          SHA512_DIGEST_LENGTH,<br>
> > >                          EC_KEY_get0_public_key(publicKey),<br>
> > >                          privateKey,<br>
> > >                          eciesKeyDerivationFn)<br>
> > > -----------------------------------------------------------------<br>
> > > ----<br>
> > > -----------------------------------------------------------------<br>
> > > <br>
> > > Replaced with high level APIs ( part2 decryption fails) :<br>
> > >    <br>
> > > // ctx setting with named curve<br>
> > >  nid = NID_secp521r1;<br>
> > >     pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);<br>
> > >     EVP_PKEY_keygen_init(pctx)<br>
> > >     EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid)<br>
> > >     params[0] = OSSL_PARAM_construct_utf8_string("point-format",<br>
> > > compressionState, 0);<br>
> > >     params[1] = OSSL_PARAM_construct_end();<br>
> > >     EVP_PKEY_CTX_set_params(pctx, params)<br>
> > > <br>
> > > // public key derivation from pubdata from peer<br>
> > >    dctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)<br>
> > >    EVP_PKEY_fromdata_init(dctx)<br>
> > >     //param struct for fromdata<br>
> > >     OSSL_PARAM params[4];<br>
> > >     char *secp521r1 = (char *)"secp521r1";<br>
> > >     params[0] = OSSL_PARAM_construct_octet_string("pub", (void *)<br>
> > > data, length);<br>
> > >     params[1] = OSSL_PARAM_construct_utf8_string("group",<br>
> > > secp521r1,<br>
> > > 0);<br>
> > >     char *compressionState = (char *)"compressed";<br>
> > >     params[2] = OSSL_PARAM_construct_utf8_string("point-format",<br>
> > > compressionState, 0);<br>
> > >     params[3] = OSSL_PARAM_construct_end();<br>
> > >     EVP_PKEY * public_key = nullptr;<br>
> > >     EVP_PKEY_fromdata(dctx, &public_key   , EVP_PKEY_PUBLIC_KEY,<br>
> > > params) <br>
> > > <br>
> > > // hash/envelope derivation <br>
> > > dctx = EVP_PKEY_CTX_new_from_pkey(NULL, d->privateKey, NULL);<br>
> > > EVP_PKEY_derive_init(dctx)<br>
> > > OSSL_PARAM params[4];<br>
> > > unsigned int padding = 1;<br>
> > > params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD,<br>
> > > &padding);<br>
> > > params[1] =<br>
> > > OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,<br>
> > >                         (char*)"sha512", 0);<br>
> > > params[2] =<br>
> > > OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,<br>
> > >                         &length);<br>
> > > params[3] = OSSL_PARAM_construct_end();<br>
> > > EVP_PKEY_CTX_set_params(dctx, params)<br>
> > > EVP_PKEY_derive_set_peer(dctx, publicKey)<br>
> > > EVP_PKEY_derive(dctx, envelope, &length)<br>
> > > <br>
> > > <br>
> > > Issue:<br>
> > > If part2 application uses high level APIs, decryption of the file<br>
> > > fails.<br>
> > > However if part2 application uses low level APIs ( deprecated in<br>
> > > openssl3) decryption succeeds.<br>
> > > Issue could be either in publickey derivation from ephdata or<br>
> > > hash.<br>
> > > <br>
> > > <br>
> > > Thanks,<br>
> > > <br>
> > <br>
<br>
-- <br>
Tomáš Mráz, OpenSSL<br>
<br>
</blockquote></div>
</div></div>
</div>