<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
Hi guys,<br>
I have to implement the ECIES scheme as specified at
<a class="moz-txt-link-freetext" href="https://wiki.plugtests.net/ITS-CMS6/images/4/4a/1609.2-consolidated-v4-d8-clean.pdf">https://wiki.plugtests.net/ITS-CMS6/images/4/4a/1609.2-consolidated-v4-d8-clean.pdf</a>
paragraph 5.3.5, with the KDF and encryption function specified here
<a class="moz-txt-link-freetext" href="https://www.etsi.org/deliver/etsi_ts/102900_102999/102941/01.03.01_60/ts_102941v010301p.pdf">https://www.etsi.org/deliver/etsi_ts/102900_102999/102941/01.03.01_60/ts_102941v010301p.pdf</a>
at annex E.<br>
<br>
I wrote an implementation, but the HMAC seems to be wrong.<br>
Here I compute the shared secret and the HMAC value with:
<div style="color: #d4d4d4;background-color: #1e1e1e;font-family: 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;"><div><span style="color: #6a9955;"> // Computing shared secret using ECSVDP-DHC</span><span style="color: #d4d4d4;">
</span><div style="color: #d4d4d4;background-color: #1e1e1e;font-family: 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;"><div><span style="color: #dcdcaa;"> EC_KEY_set_flags</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">osslEphKey</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">EC_FLAG_COFACTOR_ECDH</span><span style="color: #d4d4d4;">);</span><span style="color: #d4d4d4;"></span></div></div></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">ECDH_compute_key</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">K</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">sizeof</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">K</span><span style="color: #d4d4d4;">), </span><span style="color: #9cdcfe;">osslEncPubKey</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">osslEphKey</span><span style="color: #d4d4d4;">, &(</span><span style="color: #569cd6;">this</span><span style="color: #d4d4d4;">-></span><span style="color: #dcdcaa;">etsiKdf</span><span style="color: #d4d4d4;">));</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">free</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">osslEncPubKey</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">free</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">osslEphKey</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #6a9955;"> // Setting Ke value (the left-most 16 byte of K)</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">std</span><span style="color: #d4d4d4;">::</span><span style="color: #dcdcaa;">memcpy</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">Ke</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">K</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">Ke_KEY_LENGTH</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #6a9955;"> // Setting Km value (the remaining 256 bits of K)</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">memcpy</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">Km</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">K</span><span style="color: #d4d4d4;">+</span><span style="color: #9cdcfe;">Ke_KEY_LENGTH</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">Km_KEY_LENGTH</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #6a9955;"> /* Encrypting "aesKey": C = aesKey XOR Ke */</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">for</span><span style="color: #d4d4d4;">(</span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">i</span><span style="color: #d4d4d4;">=</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">; </span><span style="color: #9cdcfe;">i</span><span style="color: #d4d4d4;"><</span><span style="color: #9cdcfe;">AES_KEY_SIZE</span><span style="color: #d4d4d4;">; </span><span style="color: #9cdcfe;">i</span><span style="color: #d4d4d4;">++) {</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">C</span><span style="color: #d4d4d4;">[</span><span style="color: #9cdcfe;">i</span><span style="color: #d4d4d4;">] = </span><span style="color: #9cdcfe;">aesKeyBuffer</span><span style="color: #dcdcaa;">[</span><span style="color: #9cdcfe;">i</span><span style="color: #dcdcaa;">]</span><span style="color: #d4d4d4;"> ^ </span><span style="color: #9cdcfe;">Ke</span><span style="color: #d4d4d4;">[</span><span style="color: #9cdcfe;">i</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #d4d4d4;"> }</span></div><div><span style="color: #6a9955;"> // Computing the tag with HMAC (we'll retain the leftmost 16 octets)</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (</span><span style="color: #dcdcaa;">HMAC</span><span style="color: #d4d4d4;">(</span><span style="color: #dcdcaa;">EVP_sha256</span><span style="color: #d4d4d4;">(), </span><span style="color: #9cdcfe;">Km</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">sizeof</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">Km</span><span style="color: #d4d4d4;">), </span><span style="color: #9cdcfe;">C</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">sizeof</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">C</span><span style="color: #d4d4d4;">), </span><span style="color: #9cdcfe;">hmacResult</span><span style="color: #d4d4d4;">, &</span><span style="color: #9cdcfe;">hmacLength</span><span style="color: #d4d4d4;">) == </span><span style="color: #569cd6;">NULL</span><span style="color: #d4d4d4;">) {</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">throw</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">NoesCryptoException</span><span style="color: #d4d4d4;"> (</span><span style="color: #ce9178;">"Cannot perform HMAC"</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> }</span></div></div>
<br>
Here :<br>
"osslEncPubKey" and "osslEphKey" are, respectively, the
encryption public key of receiver and the just created ephemeral
key;<br>
"K" is a byte array containing the result of KDF function;<br>
"Ke" and "Km" the keys used to compute the other encrypted or
signed parts;<br>
"aesKeyBuffer" a byte array containing the AES key used to
encrypt with AES-CCM;<br>
<br>
The "etsiKdf" function called by ECDH_compute_key is:<br>
<div style="color: #d4d4d4;background-color: #1e1e1e;font-family: 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback';font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;"><div><span style="color: #569cd6;">void*</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">noes</span><span style="color: #d4d4d4;">::</span><span style="color: #4ec9b0;">securityManager</span><span style="color: #d4d4d4;">::</span><span style="color: #4ec9b0;">NoesCrypto</span><span style="color: #d4d4d4;">::</span><span style="color: #dcdcaa;">etsiKdf</span><span style="color: #d4d4d4;"> (</span><span style="color: #569cd6;">const</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">void*</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">in</span><span style="color: #d4d4d4;">, </span><span style="color: #4ec9b0;">size_t</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">inLength</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">void*</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">out</span><span style="color: #d4d4d4;">, </span><span style="color: #4ec9b0;">size_t</span><span style="color: #569cd6;">*</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">outLength</span><span style="color: #d4d4d4;">) {</span><span style="color: #6a9955;"> // TODO FIXME Check me</span></div><div><span style="color: #6a9955;"> /* counter 1..2^32</span></div><div><span style="color: #6a9955;"> * CB=big endian counter on 32 bits</span></div><div><span style="color: #6a9955;"> * SHA256(in||CB)</span></div><div><span style="color: #6a9955;"> * counter++, and we do again while we need to generate stream</span></div><div><span style="color: #6a9955;"> */</span></div><div><span style="color: #d4d4d4;"> </span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">void</span><span style="color: #d4d4d4;"> *</span><span style="color: #9cdcfe;">ret</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">NULL</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">counter</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">unsigned</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">char</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">4</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">unsigned</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">char</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">HB</span><span style="color: #d4d4d4;">[</span><span style="color: #569cd6;">EVP_MAX_MD_SIZE</span><span style="color: #d4d4d4;">];</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">unsigned</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">HB_len</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">int</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">outputedlen</span><span style="color: #d4d4d4;"> = </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">,</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;"> = *</span><span style="color: #9cdcfe;">outLength</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">EVP_MD_CTX</span><span style="color: #d4d4d4;"> *</span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">NULL</span><span style="color: #d4d4d4;">;</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;"> = </span><span style="color: #569cd6;">EVP_MD_CTX_create</span><span style="color: #d4d4d4;">();</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">while</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;"> > </span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">) {</span></div><div><span style="color: #6a9955;"> // counter++</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">] = </span><span style="color: #9cdcfe;">counter</span><span style="color: #d4d4d4;"> >> </span><span style="color: #b5cea8;">24</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">] = (</span><span style="color: #9cdcfe;">counter</span><span style="color: #d4d4d4;"> >> </span><span style="color: #b5cea8;">16</span><span style="color: #d4d4d4;">) & </span><span style="color: #b5cea8;">0xff</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">2</span><span style="color: #d4d4d4;">] = (</span><span style="color: #9cdcfe;">counter</span><span style="color: #d4d4d4;"> >> </span><span style="color: #b5cea8;">8</span><span style="color: #d4d4d4;">) & </span><span style="color: #b5cea8;">0xff</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">3</span><span style="color: #d4d4d4;">] = </span><span style="color: #9cdcfe;">counter</span><span style="color: #d4d4d4;"> & </span><span style="color: #b5cea8;">0xff</span><span style="color: #d4d4d4;">;</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">EVP_DigestInit_ex</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;">, </span><span style="color: #dcdcaa;">EVP_sha256</span><span style="color: #d4d4d4;">(), </span><span style="color: #569cd6;">NULL</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">EVP_DigestUpdate</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">in</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">inLength</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">EVP_DigestUpdate</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">, </span><span style="color: #569cd6;">sizeof</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">CB</span><span style="color: #d4d4d4;">));</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">EVP_DigestFinal_ex</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">HB</span><span style="color: #d4d4d4;">, &</span><span style="color: #9cdcfe;">HB_len</span><span style="color: #d4d4d4;">);</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> (</span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;"> > </span><span style="color: #9cdcfe;">HB_len</span><span style="color: #d4d4d4;">) {</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">memcpy</span><span style="color: #d4d4d4;">((</span><span style="color: #569cd6;">void</span><span style="color: #d4d4d4;">*)</span><span style="color: #9cdcfe;">out</span><span style="color: #d4d4d4;">+</span><span style="color: #9cdcfe;">outputedlen</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">HB</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">HB_len</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">outputedlen</span><span style="color: #d4d4d4;"> += </span><span style="color: #9cdcfe;">HB_len</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;"> -= </span><span style="color: #9cdcfe;">HB_len</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> }</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">else</span><span style="color: #d4d4d4;"> {</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">memcpy</span><span style="color: #d4d4d4;">((</span><span style="color: #569cd6;">void</span><span style="color: #d4d4d4;">*)</span><span style="color: #9cdcfe;">out</span><span style="color: #d4d4d4;">+</span><span style="color: #9cdcfe;">outputedlen</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">HB</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">outputedlen</span><span style="color: #d4d4d4;"> += </span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;"> -= </span><span style="color: #9cdcfe;">remains</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> }</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">counter</span><span style="color: #d4d4d4;">++;</span></div><div><span style="color: #d4d4d4;"> }</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">ret</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">out</span><span style="color: #d4d4d4;">;</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">std</span><span style="color: #d4d4d4;">::</span><span style="color: #9cdcfe;">cout</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;"><<</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">"</span><span style="color: #d7ba7d;">\n</span><span style="color: #ce9178;">KDF output length "</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;"><<</span><span style="color: #d4d4d4;"> *</span><span style="color: #9cdcfe;">outLength</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;"><<</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">std</span><span style="color: #d4d4d4;">::</span><span style="color: #dcdcaa;">endl</span><span style="color: #d4d4d4;">;</span></div>
<div><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">EVP_MD_CTX_destroy</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">ctx</span><span style="color: #d4d4d4;">);</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">return</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">ret</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;">}</span></div></div>
<br>
<br>
Can you help me to find the bug?<br>
<br>
Luca<br>
</body>
</html>