Help with the SEC on a 5485

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

Help with the SEC on a 5485

1,909 Views
james_edwards
Contributor I

Hi,

 

I'm developing in CodeWarrior 6.4, using mcf548x_sec.h, on a board based on the MCF5485EVB.

 

First off is there an application note or some sample code that would illustrate how to use the SEC to calculate an MD5 check sum on a file? 

 

Right now I'm using a software algorithm to calculate an MD5 check sum on some files.  But I'd really like to use the Security Encryption Controller (SEC) to do the job.

 

I've statically assigned crypto channels 0 and 1 to the MDEU.  I think I have initialized the SEC correctly with this init function.  For my sanity and yours I've added the section numbers form the MCF5485 Reference manual Rev.4 into the comments.

 

void initSEC(void)
{    
    /* set the Interrupt mask in the SIMRH 22.6.4.3*/
    MCF_SEC_SIMRH = (0);  /* don't mask any errors for now */
   
    /* Software Reset the MDEU 22.10.2*/
    MCF_SEC_MDRCR |= MCF_SEC_MDRCR_SR;
   
    /* Static assign channels 0 and 1 to the MDEU  22.6.1*/
    MCF_SEC_EUACRH  |= (0
                        | MCF_SEC_EUACRH_MDEU_CHA0
                        | MCF_SEC_EUACRH_MDEU_CHA1 );
   
   /* Set up crypto channel 0.  22.7.1
    * Burst size 2  //j increase size later
    * Write back enabled
    * Fetch next descriptor
    * Not setting MCF_SEC_CCCRn_NT will send the notification at the end last descriptor
    * Channel done interrupt enabled
    * reset the crypto channel
    */
   MCF_SEC_CCCR0 |= (0
                     | MCF_SEC_CCCRn_BURST_SIZE(0)
                     | MCF_SEC_CCCRn_WE
                     | MCF_SEC_CCCRn_NE
                     | MCF_SEC_CCCRn_CDIE
                     | MCF_SEC_CCCRn_RST);
                     
   
}

 

I built a Descriptor structure based on figure 22-40 in the manual

 

/* SEC Data packet Discriptor */

typedef struct SECdataPacketDiscriptorTag
{
    vuint32 Header;    //4
    vuint32 LEN_1;     //8
    vuint32 PTR_1;     //12
    vuint32 LEN_2;     //16
    vuint32 PTR_2;     //20
    vuint32 LEN_3;     //24
    vuint32 PTR_3;     //28
    vuint32 LEN_4;     //32
    vuint32 PTR_4;     //36
    vuint32 LEN_5;     //40
    vuint32 PTR_5;     //44
    vuint32 LEN_6;     //48
    vuint32 PTR_6;     //52
    vuint32 LEN_7;     //56
    vuint32 PTR_7;     //60
    vuint32 PTR_Next;  //64
}aSECdiscriptor;

 

I can load the descriptor with the Statically Assigned  MDEU specific stuff from 22.14.3.3 for the first, middle and last descriptor. 

 

But I have no Idea how to get this thing going.  It looks like I have to chain the descriptors so I think I need to grab the start address and the size of my file.  Build the first descriptor, run through a for loop (file size /512 bit times???) to build the middle descriptors then build the last descriptor all in RAM.  Then feed the address of the first descriptor to????  No idea, I'm lost here.

 

Sure could use a push in the right direction.  Or help getting back on track

 

Any advice would be greatly appreciated. 

 

James.

Message Edited by *null on 2009-04-14 03:24 PM
Labels (1)
0 Kudos
4 Replies

596 Views
james_edwards
Contributor I

Still plugging away at this...

 

I've re-formatted my descriptor structure so it "looks" more like the descriptors in the manual

