diff options
author | Raef Coles <raef.coles@arm.com> | 2021-06-18 08:48:17 +0100 |
---|---|---|
committer | Raef Coles <raef.coles@arm.com> | 2021-10-07 09:10:40 +0100 |
commit | 148b947b24e59e2a4535102df4e4b387ad03da6b (patch) | |
tree | bbf4cb79fc631ee86b4980edfaa253f350bb285a /platform/include | |
parent | db07170a34ffe6e17bc68294bac37091023bdee1 (diff) | |
download | trusted-firmware-m-148b947b24e59e2a4535102df4e4b387ad03da6b.tar.gz |
Platform: Add OTP api and flash implementation
Add an OTP HAL definition, and a default implementation that uses
internal flash to emulate OTP semantics. Prepare code to share that
space with the NV counters that will remain in flash. Add a cmake config
option to allow alternate OTP implementations.
Change-Id: I7cc0d69eedabc46c857d421c18103f9bd5a3d3ce
Signed-off-by: Raef Coles <raef.coles@arm.com>
Diffstat (limited to 'platform/include')
-rw-r--r-- | platform/include/tfm_plat_otp.h | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/platform/include/tfm_plat_otp.h b/platform/include/tfm_plat_otp.h new file mode 100644 index 0000000000..b2959afd54 --- /dev/null +++ b/platform/include/tfm_plat_otp.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __TFM_PLAT_OTP_H__ +#define __TFM_PLAT_OTP_H__ + +#include <stdint.h> +#include <stddef.h> +#include "tfm_plat_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum tfm_otp_element_id_t { + PLAT_OTP_ID_HUK = 0, + PLAT_OTP_ID_IAK, + PLAT_OTP_ID_IAK_LEN, + PLAT_OTP_ID_IAK_TYPE, + PLAT_OTP_ID_IAK_ID, + + PLAT_OTP_ID_BOOT_SEED, + PLAT_OTP_ID_LCS, + PLAT_OTP_ID_IMPLEMENTATION_ID, + PLAT_OTP_ID_HW_VERSION, + PLAT_OTP_ID_VERIFICATION_SERVICE_URL, + PLAT_OTP_ID_PROFILE_DEFINITION, + + PLAT_OTP_ID_BL2_ROTPK_0, + PLAT_OTP_ID_BL2_ROTPK_1, + PLAT_OTP_ID_BL2_ROTPK_2, + + PLAT_OTP_ID_NV_COUNTER_BL2_0, + PLAT_OTP_ID_NV_COUNTER_BL2_1, + PLAT_OTP_ID_NV_COUNTER_BL2_2, + + PLAT_OTP_ID_BL1_ROTPK_0, + + PLAT_OTP_ID_NV_COUNTER_BL1_0, + + PLAT_OTP_ID_ENTROPY_SEED, + + PLAT_OTP_ID_MAX = UINT32_MAX, +}; + +/* These are separate from the tfm_security_lifecycle_t definitions because here + * the possible transitions are encoded by using the property that OTP bits can + * be changed from a 0 to a 1, but not from a 1 to a 0. + * + * For example: + * If the device is in PLAT_OTP_LCS_SECURED, it can transition to + * PLAT_OTP_LCS_DECOMMISSIONED by setting bit 3, but cannot transition back to + * PLAT_OTP_LCS_PSA_ROT_PROVISIONING as that would require setting bit 2 to 0, + * which cannot be done as per OTP semantics. + * + * NON_PSA_ROT_DEBUG and RECOVERABLE_PSA_ROT_DEBUG must be handled separately to + * OTP memory as they are reversible transitions from SECURED, and OTP cannot + * handle reversible transitions. + */ +enum plat_otp_lcs_t { + PLAT_OTP_LCS_ASSEMBLY_AND_TEST = 0x0, + PLAT_OTP_LCS_PSA_ROT_PROVISIONING = 0x1, + PLAT_OTP_LCS_SECURED = 0x3, + PLAT_OTP_LCS_DECOMMISSIONED = 0x7, + PLAT_OTP_LCS_UNKNOWN = 0xF, + PLAT_OTP_LCS_MAX = UINT32_MAX, +}; + +/** + * \brief Initialises OTP storage. + * + * \return TFM_PLAT_ERR_SUCCESS if the + * initialization succeeds, otherwise + * TFM_PLAT_ERR_SYSTEM_ERR + */ +enum tfm_plat_err_t tfm_plat_otp_init(void); + +/** + * \brief Reads the given OTP element. + * + * \param[in] id ID of the element to read. + * \param[in] out_len Size of the buffer to read the element + * into in bytes. + * \param[out] out Buffer to read the element into. + * + * + * \retval TFM_PLAT_ERR_SUCCESS The element is read successfully. + * \retval TFM_PLAT_ERR_UNSUPPORTED The given element has not been + * instanciated in OTP memory by this + * particular platform. + * \retval TFM_PLAT_ERR_SYSTEM_ERR An unspecified error occurred. + */ +enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id, + size_t out_len, uint8_t *out); + +/** + * \brief Writes the specified bytes to the given + * OTP element. + * + * \param[in] id ID of the element to write. + * \param[in] in_len Size of the buffer to write to the + * element in bytes. + * \param[in] in Pointer to the buffer to write to the + * element. + * + * \note This function must implement the OTP + * writing semantics, where any bit + * currently set to 1 cannot be set to 0. + * If such a write is requested, the + * function should return an error code and + * not alter the contents of OTP memory. + * + * \retval TFM_PLAT_ERR_SUCCESS The OTP is written successfully + * \retval TFM_PLAT_ERR_UNSUPPORTED The given element has not been + * instanciated in OTP memory by this + * particular platform. + * \retval TFM_PLAT_ERR_SYSTEM_ERR An unspecified error occurred. + */ +enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id, + size_t in_len, const uint8_t *in); + +/** + * \brief Returns the size of a given OTP element. + * + * \param[in] id ID of the element. + * \param[out] size Size of the element. + * + * \retval TFM_PLAT_ERR_SUCCESS The size is return successfully. + * \retval TFM_PLAT_ERR_UNSUPPORTED The given element has not been + * instanciated in OTP memory by this + * particular platform. + * \retval TFM_PLAT_ERR_SYSTEM_ERR An unspecified error occurred. + */ +enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id, + size_t *size); + +#ifdef __cplusplus +} +#endif + +#endif /* __TFM_PLAT_OTP_H__ */ |