NXP EdgeLock® SE05x execution on TEE: enabling the GP Secure Channel Protocol 03

Photo of Jorge Ramirez Ortiz

Posted on Feb 20, 2022 by Jorge Ramirez Ortiz

10 min read

Linux microPlatform™ release v85 includes support for the OP-TEE upstream version of the NXP EdgeLock® SE05x integrating Plug-and-Trust revision 03.03.00.

NXP EdgeLock® SE05x Execution on TEE (Part II)

Enabling the GP Secure Channel Protocol 03

Global Platform (GP) is a non-profit technical standards organization whose mission is to facilitate secure interoperability across industries; it does so by providing technologies and certifications for trusted digital services and devices.

To comply with this standardization effort, OP-TEE implements the GP TEE Client API and the TEE Internal Core API specifications. They describe how to interface securely to a TEE from a rich operating environment such as Linux and how the Trusted Applications would communicate with the TEE core.

Global Platform provides the Secure Channel Protocol 03 specification with the goal of helping trusted devices to exchange data in an open channel; the specification defines how devices can securely exchange data over an unsecure communication channel while guaranteeing mutual authentication, data integrity, and confidentiality. It specifies how to establish dedicated encrypted sessions between devices, how to authenticate the messages being exchanged and how to operate and terminate those sessions.

For detailed information on the protocol you can refer to the specifications.

Since the NXP EdgeLock SE05x devices include native support for the secure channel protocol 03 (SCP03), this blog entry will cover how it is enabled in the OP-TEE driver. This is done with the help of the NXP Plug-and-Trust middleware. We will also cover some of the caveats and features currently present in the OP-TEE upstream code.

OP-TEE: Establishing the Session

Establishing the SCP03 communication channel between the TrustZone and the NXP SE05x uses symmetric block ciphers and message authentication codes.

It uses three Advanced Encryption Standard (AES) keys that are known to both host and device. These static keys are an intermediate set of keys used to help generate the session keys that later on will be used to perform encryption, decryption, and verification of the application protocol data unit (APDU) messages.

For a description of the functional architecture and SCP03 configuration sequence, checkout the NXP application note. In contrast to what is being described in the note, OP-TEE does not use the TrustZone to permanently store the SCP03 static keys. Instead OP-TEE uses it as a cryptographic interface offered to the normal world via the PKCS#11 TA and internally to the TEE Core.

In OP-TEE, these static keys are defined in the scp_config.c file. SE05x versions are identified by their OEFIDs and are pre-programmed with different keys. The keys are documented in the corresponding product data sheets.

When the OP-TEE SE05x driver is loaded, it first establishes an unsecure session to retrieve device information. This includes the applet version that executes in the secure element, and the device OEFID (the device class identifier). The applet version is required to confirm that the Plug-and-Trust middleware has been built with the right configuration.

Enabling the SCP03 session is selectable via built time configuration options. This can be done either during early firmware initialization or at a later stage via a trusted application using the U-Boot scp03 command or using libseteec from a Linux client.

The logic used to enable the SCP03 session will first attempt to use keys passed at build time through configuration flags. If a session can not be established using those keys, it will attempt to derive the keys using the platform hardware unique key (we will come back to this later). Failing that, since the OEFID is known at that point, it will fallback to trying the OEFID keys.

sss_status_t se050_enable_scp03(sss_se05x_session_t *session)
{
	struct se050_scp_key keys = { };
	sss_status_t status = kStatus_SSS_Success;
	enum se050_scp03_ksrc key_src[] = { SCP03_CFG, SCP03_DERIVED,
		SCP03_OEFID };
	size_t i = 0;

	if (se050_scp03_enabled())
		return kStatus_SSS_Success;

	for (i = 0; i < ARRAY_SIZE(key_src); i++) {
		status = se050_scp03_get_keys(&keys, key_src[i]);
		if (status != kStatus_SSS_Success)
			continue;

		if (session->subsystem)
			sss_se05x_session_close(session);

		if (!se050_core_early_init(&keys)) {
			se050_scp03_set_enable(key_src[i]);
			return kStatus_SSS_Success;
		}

		sss_host_session_close(&se050_ctx.host_session);
	}

	return kStatus_SSS_Fail;
}

