Hi all,
I'm new to IMX6.
I would like to develop a little application in c language which use the CAAM cryptographic hardware accelerator (CHA).
I've 2 main problem:
- I think I don't understand very well all concepts: job descriptor/trusted descriptor , job rings, shared descriptors, etc...
- I try to read some register (like MCFGR — Master Configuration Register for example) and it spawn an error.
I've read the Document Number: IMX6DQ6SDLSRM :
Security Reference Manual for i.MX6Dual, 6Quad, 6Solo, and 6DualLite Families of Applications Processors
but for beginning I would like a little application example. It's easier in order to understand the main idea.
As concerning the register reading,
I use this (simple) command in my c program :
#define reg32_read(addr) *((volatile uint_32_t *) (addr))
and in my program, when I call :
reg32_read(0x02100004); //0x02100004 : Master Configuration Register address
the program return me :
[1] + stopped (signal) ./caam_test
I don't understand the real problem.
Is it a right problem ?
Is their a register setting that I missed in order to read all registers?
How to read/write into register in order to use CHA of CAAM ?
Is there some code examples of AES ECB mode encryption using the CAAM ?
Please, could you help me please ? Any suggestions are welcome...
Thx
Please look at my comments below.
1.
You may look at the Platform SDK - it contains an example regarding blob using.
"The i.MX6 Platform SDK is located at:
Below is SDK link :
https://www.freescale.com/webapp/Download?colCode=i.MX6_PLATFORM_SDK&location=null
Summary page :
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX6Q&fpsp=1&tab=Design_Tools_Tab
2.
There is “sm_test.c” (Linux) example (located at "drivers/crypto/caam/sm_test.c")
for testing encapsulating and decapsulating of black keys.
3.
Also, please look at the enclosed example : simple job that will decrypt
a 1024-byte message using AES in CBC mode. I hope it helps.
[00] B080000F jobhdr: stidx=0 len=15
[01] 12200010 ld: ccb1-ctx len=16 offs=0
[02] 00000002 ptr->@0x225a84662
[03] 25A84662
[04] 02000010 key: class1-keyreg len=16
[05] 00000001 ptr->@0x1e767e1b5
[06] E767E1B5
[07] 8210010C operation: cls1-op aes cbc init-final dec
[08] 22120400 fifold: class1 msgdata-last1 len=1024
[09] 00000002 ptr->@0x23ab4850a
[10] 3AB4850A
[11] 60700000 fifostr: msgdata ext
[12] 00000004 ptr->@0x4de37d42c
[13] DE37D42C
[14] 00000400 extlen=1024
The steps involved are:
[01] Load the CBC IV into the Class 1 Context Register
[04] Load the 128-bit AES key into the Class 1 Key Register
[07] Configure the AESA CHA to decrypt with the CBC mode
[08] Read 1024 bytes of input data with the FIFO LOAD command. The data will be
directed to the Class 1 Alignment Block, and the 'last data' flag will be presented
along with the end of it.
[11] Store the deciphered data with the FIFO STORE command. The 'ext' flag means
that the length field in the first word is not used. Instead, the length comes after the
pointer. The class field value is not interpreted when data source/type is 'msgdata',
which means the OFIFO.
This is a good model for data encryption and decryption. If not all of the data is passed
through at once, but processing will continue in other job(s), it might be necessary to
store the context register as the last step of the descriptor. How many bytes to store is
dependent upon the algorithm and mode. This requirement will also affect the 'algorithm
state' value, as init-final is proper for a complete message. RC4 (the AFHA) has a
separate solution in this regard, as the 'context' is 258 bytes (256 bytes of key material of
the RC4 SBox and 1-byte each of the context pointers i and j).
Below are some details how to create a Black Key :
Load the desired key into a key register, (Class 1,Class2, PKHA E, or AFHA Sbox),
using the Key command with the NoWriteBack bit cleared, and then write out the
key register using the FIFO Store command.
The FIFO Store command OutputDataType field is used to specify the source of
the key, the encryption algorithm (AES-ECB or AES-CCM) and the KEK (either JDKEK
or TDKEK). Note that only a Trusted Descriptor may specify using the TDKEK for creating
a Black Key. Otherwise, an error will result.
A Black Key will be larger than a plaintext key. When using AES-CCM mode, the Black Key
will be 12 bytes longer than the plaintext key. Six of the extra bytes contain the nonce for
the Black Key, and the other six bytes contain a 48-bit integrity check tag. If the tag is
incorrect when a descriptor loads an AES-CCM Black Key, the descriptor will stop with an error.
When loading a Black Key into a key register using the Key command, the value
specified in the length field is the length of the plaintext key, not the size of the Black
Key buffer. When creating a Black Key using the FIFO Store command, the value in the
length field is the length of the plaintext key. The buffer must be large enough to hold the
encrypted key plus the additional padding.
Have a great day,
Yuri
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Yuri,
1.Can you provide descriptors for AES-CMAC ?
2.From the above code i changed the operation command, but i am not getting output... Can you help me with the changes i have to do to get CMAC?
3.Can i use same fifostore for CMAC as well or are we using store command(to take MAC from context register)?
I read the SRM for iMX6. Is there anything else i need to consider?
Kindly reply asap.
Best regards
Sreelakshmy M A
Hi Yuri,
0xB080000A,
0x12200010, /*Load IV*/
(uint32_t)init_vector,
0x02000010, /*Key*/
(uint32_t)key,
0x8210060C, /* CMAC*/
0x22120010, /*fifo load plain text*/
(uint32_t)plaintext,
0x52200010, /*store cipher text*/
(uint32_t)out_ptrr
I have tried with this descriptors for AES-CMAC....
i am getting this as answer(which is not the correct one)... There is no error detecting for CAAM...something is processing and i got this...
0x6b
0x4f
0x25
0x13
0x4b
0xa9
0xef
0xd0
0x52
0x46
0xfd
0x87
0x36
0xaa
0x9e
0x1f
What is wrong in my code?
Hello Yuri,
I got correct output with this descriptor... The test vector i used were wrong in the above scenario...
PS:Those who are beginners in CAAM try to use NIST test vectors...Don't depend upon any online AES, SHA calculators..
Thank you for the reply
Best regards
Sreelakshmy M A
Hi Yuri,
To give the address of plane text, key etc.., why you are using another descriptors 00000002,00000001,00000004 etc...?
Can we give the plane text and array like below?(AES-CBC encryption)
0x12200010,
(uint32_t)init_vector, ??
Can you tell me the mistake in my descriptor?
0xB080000A,
0x12200010, /*Load IV*/
(uint32_t)init_vector,
0x02000010, /*Key*/
(uint32_t)key,
0x8210010D,
0x22120010, /*plain text*/
(uint32_t)plaintext,
0x60300010, /*store cipher text*/
(uint32_t)out_ptr
For me what happening is ...I am getting an encrypted value and when i decrypt that cipher text i am getting plain text as well... but that cipher text is not same as in the test vectors...
Thanks in advance
Sreelakshmy M A
Hi Yuri,
I got output with the above descriptors.. It was some other problem in data arrays..
Best regards
Sreelakshmy M A
Hi Yuri,
First : Great thank you for your detailed explanation and links (that are not broken...)
But some little problems...
1- I don't find "drivers/crypto/caam/sm_test.c"file.. (neither in "/sdk/drivers" nor "/output/')
2- the detailed explanation of the code execution (in 3) is very interesting.
but where this code is located/loaded ? in which memory address ?
Is possible to write directly in memory/registers thanks to the code like this for example :
#define part1 B080000F;
#define part2 22 12200010;
#define part3 12 00000002;
#define part4 2225A84662;
#define part5 02000010;
#define part6 00000001;
#define part7 E767E1B5;
#define part8 8210010C;
#define part9 22120400;
#define part10 00000002;
#define part11 3AB4850A;
#define part12 60700000;
#define part13 00000004;
#define part14 DE37D42C;
#define part15 00000400;
uint32_t job_descriptor[] =
{
part1,
part2,
part3,
part4,
part5,
part6,
part7,
part8,
part9,
part10,
part11,
part12,
part13,
part14,
part15
};
Specify in job rings registers the address of this job descriptor ?
and run the job, read the result ?
In other words, can I do the work myself, without using the SDK ? writing directly the value of registers ?
But which registers must I set up to do this simple work... ?
3- when I've built the SDK. All built file are in "/output" directory.
there are no directory for my boards : (SabreLite or RioTboard...)
And when I load and test every sdk_unit_test_caam.elf or sdk_unit_test_caam.bin it return an error...
CAAM register configuration is not the same for all mx6dq processor ?
I'm still stuck...
I hope read you soon,
Julien.
Julien, good day !
I should clarify that, the items in my previous reply relate to fully
different approaches. The first (Platform SDK) is stand alone example.
The second relates to Linux
Summary Page :
i.MX 6 Series Software and Development Tool R|Freescale
And the third is just a "text" example, that may be used as base for own design.
~Yuri.