1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2022, STMicroelectronics - All Rights Reserved 4 */ 5 6 #include <config.h> 7 #include <drivers/stm32_bsec.h> 8 #include <kernel/pseudo_ta.h> 9 #include <kernel/user_access.h> 10 #include <kernel/user_mode_ctx.h> 11 #include <kernel/user_ta.h> 12 #include <mm/vm.h> 13 #include <pta_stm32mp_bsec.h> 14 #include <string.h> 15 #include <util.h> 16 17 static_assert(IS_ENABLED(CFG_STM32_BSEC)); 18 19 #define PTA_NAME "bsec.pta" 20 21 static TEE_Result bsec_check_access(uint32_t otp_id) 22 { 23 if (!stm32_bsec_nsec_can_access_otp(otp_id)) 24 return TEE_ERROR_ACCESS_DENIED; 25 26 return TEE_SUCCESS; 27 } 28 29 static TEE_Result bsec_read_mem(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 30 { 31 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 32 TEE_PARAM_TYPE_MEMREF_OUTPUT, 33 TEE_PARAM_TYPE_NONE, 34 TEE_PARAM_TYPE_NONE); 35 uint32_t *buf = (uint32_t *)params[1].memref.buffer; 36 uint32_t otp_start = 0; 37 size_t otp_length = 0; 38 uint32_t otp_id = 0; 39 TEE_Result res = TEE_ERROR_GENERIC; 40 size_t size = params[1].memref.size; 41 bool locked = false; 42 unsigned int otp_base_offset = params[0].value.a; 43 unsigned int bsec_command = params[0].value.b; 44 45 if (pt != exp_pt || !buf || !size || 46 !IS_ALIGNED_WITH_TYPE(params[1].memref.buffer, uint32_t)) 47 return TEE_ERROR_BAD_PARAMETERS; 48 49 /* Check 32bits alignment */ 50 if (otp_base_offset % BSEC_BYTES_PER_WORD || 51 size % BSEC_BYTES_PER_WORD) 52 return TEE_ERROR_BAD_PARAMETERS; 53 54 otp_start = otp_base_offset / BSEC_BYTES_PER_WORD; 55 otp_length = size / BSEC_BYTES_PER_WORD; 56 57 for (otp_id = otp_start; otp_id < otp_start + otp_length; 58 otp_id++, buf++) { 59 res = bsec_check_access(otp_id); 60 switch (bsec_command) { 61 case PTA_BSEC_SHADOW_ACCESS: 62 if (res) { 63 /* Force 0 when access is not allowed */ 64 *buf = 0x0; 65 continue; 66 } 67 /* Read shadow register */ 68 res = stm32_bsec_read_otp(buf, otp_id); 69 FMSG("Read shadow %"PRIu32" val: %#"PRIx32, otp_id, 70 *buf); 71 break; 72 case PTA_BSEC_FUSE_ACCESS: 73 /* Check access */ 74 if (res) 75 goto out; 76 /* Read fuse value */ 77 res = stm32_bsec_shadow_read_otp(buf, otp_id); 78 FMSG("Read fuse %"PRIu32" val: %#"PRIx32, otp_id, *buf); 79 break; 80 case PTA_BSEC_LOCKS_ACCESS: 81 if (res) { 82 /* Force error when access is not allowed */ 83 *buf = PTA_BSEC_LOCK_ERROR; 84 continue; 85 } 86 *buf = 0; 87 /* Read lock value */ 88 res = stm32_bsec_read_permanent_lock(otp_id, &locked); 89 if (res) 90 goto out; 91 92 if (locked) 93 *buf |= PTA_BSEC_LOCK_PERM; 94 95 res = stm32_bsec_read_sr_lock(otp_id, &locked); 96 if (res) 97 goto out; 98 99 if (locked) 100 *buf |= PTA_BSEC_LOCK_SHADOW_R; 101 102 res = stm32_bsec_read_sw_lock(otp_id, &locked); 103 if (res) 104 goto out; 105 106 if (locked) 107 *buf |= PTA_BSEC_LOCK_SHADOW_W; 108 109 res = stm32_bsec_read_sp_lock(otp_id, &locked); 110 if (res) 111 goto out; 112 113 if (locked) 114 *buf |= PTA_BSEC_LOCK_SHADOW_P; 115 116 FMSG("Read lock %"PRIu32" val: %#"PRIx32, otp_id, *buf); 117 break; 118 default: 119 FMSG("%"PRIu32" invalid operation: %"PRIu32, otp_id, 120 bsec_command); 121 res = TEE_ERROR_BAD_PARAMETERS; 122 } 123 124 if (res) 125 goto out; 126 } 127 128 FMSG("Buffer orig %p, size %zu", buf, size); 129 130 res = TEE_SUCCESS; 131 out: 132 return res; 133 } 134 135 static TEE_Result bsec_write_mem(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 136 { 137 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 138 TEE_PARAM_TYPE_MEMREF_INPUT, 139 TEE_PARAM_TYPE_NONE, 140 TEE_PARAM_TYPE_NONE); 141 142 uint32_t *buf = (uint32_t *)params[1].memref.buffer; 143 size_t size = params[1].memref.size; 144 uint32_t otp_start = 0; 145 size_t otp_length = 0; 146 uint32_t otp_id = 0; 147 TEE_Result res = TEE_ERROR_GENERIC; 148 unsigned int otp_base_offset = params[0].value.a; 149 unsigned int bsec_command = params[0].value.b; 150 151 if (pt != exp_pt || !buf || !size || 152 !IS_ALIGNED_WITH_TYPE(params[1].memref.buffer, uint32_t)) 153 return TEE_ERROR_BAD_PARAMETERS; 154 155 /* Check 32bits alignment */ 156 if (otp_base_offset % BSEC_BYTES_PER_WORD || 157 size % BSEC_BYTES_PER_WORD) 158 return TEE_ERROR_BAD_PARAMETERS; 159 160 otp_start = otp_base_offset / BSEC_BYTES_PER_WORD; 161 otp_length = size / BSEC_BYTES_PER_WORD; 162 163 /* Initial check to ensure that all BSEC words are available */ 164 for (otp_id = otp_start; otp_id < otp_start + otp_length; otp_id++) { 165 res = bsec_check_access(otp_id); 166 if (res) 167 return res; 168 } 169 170 for (otp_id = otp_start; otp_id < otp_start + otp_length; 171 otp_id++, buf++) { 172 switch (bsec_command) { 173 case PTA_BSEC_SHADOW_ACCESS: 174 /* Write shadow register */ 175 FMSG("Write shadow %"PRIx32" : %"PRIx32, 176 otp_id, *buf); 177 res = stm32_bsec_write_otp(*buf, otp_id); 178 break; 179 180 case PTA_BSEC_FUSE_ACCESS: 181 /* Write fuse value */ 182 FMSG("Write fuse %"PRIx32" : %08"PRIx32, 183 otp_id, *buf); 184 res = stm32_bsec_program_otp(*buf, otp_id); 185 break; 186 187 case PTA_BSEC_LOCKS_ACCESS: 188 if (*buf & PTA_BSEC_LOCK_PERM) { 189 FMSG("Perm lock access OTP: %u", otp_id); 190 res = stm32_bsec_permanent_lock_otp(otp_id); 191 if (res) 192 break; 193 } 194 195 if (*buf & PTA_BSEC_LOCK_SHADOW_R) { 196 FMSG("Shadow read lock"); 197 res = stm32_bsec_set_sr_lock(otp_id); 198 if (res) 199 break; 200 } 201 202 if (*buf & PTA_BSEC_LOCK_SHADOW_W) { 203 FMSG("Shadow write lock detected"); 204 res = stm32_bsec_set_sw_lock(otp_id); 205 if (res) 206 break; 207 } 208 209 if (*buf & PTA_BSEC_LOCK_SHADOW_P) { 210 FMSG("Shadow programming lock detected"); 211 res = stm32_bsec_set_sp_lock(otp_id); 212 } 213 214 break; 215 216 default: 217 FMSG("OTP %"PRIx32" invalid operation: %"PRIx32, 218 otp_id, bsec_command); 219 res = TEE_ERROR_BAD_PARAMETERS; 220 } 221 222 if (res) 223 return res; 224 } 225 226 return TEE_SUCCESS; 227 } 228 229 static TEE_Result bsec_pta_state(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 230 { 231 const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT, 232 TEE_PARAM_TYPE_NONE, 233 TEE_PARAM_TYPE_NONE, 234 TEE_PARAM_TYPE_NONE); 235 TEE_Result res = TEE_ERROR_GENERIC; 236 enum stm32_bsec_sec_state state = BSEC_STATE_INVALID; 237 enum stm32_bsec_pta_sec_state pta_state = PTA_BSEC_STATE_INVALID; 238 239 if (pt != exp_pt) 240 return TEE_ERROR_BAD_PARAMETERS; 241 242 res = stm32_bsec_get_state(&state); 243 if (res) 244 return res; 245 246 switch (state) { 247 case BSEC_STATE_SEC_CLOSED: 248 pta_state = PTA_BSEC_STATE_SEC_CLOSE; 249 break; 250 case BSEC_STATE_SEC_OPEN: 251 pta_state = PTA_BSEC_STATE_SEC_OPEN; 252 break; 253 default: 254 pta_state = PTA_BSEC_STATE_INVALID; 255 break; 256 } 257 258 params[0].value.a = pta_state; 259 260 return TEE_SUCCESS; 261 } 262 263 static TEE_Result bsec_pta_invoke_command(void *pSessionContext __unused, 264 uint32_t cmd_id, 265 uint32_t param_types, 266 TEE_Param params[TEE_NUM_PARAMS]) 267 { 268 FMSG(PTA_NAME" command %#"PRIx32" ptypes %#"PRIx32, 269 cmd_id, param_types); 270 271 switch (cmd_id) { 272 case PTA_BSEC_CMD_READ_OTP: 273 return bsec_read_mem(param_types, params); 274 case PTA_BSEC_CMD_WRITE_OTP: 275 return bsec_write_mem(param_types, params); 276 case PTA_BSEC_CMD_GET_STATE: 277 return bsec_pta_state(param_types, params); 278 default: 279 break; 280 } 281 282 return TEE_ERROR_NOT_IMPLEMENTED; 283 } 284 285 static TEE_Result pta_bsec_open_session(uint32_t ptypes __unused, 286 TEE_Param par[TEE_NUM_PARAMS] __unused, 287 void **session __unused) 288 { 289 uint32_t login = to_ta_session(ts_get_current_session())->clnt_id.login; 290 291 if (login == TEE_LOGIN_REE_KERNEL) 292 return TEE_SUCCESS; 293 294 return TEE_ERROR_ACCESS_DENIED; 295 } 296 297 pseudo_ta_register(.uuid = PTA_BSEC_UUID, .name = PTA_NAME, 298 .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT | 299 TA_FLAG_DEVICE_ENUM, 300 .open_session_entry_point = pta_bsec_open_session, 301 .invoke_command_entry_point = bsec_pta_invoke_command); 302