arm tf-m 源代码分析

main入口

在此文件中:
tfm/secure_fw/spm/cmsis_psa/main.c

Main()  
    ->tfm_arch_set_msplim((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base));  //设置堆栈限制
    ->fih_delay_init();
    ->tfm_core_init()
	->tfm_hal_set_up_static_boundaries
		->configure_mpu(rnr++, base, limit, XN_EXEC_OK, AP_RO_PRIV_UNPRIV);  //配置各个内存边界的读写属性
	->tfm_hal_platform_init()  //核心函数,需要重点展开分析
		->__enable_irq();  //使能中断
    		->stdio_init();  //初始化串口
		-> corstone1000_watchdog_init()  //初始化看门狗
		-> fwu_metadata_init()
			-> FWU_METADATA_FLASH_DEV.Initialize(NULL)   //初始化FWU metadata所在的FLASH,就是 32MB 那个
			-> flash_info = FWU_METADATA_FLASH_DEV.GetInfo()
		-> corstone1000_host_watchdog_handler_init()
	->tfm_plat_otp_init()
	->tfm_plat_provisioning_perform()
		-> tfm_plat_otp_read   //读OTP值
	->tfm_arch_config_extensions()
		->SCB->NSACR |= SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk;
->SCnSCB->CPPWR |= SCnSCB_CPPWR_SUS11_Msk | SCnSCB_CPPWR_SUS10_Msk;
	->SPMLOG_DBGMSGVAL("TF-M isolation level is: ", TFM_LVL);
    ->SPMLOG_INFMSG("\033[1;34m Booting TFM v"VERSION_FULLSTR"\033[0m\r\n");  /* Print the TF-M version */
    ->tfm_arch_clear_fp_status();   //汇编代码
    ->tfm_core_handler_mode();     //发送SVC命令,触发tfm_spm_init(),这个函数是PSA的重点

//tfm_core_handler_mode()函数定义如下,它会调用SVC命令,并且,传递一个参数 TFM_SVC_SPM_INIT,最终,会调用到SVC_Handler, 最后,根据ID,调用到 tfm_spm_init()函数,后面会重点讲到tfm_spm_init()函数

__attribute__ ((naked)) void   tfm_core_handler_mode(void)
{
    __ASM volatile("SVC %0           \n"
                   "BX LR            \n"
                   : : "I" (TFM_SVC_SPM_INIT));
}

PendSV响应

PendSV(可悬起的系统调用),它和SVC 协同使用
SVC异常是必须立即得到响应的,应用程序执行SVC 时都是希望所需的请求立即得到响应。
PendSV 则不同,它是可以像普通的中断一样被抢占挂起的

PendSV_Handle

SVC响应

SVC_Handler
	->BL   tfm_core_svc_handler
		->tfm_core_svc_handler
			-> case TFM_SVC_SPM_INIT:      tfm_spm_init()  //初始化SPM
			-> case TFM_SVC_GET_BOOT_DATA:        tfm_core_get_boot_data_handler(svc_args);
   			-> case TFM_SVC_PREPARE_DEPRIV_FLIH:      tfm_flih_prepare_depriv_flih (struct partition_t *)svc_args[0],  (uintptr_t)svc_args[1]);
    		-> case TFM_SVC_FLIH_FUNC_RETURN:       tfm_flih_return_to_isr(svc_args[0],  (struct context_flih_ret_t *)msp);
			-> default: svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, exc_return);  //根据Client端调用SVC命令时,传入的ID,进入不同的case处理函数

tfm_spm_init

tfm_spm_init
->tfm_pool_init(conn_handle_pool,POOL_BUFFER_SIZE(conn_handle_pool),sizeof(struct conn_handle_t),
                  	CONFIG_TFM_CONN_HANDLE_MAX_NUM)
->load_a_partition_assuredly   //从 section: .part.load 段中,依次获取一个 一个的partition_load_info_t
		-> p_ptldinf->psa_ff_ver  //检查Magic是否是:0x5F5F0000
		->UNI_LIST_INSERT_AFTER(head, partition, next)  //加到链表头部
		-> load_irqs_assuredly(partition)  //从partition中,获取到struct irq_load_info_t
			->p_irq_info->init(p_partition, p_irq_info)
				-> mailbox_irq_init()  //初始化mailbox中断
				-> tfm_hal_irq_enable(p_irq_info->source)  //使能中断
	-> backend_instance.comp_init_assuredly(partition, service_setting)  // backend_instance 定义在backend_ipc.c中
	-> backend_instance.system_run()  //开始调度

