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.

two way key agreement using ECC

Part Number: CC1350

I am building a cryptographic project on CC1350. I started with the AES key agreement example as we do not use TI-RTOS, I wrote the functions for encryption, decryption and initializations using the driverlib APIs. I succeeded in encrypting and decrypting the data correctly.

Now, I want to implement the key exchanging scheme to have both public and private keys and drive the shared secret from them.

1. How can I do so using the rom_crypto functions, I tried to follow the steps in the AES key agreement example, but it did ot work out. How to pick a random private key and drive a publc key from it in side A (forexample) and the same for side B (forexample). Then, take the private key of A with the public key of B and generate a shared secret that is equal to the private number of B with the public key of A?
2. Do I need a same initial number for both sides so that they can start with?

        PRCMPeripheralRunEnable(PRCM_PERIPH_CRYPTO);
        PRCMPeripheralSleepEnable(PRCM_PERIPH_CRYPTO);
        PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_CRYPTO);

        PRCMPeripheralRunEnable(PRCM_PERIPH_TRNG);
        PRCMPeripheralSleepEnable(PRCM_PERIPH_TRNG);
        PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_TRNG);
        PRCMLoadSet();

TRNGEnable();

ECC_initialize(eccWorkzone);

static void Generate_Random_Bytes(uint8_t* buffer, uint8_t size)
{
        uint32_t i,j,k,l;

        j= (uint32_t)(0x8000);
        k= (uint32_t)(0x01000000);
        l= (uint32_t)15;

        TRNGConfigure(j,k,l);
        for(i=0; i<size; i++)
        {
            buffer[i]= TRNGNumberGet(TRNG_HI_WORD);
        }
}


static void Generate_Keys(uint8_t *privateKey, uint8_t *sharedKeyX, uint8_t *sharedKeyY)
{
        Generate_Random_Bytes(&privateKey[ECC_KEY_DATA_OFFSET_BYTES], ECC_KEY_BYTES);

        /* Generate public key pair for this unit by using elliptic curve cryptography
         * The newly generated local private key is used as the input */
        ECC_generateKey((uint32_t *)privateKey,
                                 (uint32_t *)privateKey,
                                 (uint32_t *)sharedKeyX,
                                 (uint32_t *)sharedKeyY);
}

void Create_Public_Key_Packet(uint8_t* packet)
{
        Generate_Keys(Crypto_Config[0].priv_key, Crypto_LevX[1].shared_key_x, Crypto_LevX[1].shared_key_y);

        /* Load public key and packet metadata to the txPacket */
        packet[PACKET_IDENT_BYTE] = PUBLIC_KEY_PACKET;
        packet[PACKET_LENGTH_BYTE] = PUBLIC_KEY_PACKET_LENGTH;

        memcpy(&packet[PUBLIC_KEY_PKEY_X_OFFSET], &Crypto_LevX[1].shared_key_x[ECC_KEY_DATA_OFFSET_BYTES], ECC_KEY_BYTES);
        memcpy(&packet[PUBLIC_KEY_PKEY_Y_OFFSET], &Crypto_LevX[1].shared_key_y[ECC_KEY_DATA_OFFSET_BYTES], ECC_KEY_BYTES);
}

static void Generate_AES_Key(uint8_t* privateKey, uint8_t *sharedKeyX, uint8_t *sharedKeyY, uint8_t *sharedSecretKeyX, uint8_t *sharedSecretKeyY, uint8_t* sym_key)
{
    uint8_t status = ECC_ECDH_COMMON_KEY_OK;
        /* Buffers for the computed shared secret */

        /* Compute the shared secret using this units own private key + public keys from the other unit */
        status = ECC_ECDH_computeSharedSecret((uint32_t *)privateKey,
                                              (uint32_t *)sharedKeyX,
                                              (uint32_t *)sharedKeyY,
                                              (uint32_t *)sharedSecretKeyX,
                                              (uint32_t *)sharedSecretKeyY);

        if(status != ECC_ECDH_COMMON_KEY_OK) {
            /* Computation of shared secret failed */
            while (1);
        }

        /* AES keys used by the crypto module are 128-bit long, so truncate the generated entropy */
        memcpy(&sym_key[ECC_KEY_DATA_OFFSET_BYTES], &sharedSecretKeyX[ECC_KEY_DATA_OFFSET_BYTES], ECC_AES_KEY_BYTES);
}

Update:
I have problems in using the ECC function, sometimes it does not return and when I change in the arrays and the pointers I use in the code, it returns and generate the keys correctly. I think the problem is in the memory allocated for the ECC workzone and I am statically allocating it.

uint32_t  eccworkzone[3*275];

  • Hi,

    Are you using BLE? Are you using LE Secure Connections? (ECC keys are not available for Legacy pairing). In this case, BLE already how to use the secret keys, please review our SimpleLink Academy documentation for details (you can be curious and have a look to the Advanced Security lab provided in the CC13X2 / CC26X2 labs too).

    For BLE, ECC is used to generate the private keys (so devices do not have to agree on a common seed).

    Regards,

  • No, I am not using the BLE. I managed to generate the keys correctly, but I have a very strange issue.

    1. when I keep this code as it is shown, the kes are generated very well and the code works, but when I erase the data_Sample and the Decryp_data arrays from the main, the code is stuck in the ECC_ECDH_computeSharedSecret() function and I don't know why?!

  • I am statically allocating the workzone for the ECC, so is it something related to the memory?

  • I observed that the following elements in the struct, that points to local arrays in the main, are being modified when I generate the keys, so it is a problem in allocating the workzone for the ECC right?

  • Hi,

    Good to see that you are getting results.

    Can you verify if the issue might be due to an alignment issue? Can you also find the address of the buffers in the two cases?

    Thanks and regards,