1b29b4195SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2b29b4195SJens Wiklander /* Copyright (c) 2018, Linaro Limited */ 3b29b4195SJens Wiklander 4b29b4195SJens Wiklander #include <ta_avb.h> 5b29b4195SJens Wiklander #include <tee_internal_api.h> 6b29b4195SJens Wiklander #include <tee_internal_api_extensions.h> 7b29b4195SJens Wiklander 8*275d9d31SIgor Opaniuk #include <string.h> 9*275d9d31SIgor Opaniuk #include <util.h> 10*275d9d31SIgor Opaniuk 11b29b4195SJens Wiklander #define DEFAULT_LOCK_STATE 0 12b29b4195SJens Wiklander 13b29b4195SJens Wiklander static const uint32_t storageid = TEE_STORAGE_PRIVATE_RPMB; 14*275d9d31SIgor Opaniuk static const char rb_obj_name[] = "rb_state"; 15*275d9d31SIgor Opaniuk static const char *named_value_prefix = "named_value_"; 16b29b4195SJens Wiklander 17b29b4195SJens Wiklander static TEE_Result get_slot_offset(size_t slot, size_t *offset) 18b29b4195SJens Wiklander { 19b29b4195SJens Wiklander if (slot >= TA_AVB_MAX_ROLLBACK_LOCATIONS) 20b29b4195SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 21b29b4195SJens Wiklander 22b29b4195SJens Wiklander *offset = sizeof(uint32_t) /* lock_state */ + slot * sizeof(uint64_t); 23b29b4195SJens Wiklander return TEE_SUCCESS; 24b29b4195SJens Wiklander } 25b29b4195SJens Wiklander 26*275d9d31SIgor Opaniuk static TEE_Result create_rb_state(uint32_t lock_state, TEE_ObjectHandle *h) 27b29b4195SJens Wiklander { 28b29b4195SJens Wiklander const uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | 29b29b4195SJens Wiklander TEE_DATA_FLAG_ACCESS_WRITE | 30b29b4195SJens Wiklander TEE_DATA_FLAG_OVERWRITE; 31b29b4195SJens Wiklander 32*275d9d31SIgor Opaniuk return TEE_CreatePersistentObject(storageid, rb_obj_name, 33*275d9d31SIgor Opaniuk sizeof(rb_obj_name), flags, NULL, 34*275d9d31SIgor Opaniuk &lock_state, sizeof(lock_state), h); 35b29b4195SJens Wiklander } 36b29b4195SJens Wiklander 37*275d9d31SIgor Opaniuk static TEE_Result open_rb_state(uint32_t default_lock_state, 38*275d9d31SIgor Opaniuk TEE_ObjectHandle *h) 39b29b4195SJens Wiklander { 40*275d9d31SIgor Opaniuk uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | 41*275d9d31SIgor Opaniuk TEE_DATA_FLAG_ACCESS_WRITE; 42b29b4195SJens Wiklander TEE_Result res; 43b29b4195SJens Wiklander 44*275d9d31SIgor Opaniuk res = TEE_OpenPersistentObject(storageid, rb_obj_name, 45*275d9d31SIgor Opaniuk sizeof(rb_obj_name), flags, h); 46b29b4195SJens Wiklander if (!res) 47b29b4195SJens Wiklander return TEE_SUCCESS; 48b29b4195SJens Wiklander 49*275d9d31SIgor Opaniuk return create_rb_state(default_lock_state, h); 50*275d9d31SIgor Opaniuk } 51*275d9d31SIgor Opaniuk 52*275d9d31SIgor Opaniuk static TEE_Result get_named_object_name(char *name_orig, 53*275d9d31SIgor Opaniuk uint32_t name_orig_size, 54*275d9d31SIgor Opaniuk char *name, uint32_t *name_size) 55*275d9d31SIgor Opaniuk { 56*275d9d31SIgor Opaniuk size_t pref_len = strlen(named_value_prefix); 57*275d9d31SIgor Opaniuk 58*275d9d31SIgor Opaniuk if (name_orig_size + pref_len > 59*275d9d31SIgor Opaniuk TEE_OBJECT_ID_MAX_LEN) 60*275d9d31SIgor Opaniuk return TEE_ERROR_BAD_PARAMETERS; 61*275d9d31SIgor Opaniuk 62*275d9d31SIgor Opaniuk /* Start with prefix */ 63*275d9d31SIgor Opaniuk TEE_MemMove(name, named_value_prefix, pref_len); 64*275d9d31SIgor Opaniuk 65*275d9d31SIgor Opaniuk /* Concatenate provided object name */ 66*275d9d31SIgor Opaniuk TEE_MemMove(name + pref_len, name_orig, name_orig_size); 67*275d9d31SIgor Opaniuk 68*275d9d31SIgor Opaniuk *name_size = name_orig_size + pref_len; 69*275d9d31SIgor Opaniuk 70*275d9d31SIgor Opaniuk return TEE_SUCCESS; 71b29b4195SJens Wiklander } 72b29b4195SJens Wiklander 73b29b4195SJens Wiklander static TEE_Result read_rb_idx(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 74b29b4195SJens Wiklander { 75b29b4195SJens Wiklander const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 76b29b4195SJens Wiklander TEE_PARAM_TYPE_VALUE_OUTPUT, 77b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE, 78b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE); 79b29b4195SJens Wiklander size_t slot_offset; 80b29b4195SJens Wiklander uint64_t idx; 81b29b4195SJens Wiklander uint32_t count; 82b29b4195SJens Wiklander TEE_Result res; 83b29b4195SJens Wiklander TEE_ObjectHandle h; 84b29b4195SJens Wiklander 85b29b4195SJens Wiklander if (pt != exp_pt) 86b29b4195SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 87b29b4195SJens Wiklander 88b29b4195SJens Wiklander res = get_slot_offset(params[0].value.a, &slot_offset); 89b29b4195SJens Wiklander if (res) 90b29b4195SJens Wiklander return res; 91b29b4195SJens Wiklander 92*275d9d31SIgor Opaniuk res = open_rb_state(DEFAULT_LOCK_STATE, &h); 93b29b4195SJens Wiklander if (res) 94b29b4195SJens Wiklander return res; 95b29b4195SJens Wiklander 96b29b4195SJens Wiklander res = TEE_SeekObjectData(h, slot_offset, TEE_DATA_SEEK_SET); 97b29b4195SJens Wiklander if (res) 98b29b4195SJens Wiklander goto out; 99b29b4195SJens Wiklander 100b29b4195SJens Wiklander res = TEE_ReadObjectData(h, &idx, sizeof(idx), &count); 101b29b4195SJens Wiklander if (res) 102b29b4195SJens Wiklander goto out; 103b29b4195SJens Wiklander if (count != sizeof(idx)) { 104b29b4195SJens Wiklander idx = 0; /* Not yet written slots are reported as 0 */ 105b29b4195SJens Wiklander 106b29b4195SJens Wiklander if (count) { 107b29b4195SJens Wiklander /* 108b29b4195SJens Wiklander * Somehow the file didn't even hold a complete 109b29b4195SJens Wiklander * slot index entry. Write it as 0. 110b29b4195SJens Wiklander */ 111b29b4195SJens Wiklander res = TEE_SeekObjectData(h, slot_offset, 112b29b4195SJens Wiklander TEE_DATA_SEEK_SET); 113b29b4195SJens Wiklander if (res) 114b29b4195SJens Wiklander goto out; 115b29b4195SJens Wiklander res = TEE_WriteObjectData(h, &idx, sizeof(idx)); 116b29b4195SJens Wiklander if (res) 117b29b4195SJens Wiklander goto out; 118b29b4195SJens Wiklander } 119b29b4195SJens Wiklander } 120b29b4195SJens Wiklander 121b29b4195SJens Wiklander params[1].value.a = idx >> 32; 122b29b4195SJens Wiklander params[1].value.b = idx; 123b29b4195SJens Wiklander out: 124b29b4195SJens Wiklander TEE_CloseObject(h); 125b29b4195SJens Wiklander return res; 126b29b4195SJens Wiklander } 127b29b4195SJens Wiklander 128b29b4195SJens Wiklander static TEE_Result write_rb_idx(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 129b29b4195SJens Wiklander { 130b29b4195SJens Wiklander const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 131b29b4195SJens Wiklander TEE_PARAM_TYPE_VALUE_INPUT, 132b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE, 133b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE); 134b29b4195SJens Wiklander size_t slot_offset; 135b29b4195SJens Wiklander uint64_t widx; 136b29b4195SJens Wiklander uint64_t idx; 137b29b4195SJens Wiklander uint32_t count; 138b29b4195SJens Wiklander TEE_Result res; 139b29b4195SJens Wiklander TEE_ObjectHandle h; 140b29b4195SJens Wiklander 141b29b4195SJens Wiklander if (pt != exp_pt) 142b29b4195SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 143b29b4195SJens Wiklander 144b29b4195SJens Wiklander res = get_slot_offset(params[0].value.a, &slot_offset); 145b29b4195SJens Wiklander if (res) 146b29b4195SJens Wiklander return res; 147b29b4195SJens Wiklander widx = ((uint64_t)params[1].value.a << 32) | params[1].value.b; 148b29b4195SJens Wiklander 149*275d9d31SIgor Opaniuk res = open_rb_state(DEFAULT_LOCK_STATE, &h); 150b29b4195SJens Wiklander if (res) 151b29b4195SJens Wiklander return res; 152b29b4195SJens Wiklander 153b29b4195SJens Wiklander res = TEE_SeekObjectData(h, slot_offset, TEE_DATA_SEEK_SET); 154b29b4195SJens Wiklander if (res) 155b29b4195SJens Wiklander goto out; 156b29b4195SJens Wiklander 157b29b4195SJens Wiklander res = TEE_ReadObjectData(h, &idx, sizeof(idx), &count); 158b29b4195SJens Wiklander if (res) 159b29b4195SJens Wiklander goto out; 160b29b4195SJens Wiklander if (count != sizeof(idx)) 161b29b4195SJens Wiklander idx = 0; /* Not yet written slots are reported as 0 */ 162b29b4195SJens Wiklander 163b29b4195SJens Wiklander if (widx < idx) { 164b29b4195SJens Wiklander res = TEE_ERROR_SECURITY; 165b29b4195SJens Wiklander goto out; 166b29b4195SJens Wiklander } 167b29b4195SJens Wiklander 168b29b4195SJens Wiklander res = TEE_SeekObjectData(h, slot_offset, TEE_DATA_SEEK_SET); 169b29b4195SJens Wiklander if (res) 170b29b4195SJens Wiklander goto out; 171b29b4195SJens Wiklander 172b29b4195SJens Wiklander res = TEE_WriteObjectData(h, &widx, sizeof(widx)); 173b29b4195SJens Wiklander out: 174b29b4195SJens Wiklander TEE_CloseObject(h); 175b29b4195SJens Wiklander return res; 176b29b4195SJens Wiklander } 177b29b4195SJens Wiklander 178b29b4195SJens Wiklander static TEE_Result read_lock_state(uint32_t pt, TEE_Param params[TEE_NUM_PARAMS]) 179b29b4195SJens Wiklander { 180b29b4195SJens Wiklander const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT, 181b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE, 182b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE, 183b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE); 184b29b4195SJens Wiklander uint32_t lock_state; 185b29b4195SJens Wiklander uint32_t count; 186b29b4195SJens Wiklander TEE_Result res; 187b29b4195SJens Wiklander TEE_ObjectHandle h; 188b29b4195SJens Wiklander 189b29b4195SJens Wiklander if (pt != exp_pt) 190b29b4195SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 191b29b4195SJens Wiklander 192*275d9d31SIgor Opaniuk res = open_rb_state(DEFAULT_LOCK_STATE, &h); 193b29b4195SJens Wiklander if (res) 194b29b4195SJens Wiklander return res; 195b29b4195SJens Wiklander 196b29b4195SJens Wiklander res = TEE_ReadObjectData(h, &lock_state, sizeof(lock_state), &count); 197b29b4195SJens Wiklander if (res) 198b29b4195SJens Wiklander goto out; 199b29b4195SJens Wiklander if (count != sizeof(lock_state)) { 200b29b4195SJens Wiklander /* 201b29b4195SJens Wiklander * Client need write the lock state to recover, this can 202b29b4195SJens Wiklander * normally not happen. 203b29b4195SJens Wiklander */ 204b29b4195SJens Wiklander res = TEE_ERROR_CORRUPT_OBJECT; 205b29b4195SJens Wiklander goto out; 206b29b4195SJens Wiklander } 207b29b4195SJens Wiklander 208b29b4195SJens Wiklander params[0].value.a = lock_state; 209b29b4195SJens Wiklander out: 210b29b4195SJens Wiklander TEE_CloseObject(h); 211b29b4195SJens Wiklander return res; 212b29b4195SJens Wiklander } 213b29b4195SJens Wiklander 214b29b4195SJens Wiklander static TEE_Result write_lock_state(uint32_t pt, 215b29b4195SJens Wiklander TEE_Param params[TEE_NUM_PARAMS]) 216b29b4195SJens Wiklander { 217b29b4195SJens Wiklander const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 218b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE, 219b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE, 220b29b4195SJens Wiklander TEE_PARAM_TYPE_NONE); 221b29b4195SJens Wiklander uint32_t wlock_state; 222b29b4195SJens Wiklander uint32_t lock_state; 223b29b4195SJens Wiklander uint32_t count; 224b29b4195SJens Wiklander TEE_Result res; 225b29b4195SJens Wiklander TEE_ObjectHandle h; 226b29b4195SJens Wiklander 227b29b4195SJens Wiklander if (pt != exp_pt) 228b29b4195SJens Wiklander return TEE_ERROR_BAD_PARAMETERS; 229b29b4195SJens Wiklander 230b29b4195SJens Wiklander wlock_state = params[0].value.a; 231b29b4195SJens Wiklander 232*275d9d31SIgor Opaniuk res = open_rb_state(wlock_state, &h); 233b29b4195SJens Wiklander if (res) 234b29b4195SJens Wiklander return res; 235b29b4195SJens Wiklander 236b29b4195SJens Wiklander res = TEE_ReadObjectData(h, &lock_state, sizeof(lock_state), &count); 237b29b4195SJens Wiklander if (res) 238b29b4195SJens Wiklander goto out; 239b29b4195SJens Wiklander if (count == sizeof(lock_state) && lock_state == wlock_state) 240b29b4195SJens Wiklander goto out; 241b29b4195SJens Wiklander 242*275d9d31SIgor Opaniuk res = create_rb_state(wlock_state, &h); 243b29b4195SJens Wiklander out: 244b29b4195SJens Wiklander TEE_CloseObject(h); 245b29b4195SJens Wiklander return res; 246b29b4195SJens Wiklander } 247b29b4195SJens Wiklander 248*275d9d31SIgor Opaniuk static TEE_Result write_persist_value(uint32_t pt, 249*275d9d31SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS]) 250*275d9d31SIgor Opaniuk { 251*275d9d31SIgor Opaniuk const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 252*275d9d31SIgor Opaniuk TEE_PARAM_TYPE_MEMREF_INPUT, 253*275d9d31SIgor Opaniuk TEE_PARAM_TYPE_NONE, 254*275d9d31SIgor Opaniuk TEE_PARAM_TYPE_NONE); 255*275d9d31SIgor Opaniuk const uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | 256*275d9d31SIgor Opaniuk TEE_DATA_FLAG_ACCESS_WRITE | 257*275d9d31SIgor Opaniuk TEE_DATA_FLAG_OVERWRITE; 258*275d9d31SIgor Opaniuk TEE_Result res; 259*275d9d31SIgor Opaniuk TEE_ObjectHandle h; 260*275d9d31SIgor Opaniuk 261*275d9d31SIgor Opaniuk char name_full[TEE_OBJECT_ID_MAX_LEN]; 262*275d9d31SIgor Opaniuk uint32_t name_full_sz; 263*275d9d31SIgor Opaniuk 264*275d9d31SIgor Opaniuk if (pt != exp_pt) 265*275d9d31SIgor Opaniuk return TEE_ERROR_BAD_PARAMETERS; 266*275d9d31SIgor Opaniuk 267*275d9d31SIgor Opaniuk char *name_buf = params[0].memref.buffer; 268*275d9d31SIgor Opaniuk uint32_t name_buf_sz = params[0].memref.size; 269*275d9d31SIgor Opaniuk 270*275d9d31SIgor Opaniuk char *value = params[1].memref.buffer; 271*275d9d31SIgor Opaniuk uint32_t value_sz = params[1].memref.size; 272*275d9d31SIgor Opaniuk 273*275d9d31SIgor Opaniuk res = get_named_object_name(name_buf, name_buf_sz, 274*275d9d31SIgor Opaniuk name_full, &name_full_sz); 275*275d9d31SIgor Opaniuk if (res) 276*275d9d31SIgor Opaniuk return res; 277*275d9d31SIgor Opaniuk 278*275d9d31SIgor Opaniuk res = TEE_CreatePersistentObject(storageid, name_full, 279*275d9d31SIgor Opaniuk name_full_sz, 280*275d9d31SIgor Opaniuk flags, NULL, value, 281*275d9d31SIgor Opaniuk value_sz, &h); 282*275d9d31SIgor Opaniuk if (res) 283*275d9d31SIgor Opaniuk EMSG("Can't create named object value, res = 0x%x", res); 284*275d9d31SIgor Opaniuk 285*275d9d31SIgor Opaniuk TEE_CloseObject(h); 286*275d9d31SIgor Opaniuk 287*275d9d31SIgor Opaniuk return res; 288*275d9d31SIgor Opaniuk } 289*275d9d31SIgor Opaniuk 290*275d9d31SIgor Opaniuk static TEE_Result read_persist_value(uint32_t pt, 291*275d9d31SIgor Opaniuk TEE_Param params[TEE_NUM_PARAMS]) 292*275d9d31SIgor Opaniuk { 293*275d9d31SIgor Opaniuk const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 294*275d9d31SIgor Opaniuk TEE_PARAM_TYPE_MEMREF_INOUT, 295*275d9d31SIgor Opaniuk TEE_PARAM_TYPE_NONE, 296*275d9d31SIgor Opaniuk TEE_PARAM_TYPE_NONE); 297*275d9d31SIgor Opaniuk uint32_t flags = TEE_DATA_FLAG_ACCESS_READ | 298*275d9d31SIgor Opaniuk TEE_DATA_FLAG_ACCESS_WRITE; 299*275d9d31SIgor Opaniuk TEE_Result res; 300*275d9d31SIgor Opaniuk TEE_ObjectHandle h; 301*275d9d31SIgor Opaniuk 302*275d9d31SIgor Opaniuk char name_full[TEE_OBJECT_ID_MAX_LEN]; 303*275d9d31SIgor Opaniuk uint32_t name_full_sz; 304*275d9d31SIgor Opaniuk uint32_t count; 305*275d9d31SIgor Opaniuk 306*275d9d31SIgor Opaniuk if (pt != exp_pt) 307*275d9d31SIgor Opaniuk return TEE_ERROR_BAD_PARAMETERS; 308*275d9d31SIgor Opaniuk 309*275d9d31SIgor Opaniuk char *name_buf = params[0].memref.buffer; 310*275d9d31SIgor Opaniuk uint32_t name_buf_sz = params[0].memref.size; 311*275d9d31SIgor Opaniuk 312*275d9d31SIgor Opaniuk char *value = params[1].memref.buffer; 313*275d9d31SIgor Opaniuk uint32_t value_sz = params[1].memref.size; 314*275d9d31SIgor Opaniuk 315*275d9d31SIgor Opaniuk res = get_named_object_name(name_buf, name_buf_sz, 316*275d9d31SIgor Opaniuk name_full, &name_full_sz); 317*275d9d31SIgor Opaniuk if (res) 318*275d9d31SIgor Opaniuk return res; 319*275d9d31SIgor Opaniuk 320*275d9d31SIgor Opaniuk res = TEE_OpenPersistentObject(storageid, name_full, 321*275d9d31SIgor Opaniuk name_full_sz, flags, &h); 322*275d9d31SIgor Opaniuk if (res) { 323*275d9d31SIgor Opaniuk EMSG("Can't open named object value, res = 0x%x", res); 324*275d9d31SIgor Opaniuk return res; 325*275d9d31SIgor Opaniuk } 326*275d9d31SIgor Opaniuk 327*275d9d31SIgor Opaniuk res = TEE_ReadObjectData(h, value, value_sz, &count); 328*275d9d31SIgor Opaniuk if (res) { 329*275d9d31SIgor Opaniuk EMSG("Can't read named object value, res = 0x%x", res); 330*275d9d31SIgor Opaniuk goto out; 331*275d9d31SIgor Opaniuk } 332*275d9d31SIgor Opaniuk 333*275d9d31SIgor Opaniuk params[1].memref.size = count; 334*275d9d31SIgor Opaniuk out: 335*275d9d31SIgor Opaniuk TEE_CloseObject(h); 336*275d9d31SIgor Opaniuk 337*275d9d31SIgor Opaniuk return res; 338*275d9d31SIgor Opaniuk } 339*275d9d31SIgor Opaniuk 340b29b4195SJens Wiklander TEE_Result TA_CreateEntryPoint(void) 341b29b4195SJens Wiklander { 342b29b4195SJens Wiklander return TEE_SUCCESS; 343b29b4195SJens Wiklander } 344b29b4195SJens Wiklander 345b29b4195SJens Wiklander void TA_DestroyEntryPoint(void) 346b29b4195SJens Wiklander { 347b29b4195SJens Wiklander } 348b29b4195SJens Wiklander 349b29b4195SJens Wiklander TEE_Result TA_OpenSessionEntryPoint(uint32_t pt __unused, 350b29b4195SJens Wiklander TEE_Param params[4] __unused, 351b29b4195SJens Wiklander void **session __unused) 352b29b4195SJens Wiklander { 353b29b4195SJens Wiklander return TEE_SUCCESS; 354b29b4195SJens Wiklander } 355b29b4195SJens Wiklander 356b29b4195SJens Wiklander void TA_CloseSessionEntryPoint(void *sess __unused) 357b29b4195SJens Wiklander { 358b29b4195SJens Wiklander } 359b29b4195SJens Wiklander 360b29b4195SJens Wiklander TEE_Result TA_InvokeCommandEntryPoint(void *sess __unused, uint32_t cmd, 361b29b4195SJens Wiklander uint32_t pt, 362b29b4195SJens Wiklander TEE_Param params[TEE_NUM_PARAMS]) 363b29b4195SJens Wiklander { 364b29b4195SJens Wiklander switch (cmd) { 365b29b4195SJens Wiklander case TA_AVB_CMD_READ_ROLLBACK_INDEX: 366b29b4195SJens Wiklander return read_rb_idx(pt, params); 367b29b4195SJens Wiklander case TA_AVB_CMD_WRITE_ROLLBACK_INDEX: 368b29b4195SJens Wiklander return write_rb_idx(pt, params); 369b29b4195SJens Wiklander case TA_AVB_CMD_READ_LOCK_STATE: 370b29b4195SJens Wiklander return read_lock_state(pt, params); 371b29b4195SJens Wiklander case TA_AVB_CMD_WRITE_LOCK_STATE: 372b29b4195SJens Wiklander return write_lock_state(pt, params); 373*275d9d31SIgor Opaniuk case TA_AVB_CMD_READ_PERSIST_VALUE: 374*275d9d31SIgor Opaniuk return read_persist_value(pt, params); 375*275d9d31SIgor Opaniuk case TA_AVB_CMD_WRITE_PERSIST_VALUE: 376*275d9d31SIgor Opaniuk return write_persist_value(pt, params); 377b29b4195SJens Wiklander default: 378b29b4195SJens Wiklander EMSG("Command ID 0x%x is not supported", cmd); 379b29b4195SJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 380b29b4195SJens Wiklander } 381b29b4195SJens Wiklander } 382