/* define the structure of an SEC Data packet Descriptor 22.13.1 figure 22-40*/
typedef struct SECdataPacketDescriptorTag
{
    vuint32 Header;    //4
    vuint32 LEN_1;     //8
    vuint32 PTR_1;     //12
    vuint32 LEN_2;     //16
    vuint32 PTR_2;     //20
    vuint32 LEN_3;     //24
    vuint32 PTR_3;     //28
    vuint32 LEN_4;     //32
    vuint32 PTR_4;     //36
    vuint32 LEN_5;     //40
    vuint32 PTR_5;     //44
    vuint32 LEN_6;     //48
    vuint32 PTR_6;     //52
    vuint32 LEN_7;     //56
    vuint32 PTR_7;     //60
    vuint32 PTR_Next;  //64
}aSECdescriptor;
 

 

 And I think the SEC and only chew on 64 Bytes at a time so I'm building my Descriptor chain like this.

 

/**************************************************************************************************

    <Function Name> buildDescriptorChain()

***************************************************************************************************

    <DESCRIPTION> builds a SEC -> MDEU ->MD5 descriptor chain when given the size and address of a file

 <RETURNS> start address of the first descriptor in the chain.
 
 NOTE: I declared a huge array of 24576 SECdescriptors.  This should handel a file up to 1.5MB
              
 
***************************************************************************************************

 Version      Date                    Author          Comments
   1.0  2009/04/15    J. Edwards
**************************************************************************************************/   
vuint32 buildDescriptorChain(vuint32 fileSize, vuint32 fileAdd)
{
   
    vuint32 i, L;
    vuint32 hash[32];
    vuint32 interHash[32];
   
    /* build the first descriptor fig 22-69 */
    descriptorChain[0].Header = 0x39A00010;  // Algorithm - MD5, HMAC - Yes, Pad - No, figure 22-66 and 22-70
    descriptorChain[0].LEN_1 = NULL;
    descriptorChain[0].PTR_1 = NULL;
    descriptorChain[0].LEN_2 = NULL;
    descriptorChain[0].PTR_2 = NULL;
    descriptorChain[0].LEN_3 = NULL;
    descriptorChain[0].PTR_3 = NULL;
    descriptorChain[0].LEN_4 = 64;          // number of bytes to be Hashed
    descriptorChain[0].PTR_4 = fileAdd;     /*address of the file */// pointer to Data to preform Hash on (the file??)
    descriptorChain[0].LEN_5 = NULL;
    descriptorChain[0].PTR_5 = NULL;
    descriptorChain[0].LEN_6 = 32;
    descriptorChain[0].PTR_6 = (vuint32)&interHash; /* address of the intermediat hash output ???? */
    descriptorChain[0].LEN_7 = NULL;
    descriptorChain[0].PTR_7 = NULL;
    descriptorChain[0].PTR_Next = (vuint32)&descriptorChain[1];
   
    /* build all the middle descriptors */
    L=fileSize / 64;
    for(i=1; i< (L -1); i++)
    {   
        descriptorChain[i].Header = 0x38200010; // Algorithm - MD5, HMAC - No, Pad - No, figure 22-66 and 22-71
        descriptorChain[i].LEN_1 = NULL;
        descriptorChain[i].PTR_1 = NULL;
        descriptorChain[i].LEN_2 = 32;          /* number of bytes in intermediat Hash input */
        descriptorChain[i].PTR_2 = (vuint32)&interHash; /* pointer to intermediat Hash input ???*/
        descriptorChain[i].LEN_3 = NULL;
        descriptorChain[i].PTR_3 = NULL;
        descriptorChain[i].LEN_4 = 64;          // number of bytes to be Hashed
        descriptorChain[i].PTR_4 = fileAdd +(i*64); // pointer to Data to preform Hash on
        descriptorChain[i].LEN_5 = NULL;
        descriptorChain[i].PTR_5 = NULL;
        descriptorChain[i].LEN_6 = 32;
        descriptorChain[i].PTR_6 = (vuint32)&interHash; /* address of the intermediat hash output ???? */
        descriptorChain[i].LEN_7 = NULL;
        descriptorChain[i].PTR_7 = NULL;
        descriptorChain[i].PTR_Next = (vuint32)&descriptorChain[i+1];
     }
    
    /* build the last descriptor */
    
    descriptorChain[L].Header = 0x30E00010; // Algorithm - MD5, HMAC - Yes, Pad - Yes, figure 22-66 and 22-72
    descriptorChain[L].LEN_1 = NULL;
    descriptorChain[L].PTR_1 = NULL;
    descriptorChain[L].LEN_2 = 32;
    descriptorChain[L].PTR_2 = (vuint32)&interHash;  /* pointer to intermediat Hash input ???*/
    descriptorChain[L].LEN_3 = NULL;
    descriptorChain[L].PTR_3 = NULL;
    descriptorChain[L].LEN_4 = 64;      // number of bytes to be Hashed
    descriptorChain[L].PTR_4 = fileAdd + L*64; /* address of the file +(i*64) */   // pointer to Data to preform Hash on (the file??)
    descriptorChain[L].LEN_5 = NULL;
    descriptorChain[L].PTR_5 = NULL;
    descriptorChain[L].LEN_6 = 32;
    descriptorChain[L].PTR_6 = (vuint32)&hash;   /* address of the completed hash output */
    descriptorChain[L].LEN_7 = NULL;
    descriptorChain[L].PTR_7 = NULL;
    descriptorChain[L].PTR_Next = NULL;  //done
   
    return ((vuint32)&descriptorChain);
}

 