OP-TEE: Rotating the SCP03 Keys

As previously mentioned, the SE05x secure elements are shipped with a predefined set of static keys stored in their Non Nolatile Memory (NVM). For security reasons, these keys can be rotated and new ones programmed back to NVM, a process defined in the GP specification.

It is a prerequisite that key rotation requests only occur during already established SCP03 sessions.

Once the static keys have been rotated in the secure element and the new keys have been written to the device NVM, the session keys should be re-calculated. To do this, the running session has to be closed and then open again using the new static keys.

TEE_Result crypto_se_enable_scp03(bool rotate_keys)
{
	sss_status_t status = kStatus_SSS_Success;

	status = se050_enable_scp03(se050_session);
	if (status != kStatus_SSS_Success)
		return TEE_ERROR_GENERIC;

	if (rotate_keys) {
		if (IS_ENABLED(CFG_CORE_SE05X_SCP03_PROVISION)) {
			status = se050_rotate_scp03_keys(&se050_ctx);
			if (status != kStatus_SSS_Success)
				return TEE_ERROR_GENERIC;

			return TEE_SUCCESS;
		}
		return TEE_ERROR_BAD_PARAMETERS;
	}
	return TEE_SUCCESS;
}

Support for key rotation has been disabled during firmware boot and can only be triggered at a later stage by U-boot or Linux.

When OP-TEE performs the SCP03 key rotate operation, it uses the platform's hardware unique key to derive the new set of static keys. Doing this avoids having to store, protect and manage the static keys across firmware upgrades since they will be recalculated after every boot.

Key rotation - as implemented in the SE05x OP-TEE driver - is a one-time-only operation.

To avoid leaking secrets, we must confirm that the keys used to derive the SCP03 static keys are immutable, secure and non-extractable. Key derivation should only be requested when the bootrom has been configured to verify the boot image signature. This requirement however is not being enforced by OP-TEE, so be aware.

sss_status_t se050_scp03_subkey_derive(struct se050_scp_key *keys)
{
	struct {
		const char *name;
		uint8_t *data;
	} key[3] = {
		[0] = { .name = "dek", .data = keys->dek },
		[1] = { .name = "mac", .data = keys->mac },
		[2] = { .name = "enc", .data = keys->enc },
	};
	uint8_t msg[SE050_SCP03_KEY_SZ + 3] = { 0 };
	size_t i = 0;

	if (tee_otp_get_die_id(msg + 3, SE050_SCP03_KEY_SZ))
		return kStatus_SSS_Fail;

	for (i = 0; i < ARRAY_SIZE(key); i++) {
		memcpy(msg, key[i].name, 3);
		if (huk_subkey_derive(HUK_SUBKEY_SE050, msg, sizeof(msg),
				      key[i].data, SE050_SCP03_KEY_SZ))
			return kStatus_SSS_Fail;
	}

	return kStatus_SSS_Success;
}

Enabling secure boot is a sometimes convoluted process that involves burning asymmetric keys or hashes on eFuses in the SoC; the bootrom then use the information stored in these eFuses to verify the signature of the firmware images before allowing them to boot.

One expected characteristic of the platform's hardware unique key (HUK) is that when the SoC is placed in the secure boot state (and not before then) the HUK identifier becomes stable and accessible only by the Trust Zone.

You can check this implementation done for the Xilinx UltraScale+ MPSoC platform. Note that the HUK is different whether the board boots securely or not so software development can proceed without ever exposing the real HUK.

Because of the level of security implicit in this identifier, the HUK is also used to derive the keys used to access the Replay Protected Memory Block partition (RPMB) in the embedded multimedia card (eMMC).

As it happens with the RPMB keys, the SCP03 static keys should not be rotated when booting in non-secure mode since access to SE05x device will be lost once the board is secured (because the HUK will change). And once the static keys are lost, the SE05x device is non-recoverable.

