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.

CCS/CC3220SF-LAUNCHXL: ECC key-pair with the SECP256R1

Part Number: CC3220SF-LAUNCHXL

Tool/software: Code Composer Studio

Dear Sir,

This thread i open for an example of sign and verify buffer. here i have some payload which i have sign with private key and send it to via HTTPS to the client. here i have been looking for the encryption and decryption method for the my application but i cloud not able to execute the secure content delivery method because of the lake of document and proper support so i come up with some ideal like if i cloud sign my payload with unique ECC key which is already stored at entry0 as per the SimpleLink™ Wi-Fi® CC3x20, CC3x3x Network Processor guidelines. as i understood ,as per the Document the key would be the unique per device and it won't be writable and erasable ?

So i here i tried to read stored key with the below snippet .please have a look .

/* get the Public key */
configOpt = SL_NETUTIL_CRYPTO_PUBLIC_KEY_INFO;
objId = 0;
configLen = 255;

rc = sl_NetUtilGet(configOpt, objId, buf, &configLen);

if (rc < 0)
{
SHOW_ERROR(rc, "sl_NetUtilCmd() failed");
}
else
{
for (ii = 0; ii < configLen; ii++)
{
WMDebugInfo(DEBUG_LOG, "key data at index [%d] in hex[%d] = %02x", objId, ii, buf[ii]);

}

WMDebugInfo(DEBUG_LOG, "public key %s", base64decode);


}

I observed something here after getting the response. well i was reading the SECP256R1 key format , here i thing private key will be the 32-byte and public key will the 64-byte long but while reading the key from the index of Zero (0) i found @configLen it self is 64 byte. so my for loop ran for the 64 time's but it should be i thing 32 byte but i am not sure.

Here i have following question about this :

1. what type of the is stored at entry 0 ? is it public key or private key ? and what is the key format because i could not able to print directly .

2. The signed payload i have to send it via HTTPS so other side like cloud they have to verify the payload signature using the public key so i do i share the public via HTTPS.

3. What would be the format of the signature data ?

4. If i want to see the metadata of the key how do i do ? and how to verify that data if get this data ?

 

Please do needful.

Thanks 

