Importing Custom Wrapped Keys Example#

To import custom wrapped keys into CPMS, you need four fields: value, address, auth, and metadata. The following examples will show how to get the metadata value for an asymmetric and a symmetric key.

Example #1: Importing Custom Wrapped Asymmetric Keys#

  1. In Simplicity Studio, in the Launcher view, click EXAMPLE PROJECTS & DEMOS.

  2. Search for SE Manager.

  3. Create a project from the Platform - SE Manager Digital Signature (ECDSA and EdDSA) example.

    screenshotscreenshot

  4. CPMS will automatically wrap your key and write it into flash. To emulate that for testing, use the Memory System Controller to write the key into flash. To enable the MSC, first open se_manager_signature.slcp.

  5. Open the SOFTWARE COMPONENTS tab.

  6. Search for msc.

  7. Click the MSC Peripheral and click Install.

    screenshotscreenshot

  8. Modify the "create_wrap_asymmetric_key" function of app_se_manager_signature.c to use our "CPMS key". Instead of generating a key, we will import our ecc key. In app_se_manager_signature.c line 255, replace the lines:

    print_error_cycle(sl_se_generate_key(&cmd_ctx, &asymmetric_key_desc), &cmd_ctx);

    with the following:

    // YOUR KEY VALUE GOES HERE:
    static uint8_t user_key[64] =
    {
         0x79, 0x7D, 0x86, 0xE3, 0x5B, 0xAA, 0x03, 0xA5,
         0xEE, 0x09, 0xAB, 0x5E, 0x7E, 0xB1, 0x2D, 0xC3,
         0x92, 0xFC, 0xCE, 0xDC, 0xD0, 0x2A, 0xB0, 0xF7,
         0x56, 0x5E, 0x73, 0x30, 0x86, 0x1D, 0xAE, 0xD5,
         0xDD, 0x8A, 0x84, 0xA2, 0x87, 0x0F, 0xCC, 0x2B,
         0x70, 0x66, 0xAE, 0xE0, 0x88, 0x44, 0x2C, 0xCC,
         0x0C, 0x53, 0xCE, 0x9D, 0x26, 0xBB, 0xB3, 0x04,
         0xA8, 0xB7, 0xB9, 0xE5, 0x20, 0x43, 0x62, 0xAE
    };
    
    sl_se_key_descriptor_t plaintext_desc = {
         .type = key_type,
         .flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY
                  | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY,
         .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
         .storage.location.buffer.pointer = user_key,
         .storage.location.buffer.size = 64
    };
    
    if (sl_se_import_key(&cmd_ctx, &plaintext_desc, &asymmetric_key_desc) != SL_STATUS_OK) return SL_STATUS_FAIL;

    This code will import your key into the Secure Engine, wrap it, then store the wrapped key to the asymmetric_key_buf that asym- metric_key_desc.storage.location.buffer.pointer is pointing to.

    screenshotscreenshot

  9. Next, write the wrapped key blob into flash. Add the following lines to create_wrap_asymmetric_key:

    // YOUR KEY ADDRESS GOES HERE:
    unsigned int wrapped_key_address = 0x00080000;
    
    printf("\nWriting key into flash at 0x%08x...\n", wrapped_key_address);
    
    // Clear out the old wrapped key MSC_ErasePage((uint32_t*)wrapped_key_address);
    
    // Flash the new wrapped key MSC_WriteWord((uint32_t*)wrapped_key_address, asymmetric_key_buf, sizeof(asymmetric_key_buf));
    
    // Update the key descriptor to point to the key in flash asymmetric_key_desc.storage.location.buffer.pointer = (uint8_t*)wrapped_key_address;
  10. Next, print out the keyspec needed for CPMS. Add the following lines to create_wrap_asymmetric_key:

    screenshotscreenshot

    unsigned int keyspec;
    
    if (sli_se_key_to_keyspec(&asymmetric_key_desc, &keyspec) != SL_STATUS_OK) return SL_STATUS_FAIL;
    
    printf("\nKeyspec: 0x%08x\n", keyspec);
    
    return SL_STATUS_OK;
  11. Keys imported using CPMS use a different bus master than the CPU, so the key descriptor needs to be updated. In create_wrap_symmetric_key, edit the symmetric_key_desc.flags field to remove SL_SE_FLAG_ASYMMETRIC_BUF- FER_HAS_PUBLIC_KEY and add SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS (line 229):

    asymmetric_key_desc.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY
                 | SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY
                 | SL_SE_KEY_FLAG_NON_EXPORTABLE
                 | SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS;

    screenshotscreenshot

  12. Build the project.

    screenshotscreenshot

  13. Flash to the target device.

    screenshotscreenshot

  14. In the Debug Adapters window, right click on the adapter for your device and click Launch Console.

    screenshotscreenshot

  15. Click the Serial 1 tab, and then send Enter to start the console.

  16. Reset the device. The program will first ask which type of key you want to use: plaintext, wrapped, or volatile. Type a space, and then press Enter to select the second option, wrapped.

    screenshotscreenshot

  17. Press Enter four more times to see the keyspec printed to the console. When entering a custom wrapped key into CPMS, this value is the Key Metadata value.

    screenshotscreenshot

  18. Now that the key is wrapped and stored in flash, you want to see that the program can use it without having the plaintext key anywhere in the application. Go back to app_se_manager_signature.c and comment out lines 255 to 278 and lines 283 to 289.

    screenshotscreenshot

  19. Now the application simply sets up the key descriptor to point to where we wrote the wrapped key in flash, without knowing the value of the key.

  20. Repeat steps 12 to 17 to verify that the wrapped key can still be used. Note that if the flash is erased (by a commander device unlock command, for instance), this application will fail. It needs the wrapped key to be stored in flash by a previous process.

    screenshotscreenshot

