Running SHA1 with the mmcau on a K61 device

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Running SHA1 with the mmcau on a K61 device

Jump to solution
1,425 Views
francoismace
Contributor II

Hello,

 

I am currently writing a linux (µcLinux) driver for the mmcau cryptographic unit present on my K61 device.

I have currently successfuly ported the AES, DES and MD5 functions using the cau_api.h and assembly file but I am running into some issues with the SHA1 function.

 

Basically, what I am doing is writing some binding code to replace the native crypto functions of linux with the ones accessing the mmcau unit.

For the moment, I validate the behavior with the internal tests run by linux when it loads the kernel driver accessing to the funcion (here SHA1) of the mmcau driver.

The code for the driver is in attachment (kinetis_mmcau_sha1.c)

 

Linux passes its first test (validating the hash for a message containing "abc"), but it crashes during the second message.

This second message is "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".

 

What I can see is, for that test, two passes shall be done with the cau_sha1_update function.

- 1. Actual hash of the message + some part of the padding (only 64 bits out of the 512 which are necessary for the initial message length of 448 bits).

- 2. The rest of the padding + the 64 bits of the message length.

 

This is summarized in the attchment MMCAU_SHA1_Test2_Debug_info.txt.


Using a Python reference sofware, I could get access to the intermediate state value that I shall be producing after the 1st 512 bits block of data has been processed.

I can therefore see that this first pass is ok. (the output of the python script is attached for reference too: MMCAU_SHA1_Test2_pythonOutput.txt)

 

The main issue seems to be produced with the second pass (the reminder of the padding data + data length).

I tried several things (amongst which changing the endianess of the state values - since I got to do it in the end to present the data according to the big endian specification of SHA1 while the data produced by cau_sha1_update are little endian) but it does not solve the issue. Strangely enough though, when I do change the endianess of the state value, the result produced by cau_sha1_update is actually similar to the one without the change of endianess of the previous state variables, except for the endianess.

I have attached the output produced by the driver for both cases as an illustration.

 

I must confess the behavior is quite confusing and has been keeping me busy for quite a while now.

I would therefore appreciate if you could help me on this.

 

Best regards,

 

Francois

Original Attachment has been moved to: MMCAU_SHA1_Test2_driverDebugOut_OrigEndian.txt.zip

Original Attachment has been moved to: MMCAU_SHA1_Test2_pythonOuptut.txt.zip

Original Attachment has been moved to: MMCAU_SHA1_Test2_Debug_info.txt.zip

Original Attachment has been moved to: kinetis_mmcau_sha1.c.txt.zip

Original Attachment has been moved to: MMCAU_SHA1_Test2_driverDebugOut_ModEndian.txt.zip

Tags (3)
1 Solution
864 Views
melissa_hunter
NXP Employee
NXP Employee

Hi Francois,

The way we have the functions defined doesn't line up exactly with the Linux calls. We don't have any functions that include the padding. Any time you are sending the last (or only) block to be hashed to the mmCAU it needs to be padded by your software before you send it to the mmCAU.

The cau_shax_hash functions are used if you only need to hash a single block and the init function must be called first. So I don't think it is that useful.

The cau_shax_hash_n is what you should use for what you are doing. To use that function you must call cau_shax_init first, then you can call cau_shax_hash_n as many times as needed in your update function, then in your final routine you'll need to pad the last block and then you can call your update function or just call the cau_shax_hash_n directly from your final routine.

Regards,

Melissa

View solution in original post

5 Replies
864 Views
francoismace
Contributor II

Hello,

As additional information:

- The cau_api.h file is marked with a release date 12/19/2013

- The mmcau_sha1_functions.S is marked release 1.3 from Jan 8 2011 at 01:26:39 (rzsx60 experimental)

- I did exactly the same work (actually reusing my sha1 file and changing it to accomodate the specificities of SHA-256), and, this time it works without an issue ...

I hope this helps to pinpoint a potential issue in my integration ...

0 Kudos
864 Views
melissa_hunter
NXP Employee
NXP Employee

Hi Francois,

Here is an app note on using the mmCAU that I think you might find helpful:

http://cache.freescale.com/files/32bit/doc/app_note/AN4307.pdf

If you look in the "Lab and Test Software" section on this page you can find the software:

Flexis 32-bit V1 ColdFire USB Microcontroller|Freescale

I modified the software to add your example as one of the SHA-1 test cases and verified I got the right result. Here is a screenshot from the debuggerresult.png

I've highlighted the padded value that was passed into the cau_sha1_update function in the memory window at the bottom of the screen. Then in the locals window you can see the result.

Hope this helps,

Melissa

0 Kudos
864 Views
francoismace
Contributor II

Hello Melissa,

Thank you for your reply.

I took a look at it and went foreward with the implementation of my driver on SHA256 too.

While the structure of both drivers are pretty similar, I made one slight "mistake" that pushed me foreward.

Instead of using the cau_sha256_update function, I used the cau_sha256_hash function. I compiled the driver and it went through the automated test of the linux crypto driver without a problem. I did the same correction for the sha1 driver and my problem was solved.

Strangely enough, it seem the the cau_shaX_update functions perform more than updating the state variable while the cau_shaX_hash functions do just that.

I will explain myself a little bit more.

The linux crypto driver have standard functions which, while using a HW coprocessor (or acceleration unit) driver, get redefined so that the kernel utilities calling the linux crypto driver can benefit from the acceleration of the HW coprocessor or acceleration unit. In the particular case of hash functions or digest algorithms, these functions are init, update and final, the 1st one taking care of initializing the state data, the second of updating the state data (which means that, for a large message this function is actually called several times) and the last takes care of the padding and calls back the update function to get the final value of the hash/digest.

In my initial implementation, since the definition given in "CAU and mmCAU API User Guide (revision 2.3)", states that the cau_shaX_update functions definitions state: "SHAX: Updates SHAX state variables for one or more input message blocks arguments", I used those in my update function redefinition, while I figured (from the name and from the definitions of cau_shaX_hash "SHAX: Performs SHAX hash algorithm on a single input message block") that the other function could perform the full hash algorithm and possibly take care themselve of the padding.

It however seems to be the inverse.

Could you please confirm that?

Thanks in advance,

François

0 Kudos
865 Views
melissa_hunter
NXP Employee
NXP Employee

Hi Francois,

The way we have the functions defined doesn't line up exactly with the Linux calls. We don't have any functions that include the padding. Any time you are sending the last (or only) block to be hashed to the mmCAU it needs to be padded by your software before you send it to the mmCAU.

The cau_shax_hash functions are used if you only need to hash a single block and the init function must be called first. So I don't think it is that useful.

The cau_shax_hash_n is what you should use for what you are doing. To use that function you must call cau_shax_init first, then you can call cau_shax_hash_n as many times as needed in your update function, then in your final routine you'll need to pad the last block and then you can call your update function or just call the cau_shax_hash_n directly from your final routine.

Regards,

Melissa

864 Views
francoismace
Contributor II

Hello Melissa,

I guess that this confirms what I thought then.

Thank you for your replies and for the support.

Best regards,

Francois

0 Kudos