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