This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3235MODSF: sl_Fs behavior question

Part Number: CC3235MODSF
Other Parts Discussed in Thread: UNIFLASH, SYSCONFIG

Hello,

We are working on finalizing the provisioning of our CC3235 based product. I am seeing some anomalous behavior when we write the security certificates into the NWP flash memory. Some background first. There are seven certificate files that vary in size from 1554 bytes to 2090 bytes in size. Each file is sent from our STM32 main processor to the CC3235 in chunks. Our application code reassembles each file and as each file is complete it is created and written to the NWP flash. So basically STM32 -> CC3235 APP -> CC3235 NWP. The STM32 waits 3 seconds between files to give the CC3235 time to process the file. Simple enough. 

However, when I go to examine the files after they are transferred, each is exactly 2048 bytes long. Those longer than 2048 are truncated. Those shorter are complete, but the data from a previous file that was longer fills the remaining space from the ----- END CERTIFICATE ----- to the offset 2048. I know the extra data did not come from the application because the buffer the file is built up in is cleared each time before use.

Now, the really strange part of this is that if I set a breakpoint after each file is closed, the file is written properly! Initially I thought this could be because of the delay induced by examining data after each time the breakpoint is hit. However, I added a 1 minute delay between each file transfer and write, and the problem persists. I will include the file write application code below, it's fairly simple. It almost looks like the sl_Fs is having one file overwrite the other before it makes it to flash like there is a buffer that is getting corrupted.

Thanks for any help!

Regards,

John

/**
 * \details	This routine manages the FS Security Write
 * \note None
 * \param[in]	typ denotes the security file type
 * \param[out]	None
 * \return ret_val returns 0 on failure and non zero on success
 */
