<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
</head>
<body style="font-family: 'Segoe UI',Frutiger,'Frutiger Linotype','Dejavu Sans','Helvetica Neue',Arial,sans-serif; font-size: 14px;">
<div class="hiri-body-wrapper" contenteditable="true">
<div>Hi Jussi,<br>
<br>
No problem and thanks for coming back on my email.<br>
<br>
You are right - "all KCV algorithms I managed to find encrypt zero input block with the actual key as key" - except cases where the key is a weak key. While this might sound ridiculous there are many cases like this - in production as well as in test environments.
 E.g. Thales HSM default-load key-set works with some weak keys and while doing symmetric crypto we need to support those as well (in testing / dev environments Thales HSM is almost always loaded with a default key set so crypto can be reproduced and validated).<br>
<br>
Hope it makes better sense now.<br>
<br>
Cheers,<br>
Jan<br>
 </div>
</div>
<div class="hiri-signature-wrapper" contenteditable="true">
<div style="font-family: "Segoe UI", Arial, sans-serif; background-color: rgb(255, 255, 255);">
On 2020-01-06 00:36:19+10:00 Jussi Kivilinna wrote:</div>
</div>
 
<div class="hiri-extra-edited" contenteditable="true">
<blockquote style="padding-left:10px; border-left:1px solid #ccc; margin:0">
<div>
<pre class="hiri-plaintext-quote">Hello,

Apparently my first reply went only to the mailing list.

There I wrote: "I tried to find KCV specification where zero key is used to encrypt actual key as input block for KCV value, but all KCV algorithms I managed to find encrypt zero input block with the actual key as key. Can you check your documentation for KCV if zero key is really used and give pointer/link to that spec for us?"

-Jussi

On 4.1.2020 12.33, Jan Bilek wrote:
&amp;gt; Ping?
&amp;gt; &amp;nbsp;
&amp;gt; 
&amp;gt; On 2019-12-21 11:40:06+10:00 Jan Bilek wrote:
&amp;gt; 
&amp;gt;     Hi,
&amp;gt; 
&amp;gt;     We have a problem here where I need to encrypt a block of data with zeros.
&amp;gt; 
&amp;gt;     &amp;lt;&amp;gt;
&amp;gt;     &amp;nbsp;&amp;nbsp;gcry_check_version (NULL);
&amp;gt;     &amp;nbsp; unsigned char key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
&amp;gt;     &amp;nbsp; unsigned char out[8];
&amp;gt;     &amp;nbsp; unsigned char data[8];
&amp;gt;     &amp;nbsp; gcry_error_t err = 0;
&amp;gt;     &amp;nbsp; gcry_cipher_hd_t hd = nullptr;
&amp;gt;     &amp;nbsp; err = gcry_cipher_open(&amp;amp;hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
&amp;gt;     &amp;nbsp; //auto blklen = gcry_cipher_get_algo_blklen(GCRY_CIPHER_DES);
&amp;gt;     &amp;nbsp; //auto algolen = gcry_cipher_get_algo_keylen (GCRY_CIPHER_DES);
&amp;gt;     &amp;nbsp; err = gcry_cipher_setkey (hd, key, sizeof(key));
&amp;gt;     &amp;nbsp; std::cerr &amp;lt;&amp;lt; "gpg_err_code: " &amp;lt;&amp;lt; gpg_err_code(err) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; std::cerr &amp;lt;&amp;lt; "gpg_strerror: " &amp;lt;&amp;lt; gpg_strerror(err) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; gcry_cipher_encrypt(hd, out, sizeof(key), data, 8);
&amp;gt;     &amp;nbsp; if (err) {
&amp;gt;     &amp;nbsp; &amp;nbsp; std::cerr &amp;lt;&amp;lt; "Failed to perform cryptography" &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; &amp;nbsp; std::cerr &amp;lt;&amp;lt; " &amp;nbsp;cipher: &amp;nbsp; &amp;nbsp; " &amp;lt;&amp;lt; static_cast&lt;int&gt;(GCRY_CIPHER_DES) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; &amp;nbsp; std::cerr &amp;lt;&amp;lt; " &amp;nbsp;mode: &amp;nbsp; &amp;nbsp; &amp;nbsp; " &amp;lt;&amp;lt; static_cast&lt;int&gt;(GCRY_CIPHER_MODE_ECB) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; &amp;nbsp; //std::cerr &amp;lt;&amp;lt; " &amp;nbsp;keyBlock: &amp;nbsp; " &amp;lt;&amp;lt; BinToHex&lt;std::string&gt;(key) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; &amp;nbsp; //std::cerr &amp;lt;&amp;lt; " &amp;nbsp;out: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;" &amp;lt;&amp;lt; BinToHex&lt;std::string&gt;(out) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; &amp;nbsp; //std::cerr &amp;lt;&amp;lt; " &amp;nbsp;data: &amp;nbsp; &amp;nbsp; &amp;nbsp; " &amp;lt;&amp;lt; BinToHex&lt;std::string&gt;(encryptedData) &amp;lt;&amp;lt; std::endl;
&amp;gt;     &amp;nbsp; }
&amp;gt;     
&amp;gt; 
&amp;gt;     This blows on:
&amp;gt; 
&amp;gt;     gpg_err_code: 43
&amp;gt;     gpg_strerror: Weak encryption key
&amp;gt;     cipher_encrypt: key not set
&amp;gt; 
&amp;gt;     Tracked back t&amp;nbsp;in a source&amp;nbsp;to libcrypt / cipher / des.c
&amp;gt; 
&amp;gt;     r. 1384&amp;nbsp;do_des_setkey
&amp;gt;     r. 1021 is_weak_key
&amp;gt; 
&amp;gt;     &amp;nbsp;&amp;nbsp;if (is_weak_key (key)) {
&amp;gt;     &amp;nbsp; &amp;nbsp; _gcry_burn_stack (64);
&amp;gt;     &amp;nbsp; &amp;nbsp; return GPG_ERR_WEAK_KEY;
&amp;gt;     &amp;nbsp; }
&amp;gt; 
&amp;gt;     cipher.c
&amp;gt;     r.797&amp;nbsp;
&amp;gt; 
&amp;gt;     &amp;nbsp;rc = c-&amp;gt;spec-&amp;gt;setkey (&amp;amp;c-&amp;gt;context.c, key, keylen, c);
&amp;gt;     &amp;nbsp; if (!rc) {
&amp;gt; 
&amp;gt;     &amp;nbsp;&amp;nbsp;} else
&amp;gt;     &amp;nbsp; &amp;nbsp; c-&amp;gt;marks.key = 0;
&amp;gt;     &amp;nbsp;
&amp;gt;     ... then disallows weak key setting completely, resulting in a failure.
&amp;gt; 
&amp;gt;     This has quite an impact on multiple (still) in-use KCV operations (e.g. KCV_METHOD_VISA) where key needs to be encrypted with a zero key to get its KCV.
&amp;gt; 
&amp;gt;     May I propose a patch? (See in attachment).
&amp;gt; 
&amp;gt;     Thanks &amp;amp; Cheers,
&amp;gt;     Jan
&amp;gt; 
&amp;gt; 
&amp;gt; _______________________________________________
&amp;gt; Gcrypt-devel mailing list
&amp;gt; Gcrypt-devel@gnupg.org
&amp;gt; http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
&amp;gt; 

&lt;/std::string&gt;&lt;/std::string&gt;&lt;/std::string&gt;&lt;/int&gt;&lt;/int&gt;</pre>
</div>
</blockquote>
</div>
</body>
</html>