Example #2: Importing Custom Wrapped Symmetric Keys#

  1. In Simplicity Studio, in the Launcher view, click EXAMPLE PROJECTS & DEMOS.

  2. Search for SE Manager.

  3. Create a project from the Platform - SE Manager Block Cipher example:

    screenshotscreenshot

  4. CPMS will automatically wrap your key and write it into flash. To emulate that for testing, use the Memory System Controller to write the key into flash. To enable the MSC, first open se_manager_block_cipher.slcp.

  5. Open the SOFTWARE COMPONENTS tab.

  6. Search for msc.

  7. Click the MSC Peripheral and click Install.

    screenshotscreenshot

  8. Modify the "create_wrap_symmetric_key" function of app_se_manager_block_cipher.c to use the "CPMS key". Instead of generating a key, import the aes key. In app_se_manager_block_cipher.c line 259, replace the lines:

    print_error_cycle(sl_se_generate_key(&cmd_ctx, &symmetric_key_desc), &cmd_ctx);

    with the following:

    // YOUR KEY VALUE GOES HERE:
    static uint8_t user_key[16] =
    {
      0x70, 0xF4, 0x82, 0x4E, 0x49, 0xBD, 0x97, 0xAB,
      0x65, 0x65, 0x32, 0x22, 0xA0, 0x70, 0xB5, 0x16
    };
    
    sl_se_key_descriptor_t plaintext_desc = {
    .type = SL_SE_KEY_TYPE_AES_128,
    .flags = 0,
    .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
    .storage.location.buffer.pointer = user_key,
    .storage.location.buffer.size = 16
    };
    
    if (sl_se_import_key(&cmd_ctx, &plaintext_desc, &symmetric_key_desc) != SL_STATUS_OK) return SL_STATUS_FAIL;

    This code will import your key into the Secure Engine, wrap it, and then store the wrapped key to the symmetric_key_buf that symmetric_key_desc.storage.location.buffer.pointer is pointing to.

    screenshotscreenshot

  9. Next, write the wrapped key blob into flash. Add the following lines to create_wrap_symmetric_key:

    // YOUR KEY ADDRESS GOES HERE:
    unsigned int wrapped_key_address = 0x00080000;
    
    printf("Writing key into flash at 0x%08x...\n", wrapped_key_address);
    
    // Clear out the old wrapped key MSC_ErasePage((uint32_t*)wrapped_key_address);
    
    // Flash the new wrapped key
    MSC_WriteWord((uint32_t*)wrapped_key_address, symmetric_key_buf, sizeof(symmetric_key_buf));
    
    // Update the key descriptor to point to the key in flash symmetric_key_desc.storage.location.buffer.pointer = (uint8_t*)wrapped_key_address;
  10. Next, we'll print out the keyspec that we need for CPMS. Add the following lines to create_wrap_symmetric_key:

    unsigned int keyspec;
    
    if (sli_se_key_to_keyspec(&symmetric_key_desc, &keyspec) != SL_STATUS_OK) return SL_STATUS_FAIL;
    
    printf("\nKeyspec: 0x%08x\n", keyspec);
    
    return SL_STATUS_OK;

    screenshotscreenshot

  11. Keys imported using CPMS use a different bus master than the CPU, so the key descriptor needs to be updated. In cre- ate_wrap_symmetric_key, edit the symmetric_key_desc.flags field to include SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS (line 247):

    symmetric_key_desc.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE | SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS;

    screenshotscreenshot

  12. Build the project.

    screenshotscreenshot

  13. Flash to the target device.

    screenshotscreenshot

  14. In the Debug Adapters window, right click on the adapter for your device and click Launch Console.

    screenshotscreenshot

  15. Click the Serial 1 tab, and then reset the device. The program will first ask which type of key you want to use: plaintext, wrapped, or volatile. Type a space, and then press Enter to select the second option, wrapped.

    screenshotscreenshot

  16. Press Enter once more to see the keyspec printed to the console. When entering a custom wrapped key into CPMS, this value is the "Key Metadata" value.

    screenshotscreenshot

  17. Press Enter two more times to verify that the key can be used without error. Note that if you press Enter after this, the program will try to use that key as a ChaCha20-Poly1305 key, and it will fail.

    screenshotscreenshot

  18. Now that the key is wrapped and stored in flash, you want to see that the program can use it without having the plaintext key anywhere in the application. Go back to app_se_manager_block_cipher.c and comment out lines 259 to 275 and lines 280 to 286.

    screenshotscreenshot

  19. Now the application simply sets up the key descriptor to point to where you wrote the wrapped key in flash, without knowing the value of the key.

  20. Repeat steps 11 to 15 to verify that the wrapped key can still be used. Note that if the flash is erased (by a commander device unlock command, for instance), this application will fail. It needs the wrapped key to be stored in flash by a previous process.

    screenshotscreenshot