| /* |
| * Copyright (C) 2016 Freescale Semiconductor, Inc. |
| * Copyright 2017-2019 NXP |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| /*! |
| * File containing client-side RPC functions for the SECO service. These |
| * functions are ported to clients that communicate to the SC. |
| * |
| * @addtogroup SECO_SVC |
| * @{ |
| */ |
| |
| /* Includes */ |
| |
| #include <sci/sci_types.h> |
| #include <sci/svc/rm/sci_rm_api.h> |
| #include <sci/svc/seco/sci_seco_api.h> |
| #include <sci/sci_rpc.h> |
| #include "sci_seco_rpc.h" |
| #include <stdlib.h> |
| |
| /* Local Defines */ |
| |
| /* Local Types */ |
| |
| /* Local Functions */ |
| |
| sc_err_t sc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src, |
| sc_faddr_t addr_dst, uint32_t len, sc_bool_t fw) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_IMAGE_LOAD); |
| RPC_U32(&msg, 0U) = U32(addr_src >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr_src); |
| RPC_U32(&msg, 8U) = U32(addr_dst >> 32ULL); |
| RPC_U32(&msg, 12U) = U32(addr_dst); |
| RPC_U32(&msg, 16U) = U32(len); |
| RPC_U8(&msg, 20U) = B2U8(fw); |
| RPC_SIZE(&msg) = 7U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_authenticate(sc_ipc_t ipc, |
| sc_seco_auth_cmd_t cmd, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_AUTHENTICATE); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_U8(&msg, 8U) = U8(cmd); |
| RPC_SIZE(&msg) = 4U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t change) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_FORWARD_LIFECYCLE); |
| RPC_U32(&msg, 0U) = U32(change); |
| RPC_SIZE(&msg) = 2U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_RETURN_LIFECYCLE); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_commit(sc_ipc_t ipc, uint32_t *info) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_COMMIT); |
| RPC_U32(&msg, 0U) = *PTR_U32(info); |
| RPC_SIZE(&msg) = 2U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| *info = RPC_U32(&msg, 0U); |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_attest_mode(sc_ipc_t ipc, uint32_t mode) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_ATTEST_MODE); |
| RPC_U32(&msg, 0U) = U32(mode); |
| RPC_SIZE(&msg) = 2U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_attest(sc_ipc_t ipc, uint64_t nonce) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_ATTEST); |
| RPC_U32(&msg, 0U) = U32(nonce >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(nonce); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_get_attest_pkey(sc_ipc_t ipc, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_GET_ATTEST_PKEY); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_get_attest_sign(sc_ipc_t ipc, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_GET_ATTEST_SIGN); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_attest_verify(sc_ipc_t ipc, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_ATTEST_VERIFY); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_gen_key_blob(sc_ipc_t ipc, uint32_t id, |
| sc_faddr_t load_addr, sc_faddr_t export_addr, uint16_t max_size) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_GEN_KEY_BLOB); |
| RPC_U32(&msg, 0U) = U32(load_addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(load_addr); |
| RPC_U32(&msg, 8U) = U32(export_addr >> 32ULL); |
| RPC_U32(&msg, 12U) = U32(export_addr); |
| RPC_U32(&msg, 16U) = U32(id); |
| RPC_U16(&msg, 20U) = U16(max_size); |
| RPC_SIZE(&msg) = 7U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_load_key(sc_ipc_t ipc, uint32_t id, |
| sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_LOAD_KEY); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_U32(&msg, 8U) = U32(id); |
| RPC_SIZE(&msg) = 4U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr, |
| uint16_t dst_size) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_GET_MP_KEY); |
| RPC_U32(&msg, 0U) = U32(dst_addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(dst_addr); |
| RPC_U16(&msg, 8U) = U16(dst_size); |
| RPC_SIZE(&msg) = 4U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, |
| uint8_t size, uint8_t lock) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_UPDATE_MPMR); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_U8(&msg, 8U) = U8(size); |
| RPC_U8(&msg, 9U) = U8(lock); |
| RPC_SIZE(&msg) = 4U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, |
| uint16_t msg_size, sc_faddr_t dst_addr, uint16_t dst_size) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_GET_MP_SIGN); |
| RPC_U32(&msg, 0U) = U32(msg_addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(msg_addr); |
| RPC_U32(&msg, 8U) = U32(dst_addr >> 32ULL); |
| RPC_U32(&msg, 12U) = U32(dst_addr); |
| RPC_U16(&msg, 16U) = U16(msg_size); |
| RPC_U16(&msg, 18U) = U16(dst_size); |
| RPC_SIZE(&msg) = 6U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| void sc_seco_build_info(sc_ipc_t ipc, uint32_t *version, |
| uint32_t *commit) |
| { |
| sc_rpc_msg_t msg; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_BUILD_INFO); |
| RPC_SIZE(&msg) = 1U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| if (version != NULL) |
| *version = RPC_U32(&msg, 0U); |
| |
| if (commit != NULL) |
| *commit = RPC_U32(&msg, 4U); |
| } |
| |
| sc_err_t sc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc, |
| uint16_t *monotonic, uint32_t *uid_l, uint32_t *uid_h) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_CHIP_INFO); |
| RPC_SIZE(&msg) = 1U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| if (uid_l != NULL) |
| *uid_l = RPC_U32(&msg, 0U); |
| |
| if (uid_h != NULL) |
| *uid_h = RPC_U32(&msg, 4U); |
| |
| if (lc != NULL) |
| *lc = RPC_U16(&msg, 8U); |
| |
| if (monotonic != NULL) |
| *monotonic = RPC_U16(&msg, 10U); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_ENABLE_DEBUG); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_get_event(sc_ipc_t ipc, uint8_t idx, |
| uint32_t *event) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_GET_EVENT); |
| RPC_U8(&msg, 0U) = U8(idx); |
| RPC_SIZE(&msg) = 2U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| if (event != NULL) |
| *event = RPC_U32(&msg, 0U); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| sc_err_t sc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr) |
| { |
| sc_rpc_msg_t msg; |
| uint8_t result; |
| |
| RPC_VER(&msg) = SC_RPC_VERSION; |
| RPC_SVC(&msg) = U8(SC_RPC_SVC_SECO); |
| RPC_FUNC(&msg) = U8(SECO_FUNC_FUSE_WRITE); |
| RPC_U32(&msg, 0U) = U32(addr >> 32ULL); |
| RPC_U32(&msg, 4U) = U32(addr); |
| RPC_SIZE(&msg) = 3U; |
| |
| sc_call_rpc(ipc, &msg, SC_FALSE); |
| |
| result = RPC_R8(&msg); |
| return (sc_err_t)result; |
| } |
| |
| /**@}*/ |
| |