Skip to content

Shielded Connection 101

pwiegele edited this page Dec 30, 2020 · 15 revisions

Introduction

The OPTIGA™ Shielded Connection enables a protected (Integrity and Confidentiality) communication between the OPTIGA™ and a corresponding Host platform as depicted in figure below

This section provides information regarding the set up and usage of Shielded Connection in the target device application. The OPTIGA™ supports the Shielded Connection using a pre-shared secret (Platform Binding Secret) between the OPTIGA™ and a corresponding host platform. Infineon I2C protocol specification v2.02 explains internal details of establishing the shielded connection; e.g., negotiation and crypto algorithms used for the protection in the section Presentation Layer (see also this page)

Pairing

Preconditions to establish the Shielded Connection is to pair the OPTIGA™ with a host. The pre-shared secret is established during first boot/initialization sequence. The Use Case: Pair OPTIGA™ with Host (Pre-Shared Secret based) depicts the pairing process. The pal_os_datastore is an abstraction layer for writing and reading a platform binding secret to/from the host platform. This has to be adapted to the particular host platform needs. During the Shielded Connection establishment, the optiga_comms_ifx_i2c module invokes pal_os_datastore_read function. Below you can find an example:

Note: This sample updates the life cycle state of platform binding shared secret (used for shielded connection) to operational state. This can’t be reverted. Hence the example intentionally disables the step to update the metadata. Please take care of the sequence while using the provided sample.

Update Platform Binding Secret during runtime (Pre-Shared Secret based) sample code
/**
* \copyright
* MIT License
*
* Copyright (c) 2018 Infineon Technologies AG
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE
*
* \endcopyright
*
* \author  Infineon Technologies AG
*
* \file    example_pair_host_and_optiga_using_pre_shared_secret.c
*
* \brief   This file provides an example for pairing the Host and OPTIGA using a preshared secret.
*
* \ingroup
* @{
*/

#include "optiga/optiga_util.h"
#include "optiga/optiga_crypt.h"

#include "optiga/pal/pal_os_datastore.h"

extern void example_log_execution_status(const char_t* function, uint8_t status);
extern void example_log_function_name(const char_t* function);

/**
 * Platform Binding Shared Secret (0xE140) Metadata to be updated
 */
static uint8_t platform_binding_shared_secret_metadata_final [] = { 
    //Metadata to be updated
    0x20, 0x11,
        // LcsO to be set to Operational
        0xC0, 0x01, 
            // Operational
            0x07,
        // Change/Write Access tag 
        0xD0, 0x03,
            // Conf with E140 
            // This allows updating the binding secret during the runtime using shielded connection
            0x20, 0xE1, 0x40,
        // Read Access tag
        0xD1, 0x01, 
            // Never
            0xFF, 
        // Execute Access tag
        0xD3, 0x01, 
            // Always
            0x00, 
        // Data object Type - to be platform binding secret type
        0xE8, 0x01, 
            // Always
            0x22, 
 };

/**
 * Callback when optiga_util_xxxx operation is completed asynchronously
 */
static optiga_lib_status_t optiga_lib_status;
static void optiga_lib_callback(void * context, optiga_lib_status_t return_status)
{
    optiga_lib_status = return_status;
}

/**
 * The below example demonstrates pairing the Host and OPTIGA using a preshared secret for the first time.
 *
 * Note:
 * If the below example is executed once, the LcsO of Platform Binding shared secret is set to Operational.
 * The LcsO can't be reverted to previous states.
 * Please ensure the access conditions and other required settings in the metadata must be accordingly 
 * before setting the LcsO to operational state.
 *
 * Preconditions: The optiga_util_open_application must be executed before invoking the below example.
 *
 */