//如下所示,在section: .part.load 段中, 定义了一下 tfm_ns_mailbox_agent_load,该结构体是Cmake文件中,通过解析 yaml后,自动生成的:

const struct partition_tfm_ns_mailbox_agent_load_info_t    tfm_ns_mailbox_agent_load
    __attribute__((used, section(".part_load"))) = {
    .load_info = {
        .psa_ff_ver                 = 0x0101 | PARTITION_INFO_MAGIC,
        .pid                        = TFM_NS_MAILBOX_AGENT,
        .flags                      = 0
                                    | PARTITION_MODEL_IPC
                                    | PARTITION_MODEL_PSA_ROT
                                    | PARTITION_PRI_LOW,
        .entry                      = ENTRY_TO_POSITION(ns_agent_mailbox_entry),   //这里关联到了mailbox
        .stack_size                 = 0x800,
        .heap_size                  = 0,
        .ndeps                      = TFM_NS_MAILBOX_AGENT_NDEPS,
        .nservices                  = TFM_NS_MAILBOX_AGENT_NSERVS,
        .nassets                    = TFM_NS_MAILBOX_AGENT_NASSETS,
        .nirqs                      = TFM_NS_MAILBOX_AGENT_NIRQS,
    },
    .stack_addr                     = (uintptr_t)tfm_ns_mailbox_agent_stack,
    .heap_addr                      = 0,
#if TFM_LVL == 3
    .assets                         = {
        {
            .mem.start              = PART_REGION_ADDR(PT_TFM_NS_MAILBOX_AGENT_PRIVATE, _DATA_START$$Base),
            .mem.limit              = PART_REGION_ADDR(PT_TFM_NS_MAILBOX_AGENT_PRIVATE, _DATA_END$$Base),
            .attr                   = ASSET_ATTR_READ_WRITE,
        },
    },
#else
#endif
    .irqs = {
        {
            .init = mailbox_irq_init,
            .flih_func = 0,
            .pid = TFM_NS_MAILBOX_AGENT,
            .source = MAILBOX_IRQ,
            .signal = MAILBOX_SIGNAL,
        },
    },
};

//在链接脚本中,tfm/platform/ext/common/gcc/tfm_common_s.ld 有如下定义,可以看到Image$$TFM_SP_LOAD_LIST$$RO$$Base指向了.part_load 这个section的起始地址
//在load_a_partition_assuredly ()中,将会通过 Image$$TFM_SP_LOAD_LIST$$RO$$Base 找到 所有的 load_info,并且去加载它们:

.TFM_SP_LOAD_LIST : ALIGN(4)
{
   KEEP(*(.part_load))
} > FLASH
Image$$TFM_SP_LOAD_LIST$$RO$$Base = ADDR(.TFM_SP_LOAD_LIST);
Image$$TFM_SP_LOAD_LIST$$RO$$Limit = ADDR(.TFM_SP_LOAD_LIST) + SIZEOF(.TFM_SP_LOAD_LIST);
. = ALIGN(32);

//tfm/secure_fw/spm/ffm/backend_ipc.c

const struct backend_ops_t backend_instance = {
    .comp_init_assuredly = ipc_comp_init_assuredly,
    .system_run          = ipc_system_run,
    .messaging           = ipc_messaging,
    .replying            = ipc_replying,
};
ipc_system_run
	-> thrd_start_scheduler(&CURRENT_THREAD)

SVC_Handler_IPC

在M核的代码中调用SVC汇编指令,都会进入到这个处理中来:

