RE: Can someone check linux kernel 4.4, and 4.9 rfc4309 test vectors?

2017-06-09 Thread Che-Min Hsieh
Thanks.
Yes, in the new kernel, the association data passing in to the driver, the last 
8 bytes of data should be excluded in the driver.
The conversion from rfc4309 test vectors defined in the testmgr.h should drop 
the last 8 bytes of data before passing to the openSSL API as association data. 
After I did that, things match.


-Original Message-
From: Harsh Jain [mailto:harshjain.p...@gmail.com] 
Sent: Friday, June 9, 2017 2:31 AM
To: Che-Min Hsieh <chem...@qti.qualcomm.com>
Cc: linux-crypto@vger.kernel.org; Zhen Kong <zk...@quicinc.com>; Dan Bronstein 
<dbron...@qti.qualcomm.com>
Subject: Re: Can someone check linux kernel 4.4, and 4.9 rfc4309 test vectors?

On Wed, Jun 7, 2017 at 7:27 PM, Che-Min Hsieh <chem...@qti.qualcomm.com> wrote:
> Rfc4309 test vectors in testmgr.h have gone through major changes from linux3 
>  to linux4.
> In linux 4.4, linux4.9, there are vectors as such
>
> 23194 static struct aead_testvec aes_ccm_rfc4309_enc_tv_template[] = {
> 23195{ /* Generated using Crypto++ */
> 23196.key   = zeroed_string,
> 23197.klen  = 19,
> 23198.iv   = zeroed_string,
> 23199.input= zeroed_string,
> 23200.ilen   = 16,
> 23201.assoc= zeroed_string,
> 23202.alen  = 16,
> 23203.result   = "\x2E\x9A\xCA\x6B\xDA\x54\xFC\x6F"
> 23204  "\x12\x50\xE8\xDE\x81\x3C\x63\x08"
> 23205  "\x1A\x22\xBA\x75\xEE\xD4\xD5\xB5"
> 23206  "\x27\x50\x01\xAC\x03\x33\x39\xFB",
> 23207.rlen   = 32,
>
>
> I have a test program using open ssl API (-l crypto), and run on Ubuntu Linux 
> PC,   I  get the following  test result:
>
> 2e 9a ca 6b da 54 fc 6f 12 50 e8 de 81 3c 63 08 fb 64 91 b4 dd dc bf 
> 5d fd 67 e3 a2 f8 7c 0e 6c
>   The first part of encrypted text is correct. But MAC is not the 
> same.
>
> My program is as the following:
>
> void ccmTest()
> {
> /* Initialization */
> EVP_CIPHER_CTX ctx;
> EVP_CIPHER_CTX *cryptCtx = 
> EVP_CIPHER_CTX_init(cryptCtx);
> int i;
>
>unsigned char P[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
> int Psize = sizeof(P);
> unsigned char K[16] = {0};
> unsigned char N[11] = {0};
> unsigned char A[16] = {0};
> unsigned char CT[128];
>
> int Nsize = 11;
> int Tsize = 16;
>
> // Initialize the context with the alg only
> EVP_EncryptInit(cryptCtx, EVP_aes_128_ccm(), 0, 0);
>
> // Set nonce and tag sizes
> EVP_CIPHER_CTX_ctrl(cryptCtx, EVP_CTRL_CCM_SET_IVLEN, Nsize, 0);
> EVP_CIPHER_CTX_ctrl(cryptCtx, EVP_CTRL_CCM_SET_TAG, Tsize, 0);
>
> // Finally set the key and the nonce
> EVP_EncryptInit(cryptCtx, 0, K, N);
>
> // Tell the alg we will encrypt Psize bytes
> int outl = 0;
> EVP_EncryptUpdate(cryptCtx, 0, , 0, sizeof(P));
>// Add the AAD
> EVP_EncryptUpdate(cryptCtx, 0, , A, sizeof(A));
>// Now we encrypt the data in P, placing the output in CT
> EVP_EncryptUpdate(cryptCtx, CT, , P, Psize);
> EVP_EncryptFinal(cryptCtx, [outl], );
> // Append the tag to the end of the encrypted output
> EVP_CIPHER_CTX_ctrl(cryptCtx, EVP_CTRL_CCM_GET_TAG, Tsize, [Psize]);
> hexdump(CT, Tsize+Psize);
> }
>
>
> I run "insmod tcrypt.ko mode=45"  rfc4309 test with Qualcomm crypto hardware 
> on Linux4.4. The test fails. The generated output is the same as my openSSL 
> test application in 1.
Older kernel driver also includes IV in Authentication data.  Thats why MAC is 
wrong . 4.4 kernel crypto drivers don't need to include IV in authentication 
data. Updating driver not to include IV string in authentication data for 
latest kernels should work.
>
> My test application runs on Ubuntu with linux 3.10 rfc4309 test vector, and 
> generated MAC as expected from test vectors.  Qualcomm crypto hardware runs 
> "insmod tcrypt.ko mode=45" successfully with linux 3.10.
>
> I am suspicious about the test vectors of 4.4. Can someone verify the Linux 
> 4.4 rfc4309 test vectors with his/her openSSL application on PC?
>
> Chemin


Re: Can someone check linux kernel 4.4, and 4.9 rfc4309 test vectors?

2017-06-09 Thread Harsh Jain
On Wed, Jun 7, 2017 at 7:27 PM, Che-Min Hsieh  wrote:
> Rfc4309 test vectors in testmgr.h have gone through major changes from linux3 
>  to linux4.
> In linux 4.4, linux4.9, there are vectors as such
>
> 23194 static struct aead_testvec aes_ccm_rfc4309_enc_tv_template[] = {
> 23195{ /* Generated using Crypto++ */
> 23196.key   = zeroed_string,
> 23197.klen  = 19,
> 23198.iv   = zeroed_string,
> 23199.input= zeroed_string,
> 23200.ilen   = 16,
> 23201.assoc= zeroed_string,
> 23202.alen  = 16,
> 23203.result   = "\x2E\x9A\xCA\x6B\xDA\x54\xFC\x6F"
> 23204  "\x12\x50\xE8\xDE\x81\x3C\x63\x08"
> 23205  "\x1A\x22\xBA\x75\xEE\xD4\xD5\xB5"
> 23206  "\x27\x50\x01\xAC\x03\x33\x39\xFB",
> 23207.rlen   = 32,
>
>
> I have a test program using open ssl API (-l crypto), and run on Ubuntu Linux 
> PC,   I  get the following  test result:
>
> 2e 9a ca 6b da 54 fc 6f 12 50 e8 de 81 3c 63 08
> fb 64 91 b4 dd dc bf 5d fd 67 e3 a2 f8 7c 0e 6c
>   The first part of encrypted text is correct. But MAC is not the 
> same.
>
> My program is as the following:
>
> void ccmTest()
> {
> /* Initialization */
> EVP_CIPHER_CTX ctx;
> EVP_CIPHER_CTX *cryptCtx = 
> EVP_CIPHER_CTX_init(cryptCtx);
> int i;
>
>unsigned char P[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
> int Psize = sizeof(P);
> unsigned char K[16] = {0};
> unsigned char N[11] = {0};
> unsigned char A[16] = {0};
> unsigned char CT[128];
>
> int Nsize = 11;
> int Tsize = 16;
>
> // Initialize the context with the alg only
> EVP_EncryptInit(cryptCtx, EVP_aes_128_ccm(), 0, 0);
>
> // Set nonce and tag sizes
> EVP_CIPHER_CTX_ctrl(cryptCtx, EVP_CTRL_CCM_SET_IVLEN, Nsize, 0);
> EVP_CIPHER_CTX_ctrl(cryptCtx, EVP_CTRL_CCM_SET_TAG, Tsize, 0);
>
> // Finally set the key and the nonce
> EVP_EncryptInit(cryptCtx, 0, K, N);
>
> // Tell the alg we will encrypt Psize bytes
> int outl = 0;
> EVP_EncryptUpdate(cryptCtx, 0, , 0, sizeof(P));
>// Add the AAD
> EVP_EncryptUpdate(cryptCtx, 0, , A, sizeof(A));
>// Now we encrypt the data in P, placing the output in CT
> EVP_EncryptUpdate(cryptCtx, CT, , P, Psize);
> EVP_EncryptFinal(cryptCtx, [outl], );
> // Append the tag to the end of the encrypted output
> EVP_CIPHER_CTX_ctrl(cryptCtx, EVP_CTRL_CCM_GET_TAG, Tsize, [Psize]);
> hexdump(CT, Tsize+Psize);
> }
>
>
> I run "insmod tcrypt.ko mode=45"  rfc4309 test with Qualcomm crypto hardware 
> on Linux4.4. The test fails. The generated output is the same as my openSSL 
> test application in 1.
Older kernel driver also includes IV in Authentication data.  Thats
why MAC is wrong . 4.4 kernel crypto drivers don't need to include IV
in authentication data. Updating driver not to include IV string in
authentication data for latest kernels should work.
>
> My test application runs on Ubuntu with linux 3.10 rfc4309 test vector, and 
> generated MAC as expected from test vectors.  Qualcomm crypto hardware runs 
> "insmod tcrypt.ko mode=45" successfully with linux 3.10.
>
> I am suspicious about the test vectors of 4.4. Can someone verify the Linux 
> 4.4 rfc4309 test vectors with his/her openSSL application on PC?
>
> Chemin


Re: Can someone check linux kernel 4.4, and 4.9 rfc4309 test vectors?

2017-06-07 Thread Stephan Müller
Am Mittwoch, 7. Juni 2017, 15:57:31 CEST schrieb Che-Min Hsieh:

Hi Che,

> Rfc4309 test vectors in testmgr.h have gone through major changes from
> linux3  to linux4. In linux 4.4, linux4.9, there are vectors as such

I think you and the kernel implement crypto properly. It is just the 
formatting that you do not get right.

See crypto/ccm.c:

static struct aead_request *crypto_rfc4309_crypt(struct aead_request *req)
{
...
scatterwalk_map_and_copy(iv + 16, req->src, 0, req->assoclen - 8, 0);
...

The key is how to understand the input data format. RFC4309 CCM is no cipher 
implementation, but rather a special formatting of the CCM input data.

In your code, change the following line

>// Add the AAD
> EVP_EncryptUpdate(cryptCtx, 0, , A, sizeof(A));

to

EVP_EncryptUpdate(cryptCtx, 0, , A, sizeof(A) - 8);

and you will see consistent results.

Ciao
Stephan