It compiles but I'm not sure it will work.

If any of the Wizards out there can give me a hand with this it sure would be appriciated.

meanwhile I'll just keep pounding my head on the keyboard

0 Kudos

596 Views
james_edwards
Contributor I

I had an RTFM moment and found the Fetch Register 22.7.1.4  so now I'm loading the address of my first descriptor into the Fetch Register to "get this thing started".

 

I think it's running now but I get an error bit set in the SISRH on crypto channel 0.  I guess that is progress.  But when I go and look in the MDISR to "see" what caused the error, the Register reads 0 (no error)?????

 

This is how I wrote check_SEC_ERR() to decode the error regosters. 

 

I'm just thrashing in this function so it aint pritty.  I'm concerned that either the CodeWarroir deffinitions are broken or my Logic is broken.  Because I could "see" the error bit set in Debug for channel_err but I had to comment out the Mask that used the CodeWarrior register and Bit deffinitions because it was not working as I expected???

 

     channel_err = MCF_SEC_SISRH;
 //j if(((MCF_SEC_SISRH && MCF_SEC_SIMRH_CHA0ERR) == MCF_SEC_SIMRH_CHA0ERR))
      if(channel_err == 0x20000000)

 

/**************************************************************************************************

    <Function Name> check_SEC_ERR()

***************************************************************************************************

    <DESCRIPTION> Check for, and Decode errors in the SEC

 <RETURNS> the cause of the error
 
 
 - check the SISRH for an error on one of the channels
 - if we find an error bit set we must check SISRL to see which EU caused the error (should always be the MDEU)
 - then we need to decode the error bit in the MDISR 


***************************************************************************************************

 Version      Date                    Author          Comments
   1.0  2009/04/16    J. Edwards
**************************************************************************************************/
vuint32 check_SEC_ERR(void)
{
  vuint32 SIMRHerr, channel_err, eu_err, mdeu_status;
   
  SIMRHerr =0xDEADBEEF;
  eu_err =0xDEADBEEF;
  mdeu_status =0xDEADBEEF;
 
  channel_err = MCF_SEC_SISRH;
  eu_err = MCF_SEC_SISRL;
  mdeu_status= MCF_SEC_MDISR;
 
  /* check the SISRH for the error  22.6.4.4*/
  if(channel_err ==0)
  {
    /*No error */
    SIMRHerr = SEC_NO_ERROR;
  }
  else
  {
      //j if(((MCF_SEC_SISRH && MCF_SEC_SIMRH_CHA0ERR) == MCF_SEC_SIMRH_CHA0ERR))
      if(channel_err == 0x20000000)
      {
        /* error on channel 0 */
        SIMRHerr =SEC_CHANNEL_0; 
      }
      else
      {
          //j if(((MCF_SEC_SISRH && MCF_SEC_SIMRH_CHA1ERR) == MCF_SEC_SIMRH_CHA1ERR))
          if(channel_err == 0x80000000)
          {
            /* error on channel 1 */
            SIMRHerr =SEC_CHANNEL_1;
          }
          else
          {
              //j if(((MCF_SEC_SISRH && MCF_SEC_SIMRH_AERR)== MCF_SEC_SIMRH_AERR))
              if(channel_err == 0x08000000)
              {
                /* assignmet error */
                SIMRHerr =SEC_CHANNEL_ASS_ERR;
              }
              else
              {
                /* unknown error */
                printf("unknown error channel_err = %X\n",channel_err);
              }
          }
      }
   }  
  switch(SIMRHerr)
  {
    /* decode an error on channel 0 */
    case SEC_CHANNEL_0:
    {        
        printf("Error on channle 0\n");
        /* check the SIMRL to see what EU the error is on */  
        if((eu_err && MCF_SEC_SIMRL_MDEUERR)== MCF_SEC_SIMRL_MDEUERR)
        {
            printf("MDEU error");
            /* now we have to read the MDISR reg to see what the problem is 22.10.4 */
            if((MCF_SEC_MDISR && MCF_SEC_MDISR_ME)==MCF_SEC_MDISR_ME)
            {
                printf(" Mode Error\n");
            }
            if((MCF_SEC_MDISR && MCF_SEC_MDISR_AE)==MCF_SEC_MDISR_AE)
            {
                printf("Address Error\n");
            }
            if((MCF_SEC_MDISR && MCF_SEC_MDISR_IFO)==MCF_SEC_MDISR_IFO)
            {
                printf("Input FIFO overflow\n");
            }
            if((MCF_SEC_MDISR_IE && MCF_SEC_MDISR_IE)==MCF_SEC_MDISR_IE)
            {
                printf("Internal error\n");
            }
            if((MCF_SEC_MDISR_IE && MCF_SEC_MDISR_ERE)==MCF_SEC_MDISR_ERE)
            {
                printf("Early Read Error\n");
            }
            if((MCF_SEC_MDISR_IE && MCF_SEC_MDISR_CE)==MCF_SEC_MDISR_CE)
            {
                printf("Context Error\n");
            }
            if((MCF_SEC_MDISR_IE && MCF_SEC_MDISR_KSE)==MCF_SEC_MDISR_KSE)
            {
                printf("Key Size Error\n");
            }
            if((MCF_SEC_MDISR_IE && MCF_SEC_MDISR_DSE)==MCF_SEC_MDISR_DSE)
            {
                printf("Data Size Error\n");
            }
        }
        else
        {
            if((eu_err && MCF_SEC_SICRL_TEA)== MCF_SEC_SICRL_TEA)
            {
                printf("Transfer Error\n");
            }
            else
            {
                if((eu_err && MCF_SEC_SICRL_DEUERR)==MCF_SEC_SICRL_DEUERR)
                {
                    printf("DEU Error\n");
                }
                else
                {
                    if((eu_err && MCF_SEC_SICRL_AESUERR)==MCF_SEC_SICRL_AESUERR)
                    {
                        printf("AESU Error\n");
                    }
                    else
                    {
                        if((eu_err && MCF_SEC_SICRL_AFEUERR)==MCF_SEC_SICRL_AFEUERR)
                        {
                            printf("AFEU Error\n");
                        }
                        else
                        {
                            if((eu_err && MCF_SEC_SICRL_RNGERR)==MCF_SEC_SICRL_RNGERR)
                            {
                                printf("RNG Error");
                            }
                            else
                            {
                                printf("Unknown eu_err =%X \n",eu_err );
                            }
                        }
                    }
                }
             }
          }        
    }
    break;

I will not bore you with the rest of the function....

 

I'm about to give up on the forum for help.  I'll just keep plugging away at this.  If I do figure it out I'll reply to my own post yet again with a solution.

 

I can't belive I'm the only guy on the planet trying to use the SEC on the MCF5485.  Someone has to know how the SEC works.

 

All alone in the dark.

James

Message Edited by *null on 2009-04-17 10:57 AM
0 Kudos

596 Views
james_edwards
Contributor I

I just might me the only guy on the planet trying to use the SEC.

 

I found a descripency in Rev4 of the MCF548x Reference manual.

22.5 on Page 22-10 shows the MBAR offset for the MDISR as 0x2C030

22.10.4 on Page 22-43 shows the MBAR offset for the MDISR as 0x21038

 

I think CodeWarrior has it correct at 0x2C030

 

I checked the erratta for the Rev 4 manual and it's not in there???

 

Sadly my CodeWarrior project is still not working.

 

But I'm still chugging away at it. Chug, Chug, chug.

James

 

0 Kudos

596 Views
james_edwards
Contributor I

I've cleaned up my Structure to look like this

typedef struct SECdataPacketDescriptorTag
{
    vuint32     Header;            //4
    vuint32     LEN_1;             //8
    unsigned char* PTR_1;     //12
    vuint32     LEN_2;            //16
    unsigned char* PTR_2;     //20
    vuint32     LEN_3;            //24
    unsigned char* PTR_3;     //28
    vuint32     LEN_4;            //32
    unsigned char* PTR_4;     //36
    vuint32     LEN_5;           //40
    unsigned char* PTR_5;     //44
    vuint32     LEN_6;           //48
    unsigned char* PTR_6;     //52
    vuint32     LEN_7;           //56
    unsigned char* PTR_7;     //60
    unsigned char* PTR_Next;  //64
}aSECdescriptor;

 

And I fixed my buildDescriptorChain so it will not miss the next to last desctiptor in the chain.

 

/* build all the middle descriptors */
    L=fileSize / 64;
    for(i=1; i<= (L -1); i++)
    {   
        descriptorChain[i].Header = 0x38200010; // Algorithm - MD5, HMAC - No, Pad - No, figure 22-66 and 22-71
        descriptorChain[i].LEN_1 = NULL;
        descriptorChain[i].PTR_1 = NULL;
        descriptorChain[i].LEN_2 = 16;          /* number of bytes in intermediat Hash input  128 bits */
        descriptorChain[i].PTR_2 = (unsigned char*)&interHash; /* pointer to intermediat Hash input */
        descriptorChain[i].LEN_3 = NULL;
        descriptorChain[i].PTR_3 = NULL;
        descriptorChain[i].LEN_4 = 64;          // number of bytes to be Hashed
        descriptorChain[i].PTR_4 = (unsigned char*)fAdd +(i*64); // pointer to Data to preform Hash on
        descriptorChain[i].LEN_5 = NULL;
        descriptorChain[i].PTR_5 = NULL;
        descriptorChain[i].LEN_6 = 16;
        descriptorChain[i].PTR_6 = (unsigned char*)&interHash; /* address of the intermediat hash output */
        descriptorChain[i].LEN_7 = NULL;
        descriptorChain[i].PTR_7 = NULL;
        descriptorChain[i].PTR_Next = (unsigned char*)&descriptorChain[i+1];
     }

 

I'm still not sure if the Hash and the intermediat Hash are two seperate mem locations or just one.  I'm using two seperate locations now.  But still no joy.

 

James

0 Kudos