Ketan vadodariya

  • Hi Ketan,

    Each entry contain a key pair (a public key and private one).

    Index 0 contains a device unique key (fixed key pair). 

    You can read the public key with "configOpt =SL_NETUTIL_CRYPTO_PUBLIC_KEY". 

    You can't access the private key.

    Please refer to chapter 17 of the programmers guide (https://www.ti.com/lit/ug/swru455l/swru455l.pdf) for more details.

    Br,

    Kobi

  • Dear Kobi,

    Here I'm able to read the public key from entry0 but I have question about the format of the key.

    This key would the constant key?? I mean this key will change everytime when I read it??

  • Dear kobi,

    Here Is my code for the signature and verification of the buffer. Please have a look once..

    I hope this entry0 is persistent , immutable and unique for the every processor as per the document. 

    // Getting Public key from the input index
    static int generate_public_key_from_index(uint32_t index, uint32_t configOpt, uint8_t *publicKey, uint16_t *keyLen)
    {
        int rc = -1;
    
        rc = sl_NetUtilGet(configOpt, index, publicKey, keyLen);
    
        if (rc < 0)
        {
            ASSERT_ON_ERROR(rc, "sl_NetUtilCmd() failed");
        }
    
        return rc;
    }
    
    // Verify the signature using the given index
    static int verify_sign_buffer_using_index(uint32_t index, uint8_t* buff , uint16_t buffLen , uint8_t* signBuff , uint16_t signBuffLen)
    {
        int rc = -1;
    
        uint16_t resultLen = 0;
    
        if (1500 < (buffLen + signBuffLen))
        {
            SHOW_ERROR(rc, "buffer length is too large");
            return rc;
        }
    
        /* now verify the buffer */
        memcpy(base64encode, buff, buffLen);
        memcpy(base64encode + buffLen, signBuff, signBuffLen);
    
        SlNetUtilCryptoCmdVerifyAttrib_t verAttrib;
    
        verAttrib.Flags = 0;
        verAttrib.ObjId = 0;
        verAttrib.SigType = SL_NETUTIL_CRYPTO_SIG_SHAwECDSA; /* this is the only type supported */
        verAttrib.MsgLen = buffLen;
        verAttrib.SigLen = signBuffLen;
    
        resultLen = 4;
    
        int verifyResult = 0;
    
        rc = sl_NetUtilCmd(SL_NETUTIL_CRYPTO_CMD_VERIFY_MSG, (_u8 *) &verAttrib,
                           sizeof(SlNetUtilCryptoCmdVerifyAttrib_t), (const _u8 *) base64encode,
                           buffLen + signBuffLen, (_u8 *) &verifyResult, &resultLen);
    
        if (rc < 0)
        {
            ASSERT_ON_ERROR(rc, "sl_NetUtilCmd() failed");
        }
        else
        {
            WMDebugInfo(DEBUG_LOG, "sing buffer verification result %d ", verifyResult);
        }
        return verifyResult;
    }
    
    // Signing the buffer using given index
    static int sing_buffer_using_index(uint32_t index, uint8_t* buff , uint16_t buffLen , uint8_t* signBuff , uint16_t *signBuffLen)
    {
        int rc = -1;
    
        if(buff == NULL)
        {
            SHOW_ERROR(rc, "buffer is null");
            return rc;
        }
    
        if (buffLen >= 1500)
        {
            SHOW_ERROR(rc, "buffer length is too large");
            return rc;
        }
    
        SlNetUtilCryptoCmdSignAttrib_t signAttrib;
    
        signAttrib.Flags = 0;
        signAttrib.ObjId = index;
        signAttrib.SigType = SL_NETUTIL_CRYPTO_SIG_SHAwECDSA; /* this is the only type supported */
    
        rc = sl_NetUtilCmd(SL_NETUTIL_CRYPTO_CMD_SIGN_MSG, (uint8_t *) &signAttrib,
                           sizeof(SlNetUtilCryptoCmdSignAttrib_t), buff, buffLen, signBuff,
                           signBuffLen);
    
        if (rc < 0)
        {
            ASSERT_ON_ERROR(rc, "sl_NetUtilCmd() failed");
        }
    
        return rc;
    }
    
    // Process for Creating Public key, signing message and verifying 
    int decription_method(WM_https_register_get_ts *WM_https_register_get)
    {
        uint8_t buf[SL_NETUTIL_CMD_BUFFER_SIZE];
    
        int i = 0;
    
        uint16_t configLen = 255;
    
        if(generate_public_key_from_index(0, SL_NETUTIL_CRYPTO_PUBLIC_KEY, (uint8_t*)buf, (uint16_t*)&configLen) == 0)
        {
            WMDebugInfo(NO_CRLF, "\r\n\r\n");
    
            WMDebugInfo(NO_CRLF, "key result : ");
    
            for (i = 0; i < configLen; i++)
            {
                sprintf(&rawValueBuffer[i], "%02x", buf[i]);
    
                WMDebugInfo(NO_CRLF, "%02x", buf[i]);
            }
    
            WMDebugInfo(NO_CRLF, "\r\n\r\n");
        }
    
        configLen = 255;
    
        MQTTPayload_ts signaturePayload;
    
        uint16_t len = 0;
    
        len = Make_payload_for_signature(&signaturePayload);
    
        if (len == 0)
        {
            ASSERT_ON_ERROR(-1, "JSON packed creation failed");
        }
    
        WMDebugInfo(DEBUG_LOG, "signature payload %s", signaturePayload.jsonPayload);
    
        if(sing_buffer_using_index(0, (uint8_t*)signaturePayload.jsonPayload, signaturePayload.len, (uint8_t*)signatureBuffer, (uint16_t*)&configLen) == 0)
        {
            WMDebugInfo(NO_CRLF, "\r\n\r\n");
    
            WMDebugInfo(NO_CRLF, "signature result : ");
    
            for (i = 0; i < configLen; i++)
            {
                sprintf(&rawValueBuffer[i], "%x", signatureBuffer[i]);
    
                WMDebugInfo(NO_CRLF, "%x", signatureBuffer[i]);
            }
    
            WMDebugInfo(NO_CRLF, "\r\n\r\n");
    
            WMDebugInfo(NO_CRLF, "signature result : %s", rawValueBuffer);
    
            WMDebugInfo(NO_CRLF, "\r\n\r\n");
    
        }
    
        if(verify_sign_buffer_using_index(0, (uint8_t*)signaturePayload.jsonPayload, signaturePayload.len, (uint8_t*)signatureBuffer, configLen) == 0)
        {
            WMDebugInfo(DEBUG_LOG, "sing buffer verification passed");
    
        }
        else
        {
            WMDebugInfo(DEBUG_LOG, "sing buffer verification failed ");
        }
    
        return 0;
    }

  • Yes, entry0 is persistent and unique per device.

    I briefly check your code and it seems fine.

    Br,

    Kobi

  • Dear Kobi,

    Thank you for the conforming.

    Here generating index 0 public key will be persistent and immutable ? or it will change while generating public key from the index 0?

  • You can't generate the key for index 0. it is persistent and immutable.

    You can just read the public key which will always be the same.

    You can also read the CSR for this device key.

    br,

    Kobi

  • Dear kobi.

    Thank you for the replying me..

    This is more enough information.

    Thanks!