aboutsummaryrefslogtreecommitdiff
path: root/platform/include
diff options
context:
space:
mode:
authorRaef Coles <raef.coles@arm.com>2021-06-18 08:48:17 +0100
committerRaef Coles <raef.coles@arm.com>2021-10-07 09:10:40 +0100
commit148b947b24e59e2a4535102df4e4b387ad03da6b (patch)
treebbf4cb79fc631ee86b4980edfaa253f350bb285a /platform/include
parentdb07170a34ffe6e17bc68294bac37091023bdee1 (diff)
downloadtrusted-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.h145
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__ */