Hi,
I'm using P4080 (E500MC) to use the new security driver 4.0. I follow the instruction in P4080 QorIQ Reference Manual to program using Descriptor command to perform Kasumi F8 algorithm over the input data blocks. However I found the Security driver behaves not as I supposed. Following are some detailed description:
1. When I use the ALGORITHM command in a descriptor, the SEC 4.0 driver are always hang. The descriptor that I've programmed and feed into system is as below:
Header Command: 0xb081000a
Key Command: 0x02200010 // This is to load the key into Class 1 Key Register
0x05f6b774 // Pointer of the key address, key is always 16 bytes
Load Command: 0x12200040 // This is to load into Class 1 Context Register
0x05f6b7f0 // Address of the data that want to copy into class 1 context register, 512 bits total
FIFO Load Command: 0x22100010 // This is to load message data into Input Data FIFO, data is 16 bytes
0x05f63014 // Data address
Algorithm command: 0x82700d07 // This is to perform ALGORITHM (kasumi f8) over the input Data
FIFO Store Command: 0x60300010 // This is to move the ciphered data in Output Data FIFO into system memory buffer 0x05f68e70 // Output data buffer address
While I build a descriptor buffer and call the SEC_JQ_Enqueue() to perform the ciphering operation, I found I could not get the expected result. When I query the Status register using following command, I found the SEC4 driver is hung!! Please not the sstar is 0x401 (According to P4080 reference manual the lowest bit indicate the SEC 4.0 is Busy that SEC 4.0 is processing at least one Descriptor). Also, in SEC_JQ_Dequeue() source code, the sec 4.0 driver is querying orsfr register to expected SEC 4.0 to update that register to non-zero value, but unfortunately it seems SEC 4.0 never update orsfr therefore the descriptor is never completed!
Does anybody in Freescale could explain why is that? This puzzled me for quite some time.
Thanks a lot!
Jianhui
-> SEC_JQ_DumpRegisters p_SecJq
JQ Registers (0xE0301000)
---------------------------------------------------------
0xE0301000: 0x0000000005e94010 irbar
0xE030100C: 0x00000100 irsr
0xE0301014: 0x00000100 irsar
0xE030101C: 0x00000001 irjar
0xE0301020: 0x0000000005f50730 orbar
0xE030102C: 0x00000100 orsr
0xE0301034: 0x00000000 orjrr
0xE030103C: 0x00000000 orsfr
0xE0301044: 0x00000000 ostar
0xE030104C: 0x00000000 istar
0xE0301050: 0x0000000000000001 cfgr
0xE030105C: 0x0000000c irrir
0xE0301064: 0x00000000 orwir
0xE030106C: 0x00000000 cmdr
Status Registers (0xE0301F00)
---------------------------------------------------------
0xE0301F00: 0x0000000000000003 req_deq
0xE0301F08: 0x0000000000000000 ob_enc_req
0xE0301F10: 0x0000000000000000 ib_dec_req
0xE0301F18: 0x0000000000000000 ob_encrypt
0xE0301F20: 0x0000000000000000 ob_protect
0xE0301F28: 0x0000000000000000 ib_decrypt
0xE0301F30: 0x0000000000000000 ib_validated
0xE0301FA0: 0x1000000011010000 crnr
0xE0301FA8: 0x8ebf000000001fff ctpr
0xE0301FC0: 0x0000000000000000 far
0xE0301FC8: 0x00000000 falr
0xE0301FCC: 0x00000000 fadr
0xE0301FD4: 0x00000401 sstar
0xE0301FE0: 0x0f0a0001 rvidr
0xE0301FE4: 0x00000001 ccbvidr
0xE0301FE8: 0x0100000100122104 chavidr
0xE0301FF0: 0x4500001512125135 chanumr
0xE0301FF8: 0x0a10020000000000 secvidr
value = 40 = 0x28 = '('
Solved! Go to Solution.
Hi
-----------------------------------------------------------------------------------------------------------------------------------
The 'CmdInsertAnything' routine was added in order to bypass the methodology I have used, and allow options that may be missing in all other routines. You should try to avoid using it as much as possible, because it does not assert any of the flags in the command. By the way, the equivalent routine in the API level is 'SEC_DCL_InitRawDesc'.
-----------------------------------------------------------------------------------------------------------------------------------
A small correction to your description: It is not the SEC driver that hangs - it is the SEC HW.
-----------------------------------------------------------------------------------------------------------------------------------
"Comparing these source code, the only difference is I call the CmdInsertanything instead of calling CmdInsertFifoLoad/Store function. I think those should be identical (as long as I'm using a 32bit pointer system). Isn't that correct?"
Not entirely correct: If your virtual-to-physical memory mapping scheme is not "1 to 1" (i.e., virtual address != physical address), then you will probably have the wrong pointer inside your descriptor. You must write the physical address inside the descriptor, in order for SEC to process it properly.
When you do:
cmdFlags = (uint32_t) (p_Param->outputData.p_Data);
CmdInsertAnything(&descHandle, cmdFlags);
You are actually writing the virtual address.
And as you speculated, for a 64bit pointer system, it will not work even if virtual address == physical address.
-----------------------------------------------------------------------------------------------------------------------------------
I cannot explain why you should move the Algorithm command up between Key and Load command.
I just took a Kasumi-F8 example from an old code I had here (not even mine), and compared it with your descriptor. I applied this difference (along with the other differences mentioned), and it worked. If it works for you without it, then I don't see any problem with it (except, perhaps, with performance, but I don't have the means to verify that here).
In any case, I shall try to add a support for your descriptor in our next release.
-----------------------------------------------------------------------------------------------------------------------------------
Thanks
Your Load command (0x12200040) is illegal.
In the CAAM BG, see table 1-131 (LOAD Command DST, LENGTH and OFFSET Field Values):
For DST = 0x20, LENGTH must be either 4 or 8, and OFFSET must not be greater than 64 minus LENGTH.
In your Load command: DST = 0x20, LENGTH = 64, OFFSET = 0.
Also in table 1-131, a possible explanation to the fact that CAAM remains busy:
A non-IMM LOAD to a Context Register blocks if the CCB DMA is writing to either Context Register.
I'm not sure what code you've used for creating this descriptor.
Due to the fact that it's not provided within our driver, I assume that you've manually calculated each command and then created a "raw-command" descriptor.
Although not meant to serve as API routines, if you used our internal routines (sec_dcl_cmd.c) instead, then you would get an error for this Load command.
Nevertheless, CAAM appears to perform the job, so I shall send an inquiry to the HW engineer, as to why it remains busy and why ORSFR remains 0.
Hi expert,
Firstly thank you for your quick reply.
I looked into the P4080 reference Manual and did not find table 1-131 at all. Are we use different version of P4080 reference manual. Mine is Rev G (the whole name of PDF is "P4080 QorIQ Integrated Multicore Communication Processor Family Reference Manual" Rev G 04/2010). Is this the same one with yours?
In my P4080 Reference Manual, the LOAD command is described in section 28.7.8 and the table to describe the LENGTH field of LOAD command is in table 28-114, which shows DST=0x20 means "Class 1 Context Register" and the Length is indicated in "Byte" instead of "Word".
Any idea on why is that?
By the way, I've created the descriptor just using your internal routines (in sec_dcl_cmd.c) with some small modification. Following part are the codes that create the Job descriptor:
t_DescHandle descHandle = NewDescHandle(p_Desc,ptrSize);
uint32_t startIndex = 0;
uint32_t cmdFlags = 0;
static uint32_t value[16]={0};
int i = 0;
/* HEADER Command - refer to P4080RM_RevG Section 28.7.6 */
cmdFlags = JOB_DESC_HDR_SHARE_NEVER;
CmdInsertJobDescHdr(&descHandle, cmdFlags);
/* Record the startIndex */
startIndex = descHandle.nextIndex;
/* KEY Command - Class 1 Key Data Block - refer to P4080RM_RevG Section 28.7.7 */
cmdFlags = KEY_CTYPE | KEY_CLASS_1_DST_REGISTER | KEY_NWB;
cmdFlags |= KEY_LENGTH(cipherKeySize); // Ciphyering Key length is 16 Octets
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = (uint32_t) p_CipherKeyData;
CmdInsertAnything(&descHandle, cmdFlags);
/* LOAD Command - Class 1 Context Register - refer to P4080RM_RevG Section * 28.3.5.15 & 28.7.8 */
value[0] = p_Param->count;
value[1] = (p_Param->bearer << 27) | (p_Param->direction << 26);
cmdFlags = LOAD_CTYPE | LOAD_CLASS_1_DST_CTX | LOAD_OFFSET(0) | LOAD_LENGTH(64);
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = &value[0];
CmdInsertAnything(&descHandle, cmdFlags);
/* FIFO LOAD Command - refer to P4080RM_RevG Section 28.7.9 */
cmdFlags = FIFO_LOAD_CTYPE | FIFO_LOAD_CLASS_1_TYPE_MSG | FIFO_LOAD_LENGTH(p_Param->inputData.size);
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = p_Param->inputData.p_Data;
CmdInsertAnything(&descHandle, cmdFlags);
/* ALGORITHM OPERATION Command - refer to P4080RM_RevG section 28.7.13 */
cmdFlags = ALG_OP_CTYPE | ALG_OP_TYPE_CLASS_1 | ALG_OP_ID_KASUMI | ALG_OP_AAI_KASUMI_F8 | ALG_OP_AS_INIT | ALG_OP_ICV | ALG_OP_AAI_KASUMI_GSM;
cmdFlags |= (sec_op == e_KASUMI_F8_ENCAPSULATION ? ALG_OP_DIR_ENC : ALG_OP_DIR_DEC);
CmdInsertAnything(&descHandle, cmdFlags);
/* FIFO STORE Command - refer to P4080RM_RevG Section 28.7.9 */
cmdFlags = FIFO_STORE_CTYPE | FIFO_STORE_CLASS_UNUSED_TYPE_MSG | FIFO_STORE_LENGTH(p_Param->outputData.size);
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = p_Param->outputData.p_Data;
CmdInsertAnything(&descHandle, cmdFlags);
CloseJobDesc(&descHandle, startIndex);
#if 1
for (i=0; i<descHandle.nextIndex; i++)
{
printf("JOB DESC - buffer[%d] = 0x%08x\n", i, descHandle.p_Buffer[i]);
}
#endif
Thanks again,
Jianhui
Hi
Continuing my previous message, although I haven't received any answer from CAAM HW engineers, here is a descriptor that will work for you:
Header Command: B081000A (identical)
Key Command: 02200010 (identical)
Key Command: Pointer
Algorithm Command: 82700C0D (instead of 82700D07)
Load command: 12200008 (instead of 12200040)
Load Command: Pointer
FIFO Load Command: 22120010 (identical)
FIFO Load Command: Pointer
FIFO Store Command: 60300010 (identical)
FIFO Store Command: Pointer
A summary of the changes I have applied in your descriptor:
1. Algorithm command:
a. Moved up (between Key command and Load command)
b. ALG_OP_AS_INIT changed to ALG_OP_AS_INITFINAL
c. ALG_OP_AAI_KASUMI_GSM removed
2. Load command:
a. Length changed from 64 to 8
The code for this descriptor is in the enclosed files.
Add the contents of each file to the corresponding file on your PC.
You may need to make some adjustments in order for it to work with your version of the SEC driver.
Thank
Hi Expert,
Thanks so much for your detailed explanation as well as the sample code!
I've tested that using your code it works fine! Then I change the code back to my original code gradually and found the issue that cause the SEC driver to hang is the FIFO LOAD/STORE command I'm using. It looks like if I change my code from
cmdFlags = FIFO_LOAD_CTYPE | FIFO_LOAD_CLASS_1_TYPE_MSG | FIFO_LOAD_LENGTH(p_Param->inputData.size);
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = (uint32_t) (p_Param->inputData.p_Data);
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = FIFO_STORE_CTYPE | FIFO_STORE_CLASS_UNUSED_TYPE_MSG | FIFO_STORE_LENGTH(p_Param->outputData.size);
CmdInsertAnything(&descHandle, cmdFlags);
cmdFlags = (uint32_t) (p_Param->outputData.p_Data);
CmdInsertAnything(&descHandle, cmdFlags);
to
cmdFlags = FIFO_LOAD_CLASS_1_TYPE_MSG_L1;
CmdInsertFifoLoad(&descHandle, cmdFlags, p_Param->inputData.size, p_Param->inputData.p_Data);
cmdFlags = FIFO_STORE_CLASS_UNUSED_TYPE_MSG;
CmdInsertFifoStore(&descHandle, cmdFlags, p_Param->outputData.size, p_Param->outputData.p_Data);
Then everything works fine.
Comparing these source code, the only difference is I call the CmdInsertanything instead of calling CmdInsertFifoLoad/Store function. I think those should be identical (as long as I'm using a 32bit pointer system). Isn't that correct?
I also browse the source code of CmdInsertFifoLoad/Store() and the difference I can see is I'm using "WriteWord" instead of "WriteAddr" function. Then I change my code to something like following but when I run the test I still got the SEC4 driver hang up. Why is that?
cmdFlags = FIFO_LOAD_CTYPE | FIFO_LOAD_CLASS_1_TYPE_MSG | FIFO_LOAD_LENGTH(p_Param->inputData.size);
CmdInsertAnything(&descHandle, cmdFlags);
WriteAddr(&descHandle, p_Param->inputData.p_Data);
cmdFlags = FIFO_STORE_CTYPE | FIFO_STORE_CLASS_UNUSED_TYPE_MSG | FIFO_STORE_LENGTH(p_Param->outputData.size);
CmdInsertAnything(&descHandle, cmdFlags);
WriteAddr(&descHandle, p_Param->outputData.p_Data);
As long as your modifications on my descriptor, I agree with your changes on 1.b, 1.c and 2.a. But could you please explain a little bit regarding why should I move the Algorithm command up between Key and Load command? Thanks!
A summary of the changes I have applied in your descriptor:
1. Algorithm command:
a. Moved up (between Key command and Load command)
b. ALG_OP_AS_INIT changed to ALG_OP_AS_INITFINAL
c. ALG_OP_AAI_KASUMI_GSM removed
2. Load command:
a. Length changed from 64 to 8
Finally, Thanks a lot for attaching the latest SEC4 driver document, that would be very useful for me.
Thanks & Best Regards,
Jianhui
Hi
-----------------------------------------------------------------------------------------------------------------------------------
The 'CmdInsertAnything' routine was added in order to bypass the methodology I have used, and allow options that may be missing in all other routines. You should try to avoid using it as much as possible, because it does not assert any of the flags in the command. By the way, the equivalent routine in the API level is 'SEC_DCL_InitRawDesc'.
-----------------------------------------------------------------------------------------------------------------------------------
A small correction to your description: It is not the SEC driver that hangs - it is the SEC HW.
-----------------------------------------------------------------------------------------------------------------------------------
"Comparing these source code, the only difference is I call the CmdInsertanything instead of calling CmdInsertFifoLoad/Store function. I think those should be identical (as long as I'm using a 32bit pointer system). Isn't that correct?"
Not entirely correct: If your virtual-to-physical memory mapping scheme is not "1 to 1" (i.e., virtual address != physical address), then you will probably have the wrong pointer inside your descriptor. You must write the physical address inside the descriptor, in order for SEC to process it properly.
When you do:
cmdFlags = (uint32_t) (p_Param->outputData.p_Data);
CmdInsertAnything(&descHandle, cmdFlags);
You are actually writing the virtual address.
And as you speculated, for a 64bit pointer system, it will not work even if virtual address == physical address.
-----------------------------------------------------------------------------------------------------------------------------------
I cannot explain why you should move the Algorithm command up between Key and Load command.
I just took a Kasumi-F8 example from an old code I had here (not even mine), and compared it with your descriptor. I applied this difference (along with the other differences mentioned), and it worked. If it works for you without it, then I don't see any problem with it (except, perhaps, with performance, but I don't have the means to verify that here).
In any case, I shall try to add a support for your descriptor in our next release.
-----------------------------------------------------------------------------------------------------------------------------------
Thanks
Hi
In P4080RM_RevG.pdf, it is under "Table 28-114. LOAD Command DST Field Values", but the description there is very confusing and inconsistent (part of it appearing before the table itself), and so they had to change it.
I have enclosed a more recent version of the spec., where you can find table 1-131.
However, looking into the code you sent, I see that indeed you are using my internal routines.
And you did not get an error for the illegal Load command, because the driver source code on your side matches P4080RM_RevG.pdf, where this Load command is not illegal.
In any case, whether this Load command is illegal or not, I am not even sure that it is the cause of the problem.
I am waiting for an answer from CAAM HW engineers on this issue.
On thing I have noticed in the code you sent (which made your intentions more clear to me):
In your Algorithm command, you are using the flags 'ALG_OP_AAI_KASUMI_F8' and 'ALG_OP_AAI_KASUMI_GSM', which together combine to 0xD00.
In my 'sec_dcl_cmd' internal routines, you are only supposed to use one flag of each prefix (for example, in this case, you should use only one 'ALG_OP_AII_xxx' flag).
Since I did not know your intention, I used the flag 'ALG_OP_AAI_AES_CTR_CMAC_LTE', which is equal to 0xD00.
I believe that this is also what CAAM thinks. So in essense, you are not really running Kasumi.
I shall have a look to see if it works using only 'ALG_OP_AAI_KASUMI_F8'.
Thanks