int32_t FS_SecurityWrite(fs_security_type_t typ)
{
  const char *filename              = FS_securityGetFileName(typ);
  fs_security_info_t * p_sec_info   = FS_SecurityGetBuffer(typ);
  int32_t offset                    = 0;
  int32_t f_hndl                    = 0;
  int32_t ret_val                   = 0;

  //Note: Make sure to initialize config file with MAX_SECURITY_INFO_SIZE zeroes, even if
  //      only using 20 bytes.
  //      Otherwise, attempting to read MAX_SECURITY_INFO_SIZE bytes from the file would
  //      fail.
  
  f_hndl = sl_FsOpen((const unsigned char *)filename,
                     (SL_FS_CREATE | SL_FS_OVERWRITE | SL_FS_CREATE_FAILSAFE | 
                      SL_FS_CREATE_MAX_SIZE(MAX_SECURITY_INFO_SIZE)),
                     0);
  
  WSIS_SendDebugPrint("Fs Write f_hndl: %d  size: %d  typ: %d  name: %s", f_hndl, MAX_SECURITY_INFO_SIZE, typ, filename);

  //Check if open was successful
  if(f_hndl < 0)
  {
    ret_val = f_hndl;
  }
  
  if(ret_val >= 0)
  {    
    ret_val = sl_FsWrite(f_hndl,offset, (uint8_t *)p_sec_info->cert, p_sec_info->size);
    WSIS_SendDebugPrint("Fs Write ret_val: %d", ret_val);
    if(ret_val > 0)
    {
      offset += ret_val;
    }
  }
  
  if(f_hndl >= 0)
  {
    // Make sure to close it if sl_FsOpen was successful
    sl_FsClose(f_hndl, NULL, NULL, 0);
  }
 
  return ret_val; //<----- Works correctly if I set a breakpoint here
}

  • How is MAX_SECURITY_INFO_SIZE defined?

    Can you set it to the p_sec_info->size (or add some space if this file can overwritten)?

  • Hi Kobi,

    Here are the relevant definitions and the structure of the security information struct:

    #define MAX_SECURITY_CERT_SIZE          4096-sizeof(uint16_t) 
    
    typedef struct 
    {
      uint16_t      size;
      uint8_t       cert[MAX_SECURITY_CERT_SIZE];
    } fs_security_info_t;
    
    #define MAX_SECURITY_INFO_SIZE  MIN_BLOCK_SIZE(sizeof(fs_security_info_t), 1024)
    

    The p_sec_info->size varies from file to file and is always less the 4096. I thought the smallest file size allowed was 1 4096 byte block.

    I'm not sure why the original writer of this is setting the MAX_SECURITY_CERT_SIZE to 4096 - sizeof(uint16_t). We don't want the size to go into that file, just the certification itself.

    John

  • Hi Kobi,

    One other detail. In the case where things work with the breakpoint in place, the file write always returns the number of bytes in the certificate if it's 2090 we get 2090 back. Same with the other file sizes. When it fails we always get 2048 back from the write operation. Also in the failure case the certificate data is preceded by the size of the certificate from that certificate structure. I find that very interesting and cannot fathom how it is happening.

    John

  • What is the MIN_BLOCK_SIZE (used for the MAX_SECURITY_INFO_SIZE)? - does it return the minimum between 1024 and secure size?

    It is hard to believe that such a simple use of the sl_Fs API causes issues. This was done too many times by our customers so i really think you should check the application (and make sure you are using an updated SP).

    You can also use the following function instead (it can be found in utils_if.c in the mqtt_client example of SDK 6.10).

    nt FILE_write(char *pFilename, uint16_t length, uint8_t* pValue, uint32_t *pToken, uint32_t flags)
    {
        int32_t  lFileHandle;
        int   rc;
        uint32_t ulToken = 0;
        int32_t  OpenFlags = 0;
    
    
        /* Open the file as bundle !!!*/
        OpenFlags = (SL_FS_CREATE | SL_FS_OVERWRITE);
        OpenFlags |= (SL_FS_CREATE_SECURE | SL_FS_CREATE_NOSIGNATURE);
        OpenFlags |= flags;
    
        if(!pToken)
        {
            pToken = &ulToken;
            OpenFlags |= (SL_FS_CREATE_PUBLIC_WRITE | SL_FS_CREATE_PUBLIC_READ);
        }
    
        lFileHandle = sl_FsOpen((uint8_t *)pFilename,  OpenFlags| SL_FS_CREATE_MAX_SIZE( length ), (unsigned long *)pToken);
        if(lFileHandle < 0)
        {
            LOG_TRACE("FILE_write: Error sl_FsOpen %s, Status=%d", pFilename, lFileHandle);
            return (int16_t)lFileHandle;
        }
    
        rc = (int16_t)sl_FsWrite(lFileHandle , 0, (uint8_t *)pValue,length);
        if(rc < 0)
        {
            LOG_TRACE("FILE_write: Error sl_FsWrite, Status=%d", rc);
            return rc;
        }
    
        rc = sl_FsClose(lFileHandle, NULL, NULL, 0);
        if(rc < 0)
        {
            LOG_TRACE("FILE_write: Error sl_FsClose, Status=%d", rc);
            return rc;
        }
    
        return rc;
    }
    
                 

  • Hi Kobi,

    Sorry for the delay in responding. We were fortunate enough to have Friday, Monday, and Tuesday as holidays. I am also finding it hard to believe my very simple use case is having problems. I'll take a look at the example you suggested. In the mean time to answer your question: "What is the MIN_BLOCK_SIZE (used for the MAX_SECURITY_INFO_SIZE)? - does it return the minimum between 1024 and secure size?" The answer is below.


    #define MAX_SECURITY_CERT_SIZE 4096-sizeof(uint16_t)

    typedef struct
    {
    uint16_t size;
    uint8_t cert[MAX_SECURITY_CERT_SIZE];
    } fs_security_info_t;

    #define MIN_BLOCK_SIZE(x, y)             ((((x)+(y)-1)/(y))*(y))

    MIN_BLOCK_SIZE(sizeof(fs_security_info_t), 1024)

    So, the size of x should be 4096, and y is hard coded to 1024. If I did the math correctly this should result in a value of 4096 using integer math with its truncation of remainders. Not quite sure why they went through all the effort, but it is what it is.

    Regards,

    John

  • Hi,

    One other question: is there a way to see what service pack I am running or is it best to just program it again?

    Thanks,

    John

  • Hi,

    You can ignore my question of getting the service pack information. I found the sl_DeviceGet API. When I ran it, the results were:

    Which certainly looks out of date. I'll try to program the latest 6.10 SP using Uniflash.

    Regards,

    John

  • The logic of MIN_BLOCK_SIZE seems correct but please try to put a breakpoint before the sl_FsOpen to verify that the values are as expected.

  • Hi,

    So I did set a breakpoint and examined the value of the mode/flags/size. They showed a value of 0x28020010 which after breaking them down looks correct. That should be FS_OVERWRITE, FS_CREATE, and FS_FAILSAFE, plus a size of 4096 (0x10 * 0x100).

    John

  • The disassembly confirms the value that I saw in the breakpoint:

    //  651   //Note: Make sure to initialize config file with MAX_SECURITY_INFO_SIZE zeroes, even if
    //  652   //      only using 20 bytes.
    //  653   //      Otherwise, attempting to read MAX_SECURITY_INFO_SIZE bytes from the file would
    //  654   //      fail.
    //  655   
    //  656   f_hndl = sl_FsOpen((const unsigned char *)filename,
    //  657                      (SL_FS_CREATE | SL_FS_OVERWRITE | SL_FS_CREATE_FAILSAFE | 
    //  658                       SL_FS_CREATE_MAX_SIZE(MAX_SECURITY_INFO_SIZE)),
    //  659                       NULL);
            MOVS     R2,#+0
            LDR.N    R1,??DataTable10_13  ;; 0x28020010
            MOV      R0,R10
            BL       sl_FsOpen
            MOV      R8,R0

  • I tried to verify that I had the latest service pack. I think I do, but it is hard to tell. The reason is that on the device the data for versions is what the screenshot above shows. The sysconfig output this information when it selects the service pack:

    CommandNum = 2
    CommandWriteServicePack:
    Service pack versions, NWP = (4, 17, 0, 0) MAC = (3, 1, 0, 5) PHY = (3, 1, 0, 25)
    Max Service Pack file size = 131072
    FileLocation = c:\ti\simplelink_cc32xx_sdk_6_10_00_05\source\ti\drivers\net\imagecreator\bin\\..\..\..\..\..\..\.\tools/cc32xx_tools/servicepack-cc3x35\sp_4.13.0.2_3.7.0.1_3.1.0.26.bin
    FileSystemName = /sys/servicepack.ucf
    File max size is 131072 bytes, actual size 81916 bytes
    After running the extracting the file will require 66 blocks on the device

    So the version information from the device doesn't match what sysconfig thinks it is grabbing and neither match that is embedded in the file name. I reburned the .sli just to sure.

  • please ignore the Service pack versions in the ImageCreator Log: NWP = (4, 17, 0, 0) MAC = (3, 1, 0, 5) PHY = (3, 1, 0, 25).

    There is some issue with this log (but not with the content that is actually being written).

    The version in sl_DeviceGet should be correct.

  • Understood, is the version I see in the sl_DeviceGet response the latest for 6.10?

  • it is from 6.10 - not the latest (as there is 7.10)  but it should be good enough.

    Did you compare to the code I provided?

  • I've been looking at the code you sent, I'll be doing more over the weekend because I'm on a deadline for this afternoon to get something else done. I'll follow up on Monday.

  • Hi Kobi,

    Sorry for the delay in response, my priorities were changed. I'm almost back to where I can dig in on this again. I compared the code you sent from the example with our code. The biggest difference I noted was the delta on the flags set on the sl_FsOpen call. In particular the failsafe flag we are using. When I reengage this hopefully soon I'm going to do some experimentation around that and see what happens. Plus I need to add security to those files anyway, no way we want to ship with out the certificates being secure.

    John

  • I believe your issue only relates to size/length. security and fail-safe is a different matter.

    So please try check the example code. If it works - compare the parameters to your code. 

    Deal with security and other flags later.

  • Just touching this to keep it open. Still haven't been able to get back to this. Hopefully soon.