static int32_t SVC_Handler_IPC(uint8_t svc_num, uint32_t *ctx,
                               uint32_t lr)
{
    psa_status_t status = PSA_SUCCESS;

    switch (svc_num) {
    case TFM_SVC_PSA_FRAMEWORK_VERSION:
        return  tfm_spm_client_psa_framework_version();
    case TFM_SVC_PSA_VERSION:
        return tfm_spm_client_psa_version(ctx[0]);
    case TFM_SVC_PSA_CALL:
        status = tfm_spm_client_psa_call((psa_handle_t)ctx[0], ctx[1],
                                         (const psa_invec *)ctx[2],
                                         (psa_outvec *)ctx[3]);
        break;
    case TFM_SVC_PSA_WAIT:
        return tfm_spm_partition_psa_wait((psa_signal_t)ctx[0], ctx[1]);
    case TFM_SVC_PSA_GET:
        return tfm_spm_partition_psa_get((psa_signal_t)ctx[0],
                                         (psa_msg_t *)ctx[1]);
    case TFM_SVC_PSA_READ:
        return tfm_spm_partition_psa_read((psa_handle_t)ctx[0], ctx[1],
                                          (void *)ctx[2], (size_t)ctx[3]);
    case TFM_SVC_PSA_SKIP:
        return tfm_spm_partition_psa_skip((psa_handle_t)ctx[0], ctx[1],
                                          (size_t)ctx[2]);
    case TFM_SVC_PSA_WRITE:
        tfm_spm_partition_psa_write((psa_handle_t)ctx[0], ctx[1],
                                    (void *)ctx[2], (size_t)ctx[3]);
        break;
    case TFM_SVC_PSA_REPLY:
        tfm_spm_partition_psa_reply((psa_handle_t)ctx[0], (psa_status_t)ctx[1]);
        break;
    case TFM_SVC_PSA_NOTIFY:
        tfm_spm_partition_psa_notify((int32_t)ctx[0]);
        break;
    …略

如何与A核通信ns_agent_mailbox_entry

ns_agent_mailbox_entry
->boot_ns_core();   //启动A核
    	->tfm_inter_core_comm_init()
		->tfm_spe_openamp_lib_init    //OpenAMP以及MHU相关初始化
->tfm_dual_core_hal_init  
->initialize_host_to_secure_enclave_mhu();   //初始化MHU 驱动
	->mhu_v2_x_driver_init(&MHU1_SE_TO_HOST_DEV, MHU_REV_READ_FROM_HW)
    initialize_secure_enclave_to_host_mhu();  //初始化MHU 驱动
	->mhu_v2_x_driver_init(&MHU1_HOST_TO_SE_DEV, MHU_REV_READ_FROM_HW)
->tfm_to_openamp_init(callback_from_openamp, notify_request_from_openamp)
	-> metal_init(&metal_params)  //调用metal params库
	-> metal_register_generic_device(&shm_device)
	-> metal_device_open("generic", SHM_DEVICE_NAME, &device)
	-> metal_device_io_region(device, 0)
	-> virtqueue_allocate(VRING_SIZE)
	-> rpmsg_virtio_init_shm_pool(&shpool, (void *)SHM_START_VIRT_ADDR, SHM_SIZE);
    	-> rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, io, &shpool)
->init_dual_core_psa_client_secure_lib()
->tfm_rpc_register_ops(&openamp_rpc_ops)
    	->psa_irq_enable(MAILBOX_SIGNAL)
		->psa_irq_enable_svc
			-> tfm_spm_partition_psa_irq_enable((psa_signal_t)ctx[0])  //使能MHU中断
	-> signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK) //进入while(1)循环,等待来信号
	-> tfm_rpc_client_call_handler()   //处理RPC消息

MHU中断处理

所有从外部host发来的安全服务调用请求,都会从MHU中断处理函数这里开始:

HSE1_RECEIVER_COMBINED_IRQHandler
->spm_handle_interrupt(mbox_irq_info.p_pt, mbox_irq_info.p_ildi);
		-> spm_assert_signal(p_pt, p_ildi->signal)
			->thrd_wake_up(&partition->waitobj, partition->signals_asserted & partition->signals_waiting)
				->thrd_set_state(p_sync_obj->owner, THRD_STATE_RUNNABLE)
		-> tfm_arch_trigger_pendsv()   //唤醒mailbox 线程,进入到 ns_agent_mailbox_entry
			->ns_agent_mailbox_entry
				->psa_eoi(MAILBOX_SIGNAL);
            			->tfm_rpc_client_call_handler()
					-> rpc_ops.handle_req()  // rpc_ops指向static const struct tfm_rpc_ops_t openamp_rpc_ops,而不是默认的 static struct tfm_rpc_ops_t   rpc_ops			
->mhu_v2_x_channel_clear(&MHU1_HOST_TO_SE_DEV, 0);
->NVIC_ClearPendingIRQ(HSE1_RECEIVER_COMBINED_IRQn);

