1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) Foundries Ltd. 2020 - All Rights Reserved
4  * Author: Jorge Ramirez <jorge@foundries.io>
5  */
6 
7 #include <config.h>
8 #include <initcall.h>
9 #include <kernel/panic.h>
10 #include <se050.h>
11 
12 sss_se05x_key_store_t *se050_kstore;
13 sss_se05x_session_t *se050_session;
14 struct sss_se05x_ctx se050_ctx;
15 
se050_core_early_init(struct se050_scp_key * keys)16 TEE_Result se050_core_early_init(struct se050_scp_key *keys)
17 {
18 	sss_status_t status = kStatus_SSS_Success;
19 
20 	status = se050_session_open(&se050_ctx, keys);
21 	if (status != kStatus_SSS_Success)
22 		return TEE_ERROR_GENERIC;
23 
24 	if (IS_ENABLED(CFG_CORE_SE05X_INIT_NVM)) {
25 		status = se050_factory_reset(&se050_ctx.session.s_ctx);
26 		if (status != kStatus_SSS_Success)
27 			return TEE_ERROR_GENERIC;
28 	}
29 
30 	if (se050_ctx.session.subsystem == kType_SSS_SubSystem_NONE)
31 		return TEE_ERROR_GENERIC;
32 
33 	status = se050_key_store_and_object_init(&se050_ctx);
34 	if (status != kStatus_SSS_Success)
35 		return TEE_ERROR_GENERIC;
36 
37 	se050_session = (sss_se05x_session_t *)((void *)&se050_ctx.session);
38 	se050_kstore = (sss_se05x_key_store_t *)((void *)&se050_ctx.ks);
39 
40 	return TEE_SUCCESS;
41 }
42 
update_se_info(void)43 static TEE_Result update_se_info(void)
44 {
45 	sss_status_t status = kStatus_SSS_Success;
46 
47 	status = se050_get_se_info(se050_session,
48 				   IS_ENABLED(CFG_CORE_SE05X_DISPLAY_INFO));
49 
50 	/* the session must be closed after accessing the board information */
51 	sss_se05x_session_close(se050_session);
52 	se050_scp03_set_disable();
53 
54 	if (status != kStatus_SSS_Success)
55 		return TEE_ERROR_GENERIC;
56 
57 	if (IS_ENABLED(CFG_CORE_SCP03_ONLY))
58 		return TEE_SUCCESS;
59 
60 	return se050_core_early_init(NULL);
61 }
62 
enable_scp03(void)63 static TEE_Result enable_scp03(void)
64 {
65 	if (se050_enable_scp03(se050_session) != kStatus_SSS_Success)
66 		return TEE_ERROR_GENERIC;
67 
68 	return TEE_SUCCESS;
69 }
70 
se050_early_init_default(void)71 static TEE_Result se050_early_init_default(void)
72 {
73 	if (se050_core_early_init(NULL)) {
74 		EMSG("Failed to open the default session");
75 		panic();
76 	}
77 
78 	if (update_se_info()) {
79 		EMSG("Failed to read the secure element configuration");
80 		panic();
81 	}
82 
83 	if (IS_ENABLED(CFG_CORE_SE05X_SCP03_EARLY)) {
84 		if (enable_scp03()) {
85 			EMSG("Failed to open the SCP03 session");
86 			panic();
87 		}
88 	}
89 
90 	return TEE_SUCCESS;
91 }
92 
se050_early_init_scp03(void)93 static TEE_Result se050_early_init_scp03(void)
94 {
95 	/* Initialize session */
96 	se050_session = (sss_se05x_session_t *)((void *)&se050_ctx.session);
97 	se050_kstore = (sss_se05x_key_store_t *)((void *)&se050_ctx.ks);
98 
99 #ifdef CFG_CORE_SE05X_OEFID
100 	se050_ctx.se_info.oefid[0] = CFG_CORE_SE05X_OEFID >> 8;
101 	se050_ctx.se_info.oefid[1] = CFG_CORE_SE05X_OEFID & 0xff;
102 #endif
103 	if (enable_scp03()) {
104 		EMSG("Failed to enable SCP03 session");
105 		panic();
106 	}
107 
108 	if (update_se_info()) {
109 		EMSG("Failed to read the secure element configuration");
110 		panic();
111 	}
112 
113 	if (enable_scp03()) {
114 		EMSG("Failed to re-open the SCP03 session");
115 		panic();
116 	}
117 
118 	return TEE_SUCCESS;
119 }
120 
se050_session_init(void)121 static TEE_Result se050_session_init(void)
122 {
123 	if (IS_ENABLED(CFG_CORE_SCP03_ONLY))
124 		return se050_early_init_scp03();
125 
126 	return se050_early_init_default();
127 }
128 
129 driver_init(se050_session_init);
130