1 /*
2  * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __FLASH_OTP_NV_COUNTERS_BACKEND_H__
9 #define __FLASH_OTP_NV_COUNTERS_BACKEND_H__
10 
11 #include "cmsis_compiler.h"
12 
13 #define FLASH_NV_COUNTER_AM 3
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 #define OTP_NV_COUNTERS_INITIALIZED 0xC0DE8112U
19 
20 #ifdef BL2
21 #if defined(MCUBOOT_SIGN_EC384)
22 #define BL2_ROTPK_HASH_SIZE     (48)
23 #define BL2_ROTPK_KEY_SIZE      (100) /* Aligned to 4 bytes */
24 #else
25 #define BL2_ROTPK_HASH_SIZE     (32)
26 #endif /* MCUBOOT_SIGN_EC384 */
27 #if defined(MCUBOOT_SIGN_EC256)
28 #define BL2_ROTPK_KEY_SIZE      (68)  /* Aligned to 4 bytes */
29 #endif /* MCUBOOT_SIGN_EC256 */
30 
31 #ifdef MCUBOOT_BUILTIN_KEY
32 #define BL2_ROTPK_SIZE    BL2_ROTPK_KEY_SIZE
33 #else
34 #define BL2_ROTPK_SIZE    BL2_ROTPK_HASH_SIZE
35 #endif /* MCUBOOT_BUILTIN_KEY */
36 #endif /* BL2 */
37 
38 #if (defined(BL2_ROTPK_SIZE) && (BL2_ROTPK_SIZE > 64))
39 #define OTP_ELEMENT_SIZE_MAX    BL2_ROTPK_SIZE
40 #else
41 #define OTP_ELEMENT_SIZE_MAX    (64)
42 #endif
43 
44 __PACKED_STRUCT flash_otp_nv_counters_region_t {
45     /* Must be the first item */
46     uint32_t init_value;
47 
48 #ifdef PLATFORM_DEFAULT_OTP
49     __PACKED_STRUCT {
50         uint8_t huk[32];
51         uint8_t iak[32];
52         uint8_t iak_len[4];
53         uint8_t iak_type[4];
54         uint8_t iak_id[32];
55 
56         uint8_t boot_seed[32];
57         uint8_t lcs[4];
58         uint8_t implementation_id[32];
59         uint8_t cert_ref[32];
60         uint8_t verification_service_url[32];
61         uint8_t profile_definition[32];
62 
63 #ifdef BL2
64         uint8_t bl2_rotpk_0[BL2_ROTPK_SIZE];
65         uint8_t bl2_rotpk_1[BL2_ROTPK_SIZE];
66 
67         uint8_t bl2_nv_counter_0[64];
68         uint8_t bl2_nv_counter_1[64];
69         uint8_t bl2_nv_counter_2[64];
70         uint8_t bl2_nv_counter_3[64];
71 
72         uint8_t bl2_rotpk_2[BL2_ROTPK_SIZE];
73         uint8_t bl2_rotpk_3[BL2_ROTPK_SIZE];
74 #endif /* BL2 */
75 
76 #ifdef BL1
77         uint8_t bl1_rotpk_0[32];
78         uint8_t bl1_nv_counter_0[16];
79 #endif /* BL1 */
80 
81 #if (PLATFORM_NS_NV_COUNTERS > 0)
82         uint8_t ns_nv_counter_0[64];
83 #endif
84 #if (PLATFORM_NS_NV_COUNTERS > 1)
85         uint8_t ns_nv_counter_1[64];
86 #endif
87 #if (PLATFORM_NS_NV_COUNTERS > 2)
88         uint8_t ns_nv_counter_2[64];
89 #endif
90 
91         uint8_t entropy_seed[64];
92 
93         uint8_t secure_debug_pk[32];
94     };
95 #endif /* PLATFORM_DEFAULT_OTP */
96 
97 #ifdef PLATFORM_DEFAULT_NV_COUNTERS
98     __PACKED_STRUCT {
99         uint32_t flash_nv_counters[FLASH_NV_COUNTER_AM];
100     };
101 #endif /* PLATFORM_DEFAULT_NV_COUNTERS */
102 
103     /* Must be last item, so that it can be written separately after the main
104      * write operation has succeeded
105      */
106     uint32_t swap_count;
107 };
108 
109 /**
110  * \brief                               Initialise the OTP / NV counter flash
111  *                                      area.
112  *
113  * \return                              TFM_PLAT_ERR_SUCCESS if the
114  *                                      initialization succeeds, otherwise
115  *                                      TFM_PLAT_ERR_SYSTEM_ERR
116  */
117 enum tfm_plat_err_t init_otp_nv_counters_flash(void);
118 
119 /**
120  * \brief                               Reads the OTP / NV counter area at the
121  *                                      given offset into the buffer.
122  *
123  * \param[in]  offset                   offset at which to read from.
124  * \param[out] data                     buffer into which to copy the data.
125  * \param[in]  cnt                      number of bytes to read. Must not be
126  *                                      larger than the size of the buffer.
127  *
128  * \retval TFM_PLAT_ERR_SUCCESS         The data is read successfully.
129  * \retval TFM_PLAT_ERR_INVALID_INPUT   An input parameter has an invalid value.
130  * \retval TFM_PLAT_ERR_SYSTEM_ERR      An unspecified error occurred.
131  */
132 enum tfm_plat_err_t read_otp_nv_counters_flash(uint32_t offset, void *data, uint32_t cnt);
133 
134 /**
135  * \brief                               Writes from the given buffer into the
136  *                                      OTP / NV counter area at the given
137  *                                      offset.
138  *
139  * \param[in]  offset                   offset at which to write to.
140  * \param[out] data                     buffer from which to copy the data.
141  * \param[in]  cnt                      number of bytes to write. Should not be
142  *                                      larger than the size of the buffer.
143  *
144  * \retval TFM_PLAT_ERR_SUCCESS         The data is written successfully.
145  * \retval TFM_PLAT_ERR_INVALID_INPUT   An input parameter has an invalid value.
146  * \retval TFM_PLAT_ERR_SYSTEM_ERR      An unspecified error occurred.
147  */
148 enum tfm_plat_err_t write_otp_nv_counters_flash(uint32_t offset, const void *data, uint32_t cnt);
149 
150 #ifdef __cplusplus
151 }
152 #endif
153 
154 #endif /* __FLASH_OTP_NV_COUNTERS_BACKEND_H__ */
155