rpc_ops是在如下这里初始化的的:

ns_agent_mailbox_entry
->tfm_inter_core_comm_init
->tfm_spe_openamp_lib_init
			->tfm_to_openamp_init(callback_from_openamp, notify_request_from_openamp)
			->init_dual_core_psa_client_secure_lib()
			->tfm_rpc_register_ops(&openamp_rpc_ops)
				-> rpc_ops.handle_req = tfm_to_openamp_notify

openamp_rpc_ops 定义在这里:

static const struct tfm_rpc_ops_t openamp_rpc_ops = {
    .handle_req = tfm_to_openamp_notify, /* notify openamp for pendsv/irq
                                          * received from the non-secure */
    .reply      = service_reply,
    .get_caller_data = get_caller_private_data,
};

所以在mhu中断处理中,rpc_ops.handle_req() 将会调用到这里来:

rpc_ops.handle_req()  // rpc_ops指向static const struct tfm_rpc_ops_t openamp_rpc_ops,而不是默认的 static struct tfm_rpc_ops_t   rpc_ops
	-> tfm_to_openamp_notify
		->virtqueue_notification(vq[0])
			-> vq->callback(vq)

Callback 在哪里赋值的呢?

tfm_spe_openamp_lib_init
	->tfm_callback = cb;
->tfm_notify = notify
->tfm_to_openamp_init
->rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, io, &shpool)
->rpmsg_init_vdev
			->callback[0] = rpmsg_virtio_rx_callback   //前面的 vq->callback(),实际上对应于这里的 rpmsg_virtio_rx_callback   
->rpmsg_virtio_create_virtqueues
->virtio_create_virtqueues
					->virtqueue_create(vdev, i, names[i], vring_alloc,
				       		callbacks[i], vdev->func->notify,
				       		vring_info->vq)
						-> vq->callback = callback   //将rpmsg_virtio_rx_callback   赋值给了 vq->callback
						-> vq->notify = notify

在哪里绑定endpoint?
rpmsg_init_vdev中,会先注册一个name service的内置的匿名端点的endpoint:

rpmsg_init_vdev
->rpmsg_initialize_ept(&rdev->ns_ept, "NS",
				     RPMSG_NS_EPT_ADDR, RPMSG_NS_EPT_ADDR,
				     rpmsg_virtio_ns_callback, NULL);  //初始化name service端点
		-> ept->cb = rpmsg_virtio_ns_callback  //给ept->cb赋值为endpoint_cb
->rpmsg_register_endpoint(rdev, &rdev->ns_ept);  //挂入全局链表

当MHU收到name service消息后,rpmsg_virtio_rx_callback会调用rpmsg_get_endpoint,通过发送端在消息中写入的地址:RPMSG_NS_EPT_ADDR,就能找到 NS端点对应的endpoint
然后,会调用到它对应的的callback,rpmsg_virtio_ns_callback在这里调用后,会去创建普通的端点:

rpmsg_virtio_rx_callback
	->ept->cb(ept, RPMSG_LOCATE_DATA(rp_hdr), rp_hdr->len, rp_hdr->src, ept->priv)  //NS对应的cb在前面已经被过了,所以会进入到rpmsg_virtio_ns_callback
->rpmsg_virtio_ns_callback
			-》rdev->ns_bind_cb(rdev, name, dest)  //调用到rpmsg_init_vdev传入的ns_bind_cb
				->ns_bind_cb()
					-rpmsg_create_ept(ep, rdev, name, RPMSG_ADDR_ANY, dest, endpoint_cb, rpmsg_service_unbind)  //创建普通端点
						-rpmsg_initialize_ept(ept, name, addr, dest, cb, unbind_cb)
							-》ept->cb = endpoint_cb  //给ept->cb赋值为endpoint_cb
						-rpmsg_register_endpoint(rdev, ept) //注册普通端点

普通的消息,也会由MHU中断入口,进入到rpmsg_virtio_rx_callback, 只不过,此时,普通消息的端点已经在rpmsg_virtio_ns_callback中帮忙创建好了,所以,vq->callback(vq) 会调用到这里来:

rpmsg_virtio_rx_callback
	->ept->cb(ept, RPMSG_LOCATE_DATA(rp_hdr), rp_hdr->len, rp_hdr->src, ept->priv)
		-> endpoint_cb  //在rdev->ns_bind_cb 中赋值
			-> tfm_callback(data, len)  //在 tfm_to_openamp_init 中,会给tfm_callback赋值
				-> callback_from_openamp  // Process call from the other core
					-> register_msg_to_spe_and_verify(&priv, ns_msg, len)  //对消息进行检查
						-> check_msg(&s_map_entry->msg)  //进行更进一步的复杂检查
					-> deliver_msg_to_tfm_spe(priv)
						-> prepare_params_for_psa_call(&spm_params, s_map_entry)  
    // params中有一个 handle,它代表要调用哪个服务,对于 ctypto来说,是#define TFM_CRYPTO_HANDLE  (0x40000100U)
						->fm_rpc_psa_call(&spm_params)
							-> tfm_spm_client_psa_call(params->handle, PARAM_PACK(params->type, params->in_len, params->out_len), params->in_vec, params->out_vec)
								-> tfm_spm_get_client_id(ns_caller)
								->index = GET_INDEX_FROM_STATIC_HANDLE(handle)
								-> service = GET_STATELESS_SERVICE(index)
								-> sid = service->p_ldinf->sid  //找到是哪种服务的ID,比如,PS, ITS, CRYPTO, ATTESTION
								-> spm_fill_message(conn_handle, service, handle, type, client_id, invecs, in_num, outvecs, out_num, outptr)
								-> backend_instance.messaging(service, conn_handle)
									-> ipc_messaging  //唤醒当前正在等待信号的secure partition,并且阻塞住当前线程,下一次调度时,将会进入正在等待信号的partition
										->p_owner = service->partition;   //得到要调用的服务对应的parttion
    										->signal = service->p_ldinf->signal
										->thrd_wake_up(&p_owner->waitobj, (p_owner->signals_asserted & p_owner->signals_waiting))  //唤醒正在等待当前要调用的这个服务对应的partition
											->thrd_set_state(p_sync_obj->owner, THRD_STATE_RUNNABLE);  //设置为running ,下次调度会进入这个partition,  该partition会处理对应的信号
        											->tfm_arch_set_context_ret_code(p_sync_obj->owner->p_context_ctrl, ret_val)

向远程发送消息时,如果要通知对端的其他核,则会调用到这里来:

rpmsg_virtio_send_offchannel_nocopy
-metal_io_block_write(io, metal_io_virt_to_offset(io, hdr), &rp_hdr, sizeof(rp_hdr))  //将要发送的数据 写入 SHM
-virtqueue_get_buffer_length(rvdev->svq, idx)
-rpmsg_virtio_enqueue_buffer(rvdev, hdr, buff_len, idx)
-》virtqueue_kick
		-vq_ring_notify(vq)
-》virtio_notify
-》tfm_notify
-》notify_request_from_openamp  //通过MHU通知对端
						->tfm_hal_notify_peer()
							->dev = &MHU1_SE_TO_HOST_DEV  //这里用到了 MHU DEV
							->mhu_v2_x_channel_send(dev, MHU1_SEH_NOTIFY_CH, MHU1_SEH_NOTIFY_VAL)  //给HOST发MHU消息
							->mhu_v2_x_reset_access_request(dev)

virtio_notify定义在这里:

static struct virtio_dispatch dispatch = {
    .get_status = virtio_get_status,
    .set_status = virtio_set_status,
    .get_features = virtio_get_features,
    .notify = virtio_notify,
};

几个重要的partitons

(1) Ns agent

"entry_point": "ns_agent_mailbox_entry",
ns_agent_mailbox_entry
->boot_ns_core();
->LOG_DBGFMT("Enabling non-secure core...\r\n");
    	->tfm_hal_boot_ns_cpu(tfm_hal_get_ns_VTOR());
    	->tfm_hal_wait_for_ns_cpu_ready()
->tfm_inter_core_comm_init();
   ->psa_irq_enable(MAILBOX_SIGNAL)
	->psa_wait(PSA_WAIT_ANY, PSA_BLOCK)  //等待信号到来
	->tfm_rpc_client_call_handler()

(2) Sp init

“entry_point”: “platform_sp_init”,
//流程如下:

platform_sp_init
	->tfm_plat_init_nv_counter()
	->psa_wait(PSA_WAIT_ANY, PSA_BLOCK)  //等待信号到来
	->platform_signal_handle(TFM_SP_PLATFORM_IOCTL_SIGNAL, platform_sp_ioctl_ipc)
		->platform_sp_ioctl_ipc
			->tfm_platform_hal_ioctl
				->corstone1000_fwu_host_ack()

(3) Fwu(firmware update)

“entry_point”: “tfm_fwu_init”,
//流程如下:

tfm_fwu_init
	->fwu_bootloader_init()
	->psa_wait(PSA_WAIT_ANY, PSA_BLOCK) //等待信号到来
	->fwu_signal_handle(TFM_FWU_INSTALL_SIGNAL, tfm_fwu_install_ipc)
		-> tfm_fwu_install_ipc
			->get_image_index(image_id, &image_index)
			->tfm_internal_fwu_install(image_id,  &dependency_id, &dependency_version)

(4) crypto

“entry_point”: “tfm_crypto_init”,
//流程如下:

tfm_crypto_init
	->tfm_crypto_module_init()
	->tfm_crypto_engine_init()
		-> mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf, TFM_CRYPTO_ENGINE_BUF_SIZE) //初始化crypto堆
		->psa_crypto_init()
			mbedtls_psa_random_init( &global_data.rng )
			mbedtls_psa_random_seed( &global_data.rng )
			psa_initialize_key_slots( )
			psa_driver_wrapper_init( )
	->tfm_crypto_ipc_handler()
		->psa_wait(PSA_WAIT_ANY, PSA_BLOCK) //等待信号到来
		->psa_get(TFM_CRYPTO_SIGNAL, &msg)
		->status = tfm_crypto_parse_msg(&msg, &iov, &srv_id);  //要调用的加解密函数的ID
                    	->status = tfm_crypto_call_srv(&msg, &iov, srv_id);  //调用到具体的加解密函数
                	->psa_reply(msg.handle, status);

Crypto的heap size定义如下:

set(CRYPTO_ENGINE_BUF_SIZE              0x4000      CACHE STRING    "Heap size for the crypto backend")

所有的加解密API定义在这个数组中:

static const tfm_crypto_us_t sfid_func_table[TFM_CRYPTO_SID_MAX] = {
#define X(api_name) api_name,
LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API
#undef X
};
#define LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API \
    X(tfm_crypto_get_key_attributes)          \
    X(tfm_crypto_reset_key_attributes)        \
    X(tfm_crypto_open_key)                    \
    X(tfm_crypto_close_key)                   \
    X(tfm_crypto_import_key)                  \
    X(tfm_crypto_destroy_key)                 \
    X(tfm_crypto_export_key)                  \
    X(tfm_crypto_export_public_key)           \
    X(tfm_crypto_purge_key)                   \
    X(tfm_crypto_copy_key)                    \
    X(tfm_crypto_hash_compute)                \
    X(tfm_crypto_hash_compare)                \
    X(tfm_crypto_hash_setup)                  \
    X(tfm_crypto_hash_update)                 \
    X(tfm_crypto_hash_finish)                 \
    X(tfm_crypto_hash_verify)                 \
    X(tfm_crypto_hash_abort)                  \
    X(tfm_crypto_hash_clone)                  \
    X(tfm_crypto_mac_compute)                 \
    X(tfm_crypto_mac_verify)                  \
    X(tfm_crypto_mac_sign_setup)              \
    X(tfm_crypto_mac_verify_setup)            \
    X(tfm_crypto_mac_update)                  \
    X(tfm_crypto_mac_sign_finish)             \
    X(tfm_crypto_mac_verify_finish)           \
    X(tfm_crypto_mac_abort)                   \
    X(tfm_crypto_cipher_encrypt)              \
    X(tfm_crypto_cipher_decrypt)              \
    X(tfm_crypto_cipher_encrypt_setup)        \
X(tfm_crypto_cipher_decrypt_setup)        \

tfm_crypto_hash_compute在哪里定义的呢?

tfm_crypto_hash_compute
	-psa_hash_compute(alg, input, input_length, hash, hash_size, &out_vec[0].len)

又根据如下定义,可知psa_hash_compute 等价于 mbedcrypto__psa_hash_compute

#define psa_hash_compute   PSA_FUNCTION_NAME(psa_hash_compute) 
#define PSA_FUNCTION_NAME(x) mbedcrypto__ ## x