void example_pair_host_and_optiga_using_pre_shared_secret(void)
{
    uint16_t bytes_to_read;
    uint8_t platform_binding_secret[64];
    uint8_t platform_binding_secret_metadata[50];
    uint8_t logging_status = 0;
    
    optiga_lib_status_t return_status;
    optiga_util_t * me_util = NULL;
    optiga_crypt_t * me_crypt = NULL;

    example_log_function_name(__FUNCTION__);

    do
    {
        /**
         * 1. Create OPTIGA Util and Crypt Instances
         */
        me_util = optiga_util_create(0, optiga_lib_callback, NULL);
        if (NULL == me_util)
        {
            break;
        }

        me_crypt = optiga_crypt_create(0, optiga_lib_callback, NULL);
        if (NULL == me_crypt)
        {
            break;
        }

        /**
         * 2. Read Platform Binding Shared secret (0xE140) data object metadata from OPTIGA 
         *    using optiga_util_read_metadata.
         */
        bytes_to_read = sizeof(platform_binding_secret_metadata);
        optiga_lib_status = OPTIGA_LIB_BUSY;
        return_status = optiga_util_read_metadata(me_util,
                                                  0xE140,
                                                  platform_binding_secret_metadata,
                                                  &bytes_to_read);

        if (OPTIGA_LIB_SUCCESS != return_status)
        {
            break;
        }

        while (optiga_lib_status == OPTIGA_LIB_BUSY)
        {
            //Wait until the optiga_util_read_metadata operation is completed
        }

        if (OPTIGA_LIB_SUCCESS != optiga_lib_status)
        {
            //Reading metadata data object failed.
            break;
        }

        /**
         * 3. Validate LcsO in the metadata.
         *    Skip the rest of the procedure if LcsO is operational(0x07)
         */
        if (platform_binding_secret_metadata[5] >= 0x07)
        {
            // The LcsO is already greater than or equal to operational state
            break;
        }

        /**
         * 4. Generate Random using optiga_crypt_random
         *       - Specify the Random type as TRNG
         *    a. The recommended size of secret is 64 bytes which is maximum supported.
         *       the minimum recommended is 32 bytes.
         *    b. If the host platform doesn't support random generation, 
         *       use OPTIGA to generate the maximum size chosen.
         *       else choose the appropriate length of random to be generted by OPTIGA
         *
         */
        optiga_lib_status = OPTIGA_LIB_BUSY;
        return_status = optiga_crypt_random(me_crypt, 
                                            OPTIGA_RNG_TYPE_TRNG, 
                                            platform_binding_secret,
                                            sizeof(platform_binding_secret));
        if (OPTIGA_LIB_SUCCESS != return_status)
        {
            break;
        }

        while (optiga_lib_status == OPTIGA_LIB_BUSY)
        {
            //Wait until the optiga_crypt_random operation is completed
        }

        if (OPTIGA_LIB_SUCCESS != optiga_lib_status)
        {
            break;
        }
         
        /**
         * 5. Generate random on Host
         *    If the host platform doesn't support, skip this step
         */


        /**
         * 6. Write random(secret) to OPTIGA platform Binding shared secret data object (0xE140)
         */
        optiga_lib_status = OPTIGA_LIB_BUSY;
        return_status = optiga_util_write_data(me_util, 
                                               0xE140, 
                                               OPTIGA_UTIL_ERASE_AND_WRITE, 
                                               0,
                                               platform_binding_secret, 
                                               sizeof(platform_binding_secret));
        if (OPTIGA_LIB_SUCCESS != return_status)
        {
            break;
        }

        while (optiga_lib_status == OPTIGA_LIB_BUSY)
        {
            //Wait until the optiga_util_write_data operation is completed
        }

        if (OPTIGA_LIB_SUCCESS != optiga_lib_status)
        {
            //writing data to a data object failed.
            break;
        }

        /**
         * 7. Write/store the random(secret) on the Host platform
         *
         */
        pal_os_datastore_write(OPTIGA_PLATFORM_BINDING_SHARED_SECRET_ID, 
                               platform_binding_secret,
                               sizeof(platform_binding_secret));

#if 0        
        /**
         * 8. Update metadata of OPTIGA Platform Binding shared secret data object (0xE140)
         */
        optiga_lib_status = OPTIGA_LIB_BUSY;
        return_status = optiga_util_write_metadata(me_util, 
                                                   0xE140,
                                                   platform_binding_shared_secret_metadata_final,
                                                   sizeof(platform_binding_shared_secret_metadata_final));

        if (OPTIGA_LIB_SUCCESS != return_status)
        {
            break;
        }

        while (optiga_lib_status == OPTIGA_LIB_BUSY)
        {
            //Wait until the optiga_util_write_metadata operation is completed
        }

        if (OPTIGA_LIB_SUCCESS != optiga_lib_status)
        {
            //writing metadata to a data object failed.
            break;
        }
#endif
        logging_status = 1;

    } while(FALSE);

    if(me_util)
    {
        //Destroy the instance after the completion of usecase if not required.
        optiga_util_destroy(me_util);
    }
    if(me_crypt)
    {
        //Destroy the instance after the completion of usecase if not required.
        optiga_crypt_destroy(me_crypt);
    }
    example_log_execution_status(__FUNCTION__, logging_status);
}