OP-TEE: T=1 Half Duplex Communication with SCP03

Once the secure session has been established, all the communication is encrypted and authenticated using the session keys. These are different from the SCP03 static keys that we discussed earlier: the dynamic keys associated with the session are generated at runtime during session initialization.

The magic for this happens in the OP-TEE adapted version of the NXP Plug-and-Trust middleware. This is a component that gets built-in as part of the SE05x driver after this commit.

To calculate the session keys, the Plug-and-Trust middleware needs to perform some cryptographic operations. These have to be provided by the host platform. In the case of OP-TEE they are provided by its libtomcrypt implementation. The operations are referred to as host/user calls in the Plug-and-Trust software stack and they are presented to the middleware by the SE05x driver's glue layer.

It is possible that the calculation of those keys will require the generation of some randomness (unless it is provided at build time, something that we chose not to do in the current software stack). This is the reason behind disabling the SE05x RNG driver when SCP03 is enabled.

As it can be seen in the code snippet below, if the Plug-and-Trust middleware were to call back OP-TEE for some randomness, this could not be provided by the SE05x (would be a catch-22). The code might seem a bit obtuse but it is due to OP-TEE only providing a single source of randomness via its cryptographic API.

sss_status_t glue_rng_get_random(uint8_t *data, size_t len)
{
	if (IS_ENABLED(CFG_NXP_SE05X_RNG_DRV))
		return kStatus_SSS_InvalidArgument;

	if (crypto_rng_read(data, len))
		return kStatus_SSS_Fail;

	return kStatus_SSS_Success;
}

The T=1 half duplex communication protocol implementation between the host and the SE05x device is done in the Plug-and-Trust middleware; in order to facilitate the integration of the Plug-and-Trust middleware on different platforms, this software stack provides hooks that the host needs to implement to guarantee the integrity and confidentiality required by SCP03 on the exchanged APDUs. These are message authentication code algorithms (MAC) and symmetric block ciphers (ENC/DEC). These algorithms will operate on each transceive operation, that is, on every APDU being sent and received to and from the I2C bus.

OP-TEE provides CMAC AES (message authentication) and AES CBC (symmetric block cipher) via libtomcrypt to the Plug-and-Trust middleware. And as before, these are presented via the SE05x driver glue layer.

The following diagram shows the functional flow for a PKCS#11 request needing to access the SE05x (i.e: creating an RSA key) once SCP03 has been enabled:

PKCS#11 accessing the NXP SE05x with SCP03 enabled

Unfortunately at this time, even though other hardware cryptographic device supporting those operations might be available in the platform - i.e: NXP's CAAM or ST's STM32 CRYP - the current OP-TEE cryptographic driver API doesn't have the flexibility required to route these requests back to the hardware. This is something that will hopefully change as support for more devices continue to land in OP-TEE, and the reason for extending the API gains more traction.

OP-TEE: Sharing and Closing the SE05x Session.

There is a single session shared between OP-TEE core and all the Trusted (TA) Pseudo (PTA) Trusted Applications accessing the SE05x device (i.e: PKCS#11, APDU tunnel, key rotation, RNG etc).

Once this session is established it is only closed and restarted either to enable SCP03 or to rotate the SCP03 static keys.

There is a single mutex scheduling access to the device in the Plug-and-Trust repository for the OP-TEE use case. Since the NXP EdgeLock SE05x doesn't keep internal states across requests, APDUs corresponding to different cipher operations can be interleaved.

Summary

We have lightly described how the OP-TEE and the Plug-and-Trust projects interact and co-operate to enable the Global Platform SCP03 protocol. This gives the system a secure communication channel between the host and the SE05x device on the I2C bus.

Our next entry in the series will describe the APDU pseudo trusted application and its use cases: an interface presented by OP-TEE to the normal world that is being leveraged by a number of external tools to access the SE05x device.

    _  _
   | \/ |
\__|____|__/
  |  o  o|           Thumbs Up
  |___\/_|_____||_
  |       _____|__|
  |      |
  |______|
  | |  | |
  | |  | |
  |_|  |_|

Related posts