mbedcrypto__psa_hash_compute()这个接口,又是在哪里定义的呢?
git/mbedtls/library/psa_crypto.c
psa_status_t psa_hash_compute() // psa_hash_compute 通过 宏转换,变成 mbedcrypto__psa_hash_compute,所以,真实的函数名是:mbedcrypto__psa_hash_compute

->psa_driver_wrapper_hash_compute( alg, input, input_length, hash, hash_size, hash_length ) );
	-> cc3xx_hash_compute(alg, input, input_length, hash, hash_size, hash_length)  //如果定义了CC312,将会调用到这里来
		->cc3xx_hash_setup(&operation, alg)
		->cc3xx_hash_update(&operation, input, input_length)
		->cc3xx_hash_finish(&operation, hash, hash_size, hash_length)
		->cc3xx_hash_abort(&operation)
	-> mbedtls_psa_hash_compute( alg, input, input_length, hash, hash_size, hash_length )
		->mbedtls_psa_hash_setup( &operation, alg )
			->mbedtls_sha256_init( &operation->ctx.sha256 )
		->mbedtls_psa_hash_update( &operation, input, input_length )   //根据选择的加密硬件类型,或者 纯软件加密,决定后面的调用流程
			->mbedtls_internal_sha256_process( ctx, ctx->buffer ) )  //mbedtls纯软件方式
			->mbedtls_sha_update_internal( ctx, input, ilen )  //用CC312硬件时
			->dubhe_sha256_update(ctx, input, ilen)             //用 ShanHai 硬件 时
		->mbedtls_psa_hash_finish( &operation, hash, hash_size, hash_length )
		->mbedtls_psa_hash_abort( &operation )

(5) ps

“entry_point”: “tfm_ps_req_mngr_init”,
//流程如下:

tfm_ps_req_mngr_init
	-> tfm_ps_init()  //ps FLASH相关的设置,已经在 its 的初始化过程中完成了
		-> ps_system_prepare()
	->psa_wait(PSA_WAIT_ANY, PSA_BLOCK) //等待信号到来
	->ps_signal_handle(TFM_PROTECTED_STORAGE_SERVICE_SIGNAL)

ps所在的flash地址,是在这里赋值的:

init_fs_cfg
tfm_hal_ps_fs_info
		->fs_info->flash_area_addr = TFM_HAL_PS_FLASH_AREA_ADDR;
->fs_info->flash_area_size = TFM_HAL_PS_FLASH_AREA_SIZE;
  	  ->fs_info->sectors_per_block = TFM_HAL_PS_SECTORS_PER_BLOCK;

(6) Proxy sp

“entry_point”: “psa_proxy_sp_init”,

(7) attest

“entry_point”: “attest_partition_init”,

7.7.8 its
“entry_point”: “tfm_its_req_mngr_init”,
//流程如下:

tfm_its_req_mngr_init
	->tfm_its_init()
		->init_fs_cfg()	
			->tfm_hal_its_fs_info(&its_fs_info)
				->fs_info->flash_area_addr = TFM_HAL_ITS_FLASH_AREA_ADDR     //(0x2000000 + 0x40000)
		->its_flash_fs_init_ctx(&fs_ctx_its, &fs_cfg_its, &ITS_FLASH_OPS)
		->its_flash_fs_prepare(&fs_ctx_its)
	->psa_wait(PSA_WAIT_ANY, PSA_BLOCK)     //等待信号到来
	->its_signal_handle(TFM_INTERNAL_TRUSTED_STORAGE_SERVICE_SIGNAL)
		->status = psa_get(signal, &msg)
		 ->case TFM_ITS_SET:   //设置 its
        status = tfm_its_set_ipc();
	psa_read(msg.handle, 0, &uid, sizeof(uid))
	tfm_its_set(msg.client_id, uid, data_length, create_flags)
		its_req_mngr_read(asset_data, write_size)
		its_flash_fs_file_write
        psa_reply(msg.handle, status);
        break;
    case TFM_ITS_GET:  //读取 its
        status = tfm_its_get_ipc();
        psa_reply(msg.handle, status);
        break;
    case TFM_ITS_GET_INFO:
        status = tfm_its_get_info_ipc();
        psa_reply(msg.handle, status);
        break;
    case TFM_ITS_REMOVE:
        status = tfm_its_remove_ipc();
        psa_reply(msg.handle, status);
  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值