1abdd2437Shisping /* 2abdd2437Shisping * Copyright 2017, Rockchip Electronics Co., Ltd 3abdd2437Shisping * hisping lin, <hisping.lin@rock-chips.com> 4abdd2437Shisping * 5abdd2437Shisping * SPDX-License-Identifier: GPL-2.0+ 6abdd2437Shisping */ 7abdd2437Shisping #include <common.h> 8abdd2437Shisping #include <stdlib.h> 9abdd2437Shisping #include <command.h> 10abdd2437Shisping #include <mmc.h> 11abdd2437Shisping #include <optee_include/OpteeClientMem.h> 12abdd2437Shisping #include <optee_include/OpteeClientRPC.h> 13abdd2437Shisping #include <optee_include/teesmc.h> 141f25ada2SHisping Lin #include <optee_include/teesmc_v2.h> 15abdd2437Shisping #include <optee_include/teesmc_optee.h> 16abdd2437Shisping #include <optee_include/tee_rpc_types.h> 17abdd2437Shisping #include <optee_include/tee_rpc.h> 183251364cSHisping Lin #ifdef CONFIG_OPTEE_V1 191f25ada2SHisping Lin #include <optee_include/OpteeClientRkFs.h> 203251364cSHisping Lin #endif 213251364cSHisping Lin #ifdef CONFIG_OPTEE_V2 223251364cSHisping Lin #include <optee_include/OpteeClientRkFs-v2.h> 233251364cSHisping Lin #endif 24abdd2437Shisping 25abdd2437Shisping /* 26abdd2437Shisping * Memory allocation. 27abdd2437Shisping * Currently treated the same for both arguments & payloads. 28abdd2437Shisping */ 29abdd2437Shisping TEEC_Result OpteeRpcAlloc(uint32_t Size, uint32_t *Address) 30abdd2437Shisping { 31abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 321f25ada2SHisping Lin size_t AllocAddress; 33abdd2437Shisping 34abdd2437Shisping *Address = 0; 35abdd2437Shisping 36abdd2437Shisping if (Size != 0) { 371f25ada2SHisping Lin AllocAddress = (size_t) OpteeClientMemAlloc(Size); 38abdd2437Shisping 39abdd2437Shisping if (AllocAddress == 0) 40abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 41abdd2437Shisping else 42abdd2437Shisping *Address = AllocAddress; 43abdd2437Shisping } 44abdd2437Shisping return TeecResult; 45abdd2437Shisping } 46abdd2437Shisping 47abdd2437Shisping /* 48abdd2437Shisping * Memory free. 49abdd2437Shisping * Currently treated the same for both arguments & payloads. 50abdd2437Shisping */ 51abdd2437Shisping TEEC_Result OpteeRpcFree(uint32_t Address) 52abdd2437Shisping { 531f25ada2SHisping Lin OpteeClientMemFree((void *)(size_t)Address); 54abdd2437Shisping return TEEC_SUCCESS; 55abdd2437Shisping } 56abdd2437Shisping 57a7df4868Stony.xu int is_uuid_equal(TEE_UUID uuid1, TEEC_UUID uuid2) 58a7df4868Stony.xu { 59a7df4868Stony.xu bool a, b, c; 60a7df4868Stony.xu 61a7df4868Stony.xu a = (uuid1.timeLow == uuid2.timeLow); 62a7df4868Stony.xu b = (uuid1.timeMid == uuid2.timeMid); 63a7df4868Stony.xu c = (uuid1.timeHiAndVersion == uuid2.timeHiAndVersion); 64a7df4868Stony.xu if ((a & b & c) == 0) { 65a7df4868Stony.xu return 0; 66a7df4868Stony.xu } else { 67a7df4868Stony.xu if (memcmp(uuid1.clockSeqAndNode, 68a7df4868Stony.xu uuid2.clockSeqAndNode, 8) == 0) { 69a7df4868Stony.xu return 1; 70a7df4868Stony.xu } else { 71a7df4868Stony.xu return 0; 72a7df4868Stony.xu } 73a7df4868Stony.xu } 74a7df4868Stony.xu } 75a7df4868Stony.xu 76abdd2437Shisping /* 77abdd2437Shisping * Load a TA from storage into memory and provide it back to OpTEE. 78abdd2437Shisping * Param[0] = IN: struct tee_rpc_load_ta_cmd 79abdd2437Shisping * Param[1] = IN: all-zero OUT: TA Image allocated 80abdd2437Shisping */ 81abdd2437Shisping TEEC_Result OpteeRpcCmdLoadTa(t_teesmc32_arg *TeeSmc32Arg) 82abdd2437Shisping { 83abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 84abdd2437Shisping t_teesmc32_param *TeeSmc32Param = NULL; 85abdd2437Shisping struct tee_rpc_load_ta_cmd *TeeLoadTaCmd = NULL; 86abdd2437Shisping uint32_t TeeLoadTaCmdSize = 0; 87abdd2437Shisping 88abdd2437Shisping if (TeeSmc32Arg->num_params != 2) { 89abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 90abdd2437Shisping goto Exit; 91abdd2437Shisping } 92abdd2437Shisping 93a7df4868Stony.xu TEEC_UUID TA_RK_KEYMASTER_UUID = {0x258be795, 0xf9ca, 0x40e6, 94a7df4868Stony.xu {0xa8, 0x69, 0x9c, 0xe6, 0x88, 0x6c, 0x5d, 0x5d} }; 95abdd2437Shisping TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 96abdd2437Shisping TeeLoadTaCmd = (struct tee_rpc_load_ta_cmd *) 971f25ada2SHisping Lin (size_t)TeeSmc32Param[0].u.memref.buf_ptr; 98abdd2437Shisping TeeLoadTaCmdSize = TeeSmc32Param[0].u.memref.size; 99abdd2437Shisping 100abdd2437Shisping if ((TeeLoadTaCmd == NULL) || 101abdd2437Shisping (TeeLoadTaCmdSize != sizeof(*TeeLoadTaCmd))) { 102abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 103abdd2437Shisping goto Exit; 104abdd2437Shisping } 105abdd2437Shisping 106abdd2437Shisping TEEC_Result Status = 0; 107abdd2437Shisping void *ImageData = NULL; 108abdd2437Shisping uint32_t ImageSize = 0; 1091f25ada2SHisping Lin size_t AllocAddress = 0; 110abdd2437Shisping 111a7df4868Stony.xu if (is_uuid_equal(TeeLoadTaCmd->uuid, TA_RK_KEYMASTER_UUID)) { 11299830019SHisping Lin ImageData = (void *)0; 11399830019SHisping Lin ImageSize = 0; 114a7df4868Stony.xu } else { 115d8100d74SHisping Lin ImageData = (void *)0; 116d8100d74SHisping Lin ImageSize = 0; 117a7df4868Stony.xu } 118abdd2437Shisping 119abdd2437Shisping if (Status != 0) { 120abdd2437Shisping TeecResult = TEEC_ERROR_ITEM_NOT_FOUND; 121abdd2437Shisping goto Exit; 122abdd2437Shisping } 123abdd2437Shisping 1241f25ada2SHisping Lin AllocAddress = (size_t) OpteeClientMemAlloc(ImageSize); 125abdd2437Shisping 126abdd2437Shisping if (AllocAddress == 0) { 127abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 128abdd2437Shisping goto Exit; 129abdd2437Shisping } 130abdd2437Shisping 131abdd2437Shisping memcpy((void *)AllocAddress, ImageData, ImageSize); 132abdd2437Shisping 133efb93541SHisping Lin debug("TEEC: ...TA loaded at 0x%zu of size 0x%X bytes\n", 134abdd2437Shisping AllocAddress, ImageSize); 135efb93541SHisping Lin debug("TEEC: ...AllocAddress[0] 0x%X ; AllocAddress[1] 0x%X bytes\n", 136abdd2437Shisping *(char *)AllocAddress, *(char *)(AllocAddress+1)); 137abdd2437Shisping 1381f25ada2SHisping Lin TeeLoadTaCmd->va = AllocAddress; 139abdd2437Shisping 140abdd2437Shisping TeeSmc32Param[1].u.memref.buf_ptr = AllocAddress; 141abdd2437Shisping TeeSmc32Param[1].u.memref.size = ImageSize; 142abdd2437Shisping 143abdd2437Shisping Exit: 144abdd2437Shisping TeeSmc32Arg->ret = TeecResult; 145abdd2437Shisping TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API; 146abdd2437Shisping 147efb93541SHisping Lin debug("TEEC: OpteeRpcCmdLoadTa Exit : TeecResult=0x%X\n", TeecResult); 148abdd2437Shisping 149abdd2437Shisping return TeecResult; 150abdd2437Shisping } 151abdd2437Shisping 1521f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 1531f25ada2SHisping Lin TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg) 1541f25ada2SHisping Lin { 1551f25ada2SHisping Lin TEEC_Result TeecResult = TEEC_SUCCESS; 1561f25ada2SHisping Lin t_teesmc32_param *TeeSmc32Param = NULL; 1571f25ada2SHisping Lin uint8_t uuid[16]; 1581f25ada2SHisping Lin int i; 1591f25ada2SHisping Lin 1601f25ada2SHisping Lin if (TeeSmc32Arg->num_params != 2) { 1611f25ada2SHisping Lin TeecResult = TEEC_ERROR_BAD_PARAMETERS; 1621f25ada2SHisping Lin goto Exit; 1631f25ada2SHisping Lin } 1641f25ada2SHisping Lin 1651f25ada2SHisping Lin TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 1661f25ada2SHisping Lin 1671f25ada2SHisping Lin memcpy(uuid, (void *)&TeeSmc32Param[0].u.value, 16); 1681f25ada2SHisping Lin for (i = 0; i < 16; i++) 169efb93541SHisping Lin debug("TEEC: uuid 0x%x", uuid[i]); 1701f25ada2SHisping Lin 1711f25ada2SHisping Lin if (TeeSmc32Param[1].u.memref.buf_ptr == 0) { 172efb93541SHisping Lin debug("TEEC: return size of TA, keymaster_size = 0\n"); 17399830019SHisping Lin TeeSmc32Param[1].u.memref.size = 0; 1741f25ada2SHisping Lin } else { 17599830019SHisping Lin /*memcpy((void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr, 17699830019SHisping Lin (void *)keymaster_data, TeeSmc32Param[1].u.memref.size);*/ 177efb93541SHisping Lin debug("TEEC: memref.buf_ptr = 0x%llx; memref.size = 0x%llx\n", 1781f25ada2SHisping Lin TeeSmc32Param[1].u.memref.buf_ptr, 1791f25ada2SHisping Lin TeeSmc32Param[1].u.memref.size); 1801f25ada2SHisping Lin } 1811f25ada2SHisping Lin 1821f25ada2SHisping Lin Exit: 1831f25ada2SHisping Lin TeeSmc32Arg->ret = TeecResult; 1841f25ada2SHisping Lin TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API; 1851f25ada2SHisping Lin 186efb93541SHisping Lin debug("TEEC: OpteeRpcCmdLoadTa Exit : TeecResult=0x%X\n", TeecResult); 1871f25ada2SHisping Lin 1881f25ada2SHisping Lin return TeecResult; 1891f25ada2SHisping Lin } 1901f25ada2SHisping Lin #endif 1911f25ada2SHisping Lin 192abdd2437Shisping /* 193abdd2437Shisping * Free a previously loaded TA and release the memory 194abdd2437Shisping * Param[0] = IN: TA Image to free 195abdd2437Shisping * 196abdd2437Shisping * Um, why is OpTEE holding on to this memory? The OS code suggests that OpTEE 197abdd2437Shisping * is using the binary in place out of shared memory but I don't understand how 198abdd2437Shisping * runtime modifications of the binary are being prevented if that's the case? 199abdd2437Shisping */ 200abdd2437Shisping TEEC_Result OpteeRpcCmdFreeTa(t_teesmc32_arg *TeeSmc32Arg) 201abdd2437Shisping { 202abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 203abdd2437Shisping t_teesmc32_param *TeeSmc32Param = NULL; 204abdd2437Shisping uint32_t ImageSize = 0; 2051f25ada2SHisping Lin size_t AllocAddress = 0; 206abdd2437Shisping 207abdd2437Shisping if (TeeSmc32Arg->num_params != 1) { 208abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 209abdd2437Shisping goto Exit; 210abdd2437Shisping } 211abdd2437Shisping 212abdd2437Shisping TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 213abdd2437Shisping 214abdd2437Shisping AllocAddress = TeeSmc32Param[0].u.memref.buf_ptr; 215abdd2437Shisping ImageSize = TeeSmc32Param[0].u.memref.size; 216abdd2437Shisping 217efb93541SHisping Lin debug("TEEC: OpteeRpcCmdFreeTa Enter: AllocAddress=0x%X, ImageSize=0x%X\n", 218abdd2437Shisping (uint32_t) AllocAddress, (uint32_t) ImageSize); 219abdd2437Shisping 220abdd2437Shisping if (AllocAddress == 0) { 221abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 222abdd2437Shisping goto Exit; 223abdd2437Shisping } 224abdd2437Shisping 225abdd2437Shisping OpteeClientMemFree((void *)AllocAddress); 226abdd2437Shisping 227abdd2437Shisping Exit: 228abdd2437Shisping TeeSmc32Arg->ret = TeecResult; 229abdd2437Shisping TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API; 230abdd2437Shisping 231efb93541SHisping Lin debug("TEEC: OpteeRpcCmdFreeTa Exit : TeecResult=0x%X\n", TeecResult); 232abdd2437Shisping 233abdd2437Shisping return TeecResult; 234abdd2437Shisping } 235abdd2437Shisping 236abdd2437Shisping /* 237abdd2437Shisping * Execute an RPMB storage operation. 238abdd2437Shisping */ 2391f25ada2SHisping Lin 240abdd2437Shisping uint16_t global_block_count; 241abdd2437Shisping TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg) 242abdd2437Shisping { 243abdd2437Shisping struct tee_rpc_rpmb_dev_info *DevInfo; 244abdd2437Shisping TEEC_Result EfiStatus; 245abdd2437Shisping uint16_t RequestMsgType, i; 246abdd2437Shisping EFI_RK_RPMB_DATA_PACKET *RequestPackets; 247abdd2437Shisping EFI_RK_RPMB_DATA_PACKET *ResponsePackets; 248abdd2437Shisping EFI_RK_RPMB_DATA_PACKET *tempPackets; 249abdd2437Shisping EFI_RK_RPMB_DATA_PACKET_BACK *RequestPackets_back; 250abdd2437Shisping EFI_RK_RPMB_DATA_PACKET_BACK *tempPackets_back; 251abdd2437Shisping struct tee_rpc_rpmb_cmd *RpmbRequest; 252abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 253abdd2437Shisping t_teesmc32_param *TeeSmc32Param; 254abdd2437Shisping struct mmc *mmc; 255abdd2437Shisping 256efb93541SHisping Lin debug("TEEC: Entered RPMB RPC\n"); 257abdd2437Shisping 258abdd2437Shisping if (TeeSmc32Arg->num_params != 2) { 259abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 260abdd2437Shisping goto Exit; 261abdd2437Shisping } 262abdd2437Shisping 263abdd2437Shisping TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 2641f25ada2SHisping Lin RpmbRequest = (struct tee_rpc_rpmb_cmd *)(size_t) 265abdd2437Shisping TeeSmc32Param[0].u.memref.buf_ptr; 266abdd2437Shisping switch (RpmbRequest->cmd) { 267abdd2437Shisping case TEE_RPC_RPMB_CMD_DATA_REQ: { 268abdd2437Shisping RequestPackets = (EFI_RK_RPMB_DATA_PACKET *)(RpmbRequest + 1); 2691f25ada2SHisping Lin ResponsePackets = (EFI_RK_RPMB_DATA_PACKET *)(size_t) 270abdd2437Shisping TeeSmc32Param[1].u.memref.buf_ptr; 271abdd2437Shisping 272abdd2437Shisping global_block_count = 273abdd2437Shisping (RpmbRequest->block_count == 0 ? 274abdd2437Shisping 1 : RpmbRequest->block_count); 275abdd2437Shisping RequestPackets_back = 276abdd2437Shisping malloc(sizeof(EFI_RK_RPMB_DATA_PACKET_BACK) 277abdd2437Shisping * global_block_count); 278abdd2437Shisping memcpy(RequestPackets_back->stuff, 279abdd2437Shisping RequestPackets->stuff_bytes, 280abdd2437Shisping RPMB_STUFF_DATA_SIZE); 281abdd2437Shisping memcpy(RequestPackets_back->mac, 282abdd2437Shisping RequestPackets->key_mac, 283abdd2437Shisping RPMB_KEY_MAC_SIZE); 284abdd2437Shisping memcpy(RequestPackets_back->data, 285abdd2437Shisping RequestPackets->data, 286abdd2437Shisping RPMB_DATA_SIZE); 287abdd2437Shisping memcpy(RequestPackets_back->nonce, 288abdd2437Shisping RequestPackets->nonce, 289abdd2437Shisping RPMB_NONCE_SIZE); 290abdd2437Shisping RequestPackets_back->write_counter = 291abdd2437Shisping ((RequestPackets->write_counter[3]) << 24) + 292abdd2437Shisping ((RequestPackets->write_counter[2]) << 16) + 293abdd2437Shisping ((RequestPackets->write_counter[1]) << 8) + 294abdd2437Shisping (RequestPackets->write_counter[0]); 295abdd2437Shisping RequestPackets_back->address = 296abdd2437Shisping ((RequestPackets->address[1]) << 8) + 297abdd2437Shisping (RequestPackets->address[0]); 298abdd2437Shisping RequestPackets_back->block_count = 299abdd2437Shisping ((RequestPackets->block_count[1]) << 8) + 300abdd2437Shisping (RequestPackets->block_count[0]); 301abdd2437Shisping RequestPackets_back->result = 302abdd2437Shisping ((RequestPackets->op_result[1]) << 8) + 303abdd2437Shisping (RequestPackets->op_result[0]); 304abdd2437Shisping RequestPackets_back->request = 305abdd2437Shisping ((RequestPackets->msg_type[1]) << 8) + 306abdd2437Shisping (RequestPackets->msg_type[0]); 307abdd2437Shisping 308abdd2437Shisping RequestMsgType = RPMB_PACKET_DATA_TO_UINT16( 309abdd2437Shisping RequestPackets->msg_type); 310abdd2437Shisping 311efb93541SHisping Lin debug("TEEC: RPMB Data request %d\n", RequestMsgType); 312abdd2437Shisping 313abdd2437Shisping switch (RequestMsgType) { 314abdd2437Shisping case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM: { 31568ba9373SHisping Lin if (init_rpmb() != 0) { 316abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 317abdd2437Shisping break; 318abdd2437Shisping } 319abdd2437Shisping 320abdd2437Shisping EfiStatus = do_programkey((struct s_rpmb *) 321abdd2437Shisping RequestPackets_back); 322abdd2437Shisping 32368ba9373SHisping Lin if (finish_rpmb() != 0) { 324abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 325abdd2437Shisping break; 326abdd2437Shisping } 327abdd2437Shisping 328abdd2437Shisping if (EfiStatus != 0) { 329abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 330abdd2437Shisping break; 331abdd2437Shisping } 332abdd2437Shisping 333abdd2437Shisping break; 334abdd2437Shisping } 335abdd2437Shisping 336abdd2437Shisping case TEE_RPC_RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ: { 33768ba9373SHisping Lin if (init_rpmb() != 0) { 338abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 339abdd2437Shisping break; 340abdd2437Shisping } 341abdd2437Shisping 342abdd2437Shisping EfiStatus = do_readcounter((struct s_rpmb *) 343abdd2437Shisping RequestPackets_back); 34468ba9373SHisping Lin 34568ba9373SHisping Lin if (finish_rpmb() != 0) { 346abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 347abdd2437Shisping break; 348abdd2437Shisping } 349abdd2437Shisping 350abdd2437Shisping if (EfiStatus != 0) { 351abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 352abdd2437Shisping break; 353abdd2437Shisping } 354abdd2437Shisping 355abdd2437Shisping break; 356abdd2437Shisping } 357abdd2437Shisping 358abdd2437Shisping case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE: { 35968ba9373SHisping Lin if (init_rpmb() != 0) { 360abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 361abdd2437Shisping break; 362abdd2437Shisping } 363abdd2437Shisping 364abdd2437Shisping EfiStatus = do_authenticatedwrite((struct s_rpmb *) 365abdd2437Shisping RequestPackets_back); 36668ba9373SHisping Lin 36768ba9373SHisping Lin if (finish_rpmb() != 0) { 368abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 369abdd2437Shisping break; 370abdd2437Shisping } 371abdd2437Shisping 372abdd2437Shisping if (EfiStatus != 0) { 373abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 374abdd2437Shisping break; 375abdd2437Shisping } 376abdd2437Shisping 377abdd2437Shisping break; 378abdd2437Shisping } 379abdd2437Shisping 380abdd2437Shisping case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_READ: { 38168ba9373SHisping Lin if (init_rpmb() != 0) { 382abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 383abdd2437Shisping break; 384abdd2437Shisping } 385abdd2437Shisping 386abdd2437Shisping EfiStatus = do_authenticatedread((struct s_rpmb *) 387abdd2437Shisping RequestPackets_back, global_block_count); 38868ba9373SHisping Lin 38968ba9373SHisping Lin if (finish_rpmb() != 0) { 390abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 391abdd2437Shisping break; 392abdd2437Shisping } 393abdd2437Shisping 394abdd2437Shisping if (EfiStatus != 0) { 395abdd2437Shisping TeecResult = TEEC_ERROR_GENERIC; 396abdd2437Shisping break; 397abdd2437Shisping } 398abdd2437Shisping 399abdd2437Shisping break; 400abdd2437Shisping } 401abdd2437Shisping 402abdd2437Shisping default: 403abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 404abdd2437Shisping break; 405abdd2437Shisping } 406efb93541SHisping Lin debug("TEEC: RPMB TeecResult %d\n", TeecResult); 407abdd2437Shisping break; 408abdd2437Shisping } 409abdd2437Shisping 410abdd2437Shisping case TEE_RPC_RPMB_CMD_GET_DEV_INFO: { 41126690680SHisping Lin if (init_rpmb()) { 41226690680SHisping Lin TeecResult = TEEC_ERROR_GENERIC; 41326690680SHisping Lin goto Exit; 41426690680SHisping Lin } 41526690680SHisping Lin 416abdd2437Shisping mmc = do_returnmmc(); 41726690680SHisping Lin if (finish_rpmb()) { 41826690680SHisping Lin TeecResult = TEEC_ERROR_GENERIC; 41926690680SHisping Lin goto Exit; 42026690680SHisping Lin } 42126690680SHisping Lin 42226690680SHisping Lin if (mmc == NULL) { 42326690680SHisping Lin TeecResult = TEEC_ERROR_GENERIC; 42426690680SHisping Lin goto Exit; 42526690680SHisping Lin } 426abdd2437Shisping 4271f25ada2SHisping Lin DevInfo = (struct tee_rpc_rpmb_dev_info *)(size_t) 428abdd2437Shisping TeeSmc32Param[1].u.memref.buf_ptr; 429abdd2437Shisping 430abdd2437Shisping DevInfo->cid[0] = (mmc->cid[0]) >> 24 & 0xff; 431abdd2437Shisping DevInfo->cid[1] = (mmc->cid[0]) >> 16 & 0xff; 432abdd2437Shisping DevInfo->cid[2] = (mmc->cid[0]) >> 8 & 0xff; 433abdd2437Shisping DevInfo->cid[3] = (mmc->cid[0]) & 0xff; 434abdd2437Shisping DevInfo->cid[4] = (mmc->cid[1]) >> 24 & 0xff; 435abdd2437Shisping DevInfo->cid[5] = (mmc->cid[1]) >> 16 & 0xff; 436abdd2437Shisping DevInfo->cid[6] = (mmc->cid[1]) >> 8 & 0xff; 437abdd2437Shisping DevInfo->cid[7] = (mmc->cid[1]) & 0xff; 438abdd2437Shisping DevInfo->cid[8] = (mmc->cid[2]) >> 24 & 0xff; 439abdd2437Shisping DevInfo->cid[9] = (mmc->cid[2]) >> 16 & 0xff; 440abdd2437Shisping DevInfo->cid[10] = (mmc->cid[2]) >> 8 & 0xff; 441abdd2437Shisping DevInfo->cid[11] = (mmc->cid[2]) & 0xff; 442abdd2437Shisping DevInfo->cid[12] = (mmc->cid[3]) >> 24 & 0xff; 443abdd2437Shisping DevInfo->cid[13] = (mmc->cid[3]) >> 16 & 0xff; 444abdd2437Shisping DevInfo->cid[14] = (mmc->cid[3]) >> 8 & 0xff; 445abdd2437Shisping DevInfo->cid[15] = (mmc->cid[3]) & 0xff; 446abdd2437Shisping DevInfo->rel_wr_sec_c = 1; 447abdd2437Shisping DevInfo->rpmb_size_mult = 448abdd2437Shisping (uint8_t)(mmc->capacity_rpmb / (128 * 1024)); 449abdd2437Shisping DevInfo->ret_code = 0; 450abdd2437Shisping 451abdd2437Shisping goto Exit; 452abdd2437Shisping } 453abdd2437Shisping 454abdd2437Shisping default: 455abdd2437Shisping TeecResult = TEEC_ERROR_BAD_PARAMETERS; 456abdd2437Shisping 457abdd2437Shisping goto Exit; 458abdd2437Shisping } 459abdd2437Shisping 460abdd2437Shisping tempPackets = ResponsePackets; 461abdd2437Shisping tempPackets_back = RequestPackets_back; 462abdd2437Shisping 463abdd2437Shisping for (i = 0; i < global_block_count; i++) { 464abdd2437Shisping memcpy(tempPackets->stuff_bytes, 465abdd2437Shisping tempPackets_back->stuff, 466abdd2437Shisping RPMB_STUFF_DATA_SIZE); 467abdd2437Shisping memcpy(tempPackets->key_mac, 468abdd2437Shisping tempPackets_back->mac, 469abdd2437Shisping RPMB_KEY_MAC_SIZE); 470abdd2437Shisping memcpy(tempPackets->data, 471abdd2437Shisping tempPackets_back->data, 472abdd2437Shisping RPMB_DATA_SIZE); 473abdd2437Shisping memcpy(tempPackets->nonce, 474abdd2437Shisping tempPackets_back->nonce, 475abdd2437Shisping RPMB_NONCE_SIZE); 476abdd2437Shisping tempPackets->write_counter[3] = 477abdd2437Shisping ((tempPackets_back->write_counter) >> 24) & 0xFF; 478abdd2437Shisping tempPackets->write_counter[2] = 479abdd2437Shisping ((tempPackets_back->write_counter) >> 16) & 0xFF; 480abdd2437Shisping tempPackets->write_counter[1] = 481abdd2437Shisping ((tempPackets_back->write_counter) >> 8) & 0xFF; 482abdd2437Shisping tempPackets->write_counter[0] = 483abdd2437Shisping (tempPackets_back->write_counter) & 0xFF; 484abdd2437Shisping tempPackets->address[1] = 485abdd2437Shisping ((tempPackets_back->address) >> 8) & 0xFF; 486abdd2437Shisping tempPackets->address[0] = 487abdd2437Shisping (tempPackets_back->address) & 0xFF; 488abdd2437Shisping tempPackets->block_count[1] = 489abdd2437Shisping ((tempPackets_back->block_count) >> 8) & 0xFF; 490abdd2437Shisping tempPackets->block_count[0] = 491abdd2437Shisping (tempPackets_back->block_count) & 0xFF; 492abdd2437Shisping tempPackets->op_result[1] = 493abdd2437Shisping ((tempPackets_back->result) >> 8) & 0xFF; 494abdd2437Shisping tempPackets->op_result[0] = 495abdd2437Shisping (tempPackets_back->result) & 0xFF; 496abdd2437Shisping tempPackets->msg_type[1] = 497abdd2437Shisping ((tempPackets_back->request) >> 8) & 0xFF; 498abdd2437Shisping tempPackets->msg_type[0] = 499abdd2437Shisping (tempPackets_back->request) & 0xFF; 500abdd2437Shisping tempPackets++; 501abdd2437Shisping tempPackets_back++; 502abdd2437Shisping } 503abdd2437Shisping 504abdd2437Shisping free(RequestPackets_back); 505abdd2437Shisping 506abdd2437Shisping Exit: 507abdd2437Shisping TeeSmc32Arg->ret = TeecResult; 508abdd2437Shisping TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API; 509abdd2437Shisping 510abdd2437Shisping return TeecResult; 511abdd2437Shisping } 512abdd2437Shisping 513abdd2437Shisping /* 514abdd2437Shisping * Execute a normal world local file system operation. 515abdd2437Shisping */ 516abdd2437Shisping TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg) 517abdd2437Shisping { 5181f25ada2SHisping Lin TEEC_Result TeecResult = TEEC_SUCCESS; 5191f25ada2SHisping Lin t_teesmc32_param *TeeSmc32Param; 520abdd2437Shisping 5211f25ada2SHisping Lin TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 5223251364cSHisping Lin #ifdef CONFIG_OPTEE_V1 523*d079c1a5SHisping Lin TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr, 5241f25ada2SHisping Lin TeeSmc32Param[0].u.memref.size); 5253251364cSHisping Lin #endif 5263251364cSHisping Lin #ifdef CONFIG_OPTEE_V2 5273251364cSHisping Lin TeecResult = tee_supp_rk_fs_process((size_t)TeeSmc32Arg->num_params, 5283251364cSHisping Lin (struct tee_ioctl_param *)TeeSmc32Param); 5293251364cSHisping Lin #endif 5301f25ada2SHisping Lin 5311f25ada2SHisping Lin return TeecResult; 5321f25ada2SHisping Lin } 533abdd2437Shisping 534abdd2437Shisping /* 535abdd2437Shisping * TBD. 536abdd2437Shisping */ 537abdd2437Shisping TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg) 538abdd2437Shisping { 539abdd2437Shisping return TEEC_ERROR_NOT_IMPLEMENTED; 540abdd2437Shisping } 541abdd2437Shisping 542abdd2437Shisping /* 543abdd2437Shisping * TBD. 544abdd2437Shisping */ 545abdd2437Shisping TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg) 546abdd2437Shisping { 547abdd2437Shisping return TEEC_ERROR_NOT_IMPLEMENTED; 548abdd2437Shisping } 549abdd2437Shisping 550abdd2437Shisping /* 551abdd2437Shisping * Handle the callback from secure world. 552abdd2437Shisping */ 553abdd2437Shisping TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs) 554abdd2437Shisping { 555abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 556abdd2437Shisping 5571f25ada2SHisping Lin //printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n", 5581f25ada2SHisping Lin //ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2); 559abdd2437Shisping 560abdd2437Shisping switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) { 561abdd2437Shisping case TEESMC_RPC_FUNC_ALLOC_ARG: { 5621f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 563abdd2437Shisping TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 5641f25ada2SHisping Lin #endif 5651f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 566efb93541SHisping Lin debug("TEEC: ArmSmcArgs->Arg1 = 0x%x \n", ArmSmcArgs->Arg1); 5671f25ada2SHisping Lin TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2); 5681f25ada2SHisping Lin ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2; 5691f25ada2SHisping Lin ArmSmcArgs->Arg1 = 0; 5701f25ada2SHisping Lin ArmSmcArgs->Arg4 = 0; 5711f25ada2SHisping Lin #endif 572abdd2437Shisping break; 573abdd2437Shisping } 574abdd2437Shisping 575abdd2437Shisping case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: { 576abdd2437Shisping TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 577abdd2437Shisping break; 578abdd2437Shisping } 579abdd2437Shisping 580abdd2437Shisping case TEESMC_RPC_FUNC_FREE_ARG: { 5811f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 582abdd2437Shisping TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 5831f25ada2SHisping Lin #endif 5841f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 5851f25ada2SHisping Lin TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2); 5861f25ada2SHisping Lin #endif 587abdd2437Shisping break; 588abdd2437Shisping } 589abdd2437Shisping 590abdd2437Shisping case TEESMC_RPC_FUNC_FREE_PAYLOAD: { 591abdd2437Shisping TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 592abdd2437Shisping break; 593abdd2437Shisping } 594abdd2437Shisping 595abdd2437Shisping case TEESMC_RPC_FUNC_IRQ: { 596abdd2437Shisping break; 597abdd2437Shisping } 598abdd2437Shisping 599abdd2437Shisping case TEESMC_RPC_FUNC_CMD: { 6001f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 601abdd2437Shisping t_teesmc32_arg *TeeSmc32Arg = 6021f25ada2SHisping Lin (t_teesmc32_arg *)(size_t)ArmSmcArgs->Arg1; 6031f25ada2SHisping Lin #endif 6041f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 6051f25ada2SHisping Lin t_teesmc32_arg *TeeSmc32Arg = 606d156c9ffSHisping Lin (t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2); 607efb93541SHisping Lin debug("TEEC: TeeSmc32Arg->cmd = 0x%x\n", TeeSmc32Arg->cmd); 6081f25ada2SHisping Lin #endif 609abdd2437Shisping switch (TeeSmc32Arg->cmd) { 6101f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 611abdd2437Shisping case TEE_RPC_LOAD_TA: { 612abdd2437Shisping TeecResult = OpteeRpcCmdLoadTa(TeeSmc32Arg); 613abdd2437Shisping break; 614abdd2437Shisping } 615abdd2437Shisping 616abdd2437Shisping case TEE_RPC_FREE_TA: { 617abdd2437Shisping TeecResult = OpteeRpcCmdFreeTa(TeeSmc32Arg); 618abdd2437Shisping break; 619abdd2437Shisping } 620abdd2437Shisping 621abdd2437Shisping case TEE_RPC_RPMB_CMD: { 622abdd2437Shisping TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg); 623abdd2437Shisping break; 624abdd2437Shisping } 625abdd2437Shisping 626abdd2437Shisping case TEE_RPC_FS: { 627abdd2437Shisping TeecResult = OpteeRpcCmdFs(TeeSmc32Arg); 6281f25ada2SHisping Lin TeeSmc32Arg->ret = TEEC_SUCCESS; 629abdd2437Shisping break; 630abdd2437Shisping } 631abdd2437Shisping 632abdd2437Shisping case TEE_RPC_GET_TIME: { 633abdd2437Shisping TeecResult = OpteeRpcCmdGetTime(TeeSmc32Arg); 634abdd2437Shisping break; 635abdd2437Shisping } 636abdd2437Shisping 637abdd2437Shisping case TEE_RPC_WAIT_MUTEX: { 638abdd2437Shisping TeecResult = OpteeRpcCmdWaitMutex(TeeSmc32Arg); 639abdd2437Shisping break; 640abdd2437Shisping } 6411f25ada2SHisping Lin #endif 6421f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 6431f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: { 6441f25ada2SHisping Lin uint32_t tempaddr; 6451f25ada2SHisping Lin uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b; 6461f25ada2SHisping Lin TeecResult = OpteeRpcAlloc(allocsize, &tempaddr); 647efb93541SHisping Lin debug("TEEC: allocsize = 0x%x tempaddr = 0x%x\n", allocsize, tempaddr); 6481f25ada2SHisping Lin TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2; 6491f25ada2SHisping Lin TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr; 6501f25ada2SHisping Lin TeeSmc32Arg->params[0].u.memref.size = allocsize; 6511f25ada2SHisping Lin TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr; 6521f25ada2SHisping Lin TeeSmc32Arg->ret = TEE_SUCCESS; 6531f25ada2SHisping Lin break; 6541f25ada2SHisping Lin } 6551f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: { 6561f25ada2SHisping Lin uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b; 6571f25ada2SHisping Lin TeecResult = OpteeRpcFree(tempaddr); 6581f25ada2SHisping Lin break; 6591f25ada2SHisping Lin 6601f25ada2SHisping Lin } 6611f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_RPMB_V2: { 6621f25ada2SHisping Lin TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg); 6631f25ada2SHisping Lin break; 6641f25ada2SHisping Lin } 6653251364cSHisping Lin case OPTEE_MSG_RPC_CMD_FS_V2: { 6663251364cSHisping Lin TeecResult = OpteeRpcCmdFs(TeeSmc32Arg); 6673251364cSHisping Lin TeeSmc32Arg->ret = TEEC_SUCCESS; 6683251364cSHisping Lin break; 6693251364cSHisping Lin } 6701f25ada2SHisping Lin case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: { 6711f25ada2SHisping Lin TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg); 6721f25ada2SHisping Lin break; 6731f25ada2SHisping Lin } 6741f25ada2SHisping Lin #endif 675abdd2437Shisping 676abdd2437Shisping default: { 677efb93541SHisping Lin printf("TEEC: ...unsupported RPC CMD: cmd=0x%X\n", 678abdd2437Shisping TeeSmc32Arg->cmd); 679abdd2437Shisping TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 680abdd2437Shisping break; 681abdd2437Shisping } 682abdd2437Shisping } 683abdd2437Shisping 684abdd2437Shisping break; 685abdd2437Shisping } 686abdd2437Shisping 687abdd2437Shisping case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: { 688abdd2437Shisping TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1); 689abdd2437Shisping ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1; 690abdd2437Shisping break; 691abdd2437Shisping } 692abdd2437Shisping 693abdd2437Shisping case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: { 694abdd2437Shisping TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1); 695abdd2437Shisping break; 696abdd2437Shisping } 697abdd2437Shisping 698abdd2437Shisping default: { 699efb93541SHisping Lin printf("TEEC: ...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0); 700abdd2437Shisping TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 701abdd2437Shisping break; 702abdd2437Shisping } 703abdd2437Shisping } 704abdd2437Shisping 705abdd2437Shisping ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC; 706efb93541SHisping Lin debug("TEEC: OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult); 707abdd2437Shisping 708abdd2437Shisping return TeecResult; 709abdd2437Shisping } 710