The use case sequence diagram is depicted below:

Usage

In the OPTIGA™ Host Library, the Shielded Connection feature can be enabled/disabled using the macro OPTIGA_COMMS_SHIELDED_CONNECTION in optiga_lib_config.h) with the required default protection level OPTIGA_COMMS_DEFAULT_PROTECTION_LEVEL in optiga_lib_config.h).

For the protected communication (Shielded Connection) between a host and the OPTIGA™, an instance of optiga_util or optiga_crypt needs to be updated with the required protection level before invoking the operations provided by optiga_util or optiga_crypt using OPTIGA_UTIL_SET_COMMS_PROTECTION_LEVEL and OPTIGA_CRYPT_SET_COMMS_PROTECTION_LEVEL respectively.


For example, to enable a full: i.e. command and response, protection for deriving the decryption keys in FW update use case using the pre-shared secret from OPTIGA™

  • Invoke
      OPTIGA_CRYPT_SET_COMMS_PROTECTION_LEVEL(me_crypt, OPTIGA_COMMS_FULL_PROTECTION)
      optiga_crypt_tls_prf_sha256 (me_crypt, shard_secret_oid, …);

See optiga_crypt_tls_prf_sha256


In case of re-establishing the Shielded Connection periodically, the protection_level |OPTIGA_COMMS_RE_ESTABLISH can be set to the instance using above specified. The access layer will take care of rescheduling the shielded connection internally.

For example, to enable re-establishing the shielded connection with response protection for the data object read data operation.

  OPTIGA_UTIL_SET_COMMS_PROTECTION_LEVEL(me_util, OPTIGA_COMMS_RESPONSE_PROTECTION|OPTIGA_COMMS_RE_ESTABLISH)`
  optiga_util_read_data (me_util, oid, …);

See optiga_util_read_data

Based on the above settings, the access layer activates the Shielded Connection between a host and the OPTIGA™. These settings reset automatically to the default protection level; i.e. OPTIGA_COMMS_DEFAULT_PROTECTION_LEVEL once after the operation is invoked. The Use Case: Update Platform Binding Secret during runtime (Pre-Shared Secret based) depicts a process of updating the platform binding secret periodically using the shielded connection at runtime.

Security Counter

If you are using the OPTIGA™ Shielded Connection be aware that it has an impact on the security counter of the secure element. Each time the shielded connection is established between host MCU and the secure element the security counter is incremented. If a certain threshold is reached the MCU has to backoff and wait. (times can be found in the Solution Reference Manual). After each power up of the device the shielded connection will be newly set up which affects the security counter.

Security Guidance

The security level of the Shielded connection is as high as typical microcontroller/Host side hardware security level.

  • The recommended length of Platform binding shared secret is minimum 32 bytes.
  • Updating the Platform Binding shared secret during the run time using the shielded connection is recommended.
    • enable the monotonic counter and reduce the max number of usages to XYZ using monotonic counter and update the secret on chip periodically.
    • To enforce this, the write access conditions for the Platform binding data object must be set accordingly.
  • Secure binding (using the Platform binding shared secret) and usage restriction using the Monotonic counters enables additional usage restriction for the critical asset (e.g. RSA keys and shared secrets) if assets are not intended to use extremely.
  • It is recommended to use the shielded connection for EncryptAsym (which uses a session context) command based operations which enforces the usage of session context.