P4080 SEC 4.0 Issue

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

P4080 SEC 4.0 Issue

Jump to solution
4,459 Views
Jianhui
Contributor I

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 = '('

 

0 Kudos
Reply
1 Solution
3,593 Views
barakman
Contributor II

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

 

View solution in original post

0 Kudos
Reply
6 Replies
3,593 Views
barakman
Contributor II

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.

0 Kudos
Reply
3,593 Views
Jianhui
Contributor I

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

 

0 Kudos
Reply
3,593 Views
barakman
Contributor II

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

0 Kudos
Reply
3,593 Views
Jianhui
Contributor I

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


0 Kudos
Reply
3,594 Views
barakman
Contributor II

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

 

0 Kudos
Reply
3,593 Views
barakman
Contributor II

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

 

0 Kudos
Reply