xref: /optee_os/core/drivers/crypto/se050/adaptors/apis/sss.c (revision 85bba90ddb851151c484a150e97b62db3b23b308)
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 <crypto/crypto.h>
9 #include <se050.h>
10 #include <se050_utils.h>
11 #include <string.h>
12 #include <string_ext.h>
13 
14 static const sss_policy_u asym_key = {
15 	.type = KPolicy_Asym_Key,
16 	.auth_obj_id = 0,
17 	.policy = {
18 		.asymmkey = {
19 			.can_Sign = 1,
20 			.can_Verify = 1,
21 			.can_Encrypt = 1,
22 			.can_Decrypt = 1,
23 			.can_KD = 1,
24 			.can_Wrap = 1,
25 			.can_Write = 1,
26 			.can_Gen = 1,
27 			.can_Import_Export = 1,
28 			.can_KA = 1,
29 			.can_Read = 1,
30 			.can_Attest = 1,
31 		}
32 	}
33 };
34 
35 static const sss_policy_u common = {
36 	.type = KPolicy_Common,
37 	.auth_obj_id = 0,
38 	.policy = {
39 		.common = {
40 			.can_Delete = 1,
41 			.can_Read = 1,
42 			.can_Write = 1,
43 			.req_Sm = 1,
44 		},
45 	},
46 };
47 
48 sss_policy_t se050_asym_policy = {
49 	.nPolicies = 2,
50 	.policies = { &asym_key, &common },
51 };
52 
se050_rotate_scp03_keys(struct sss_se05x_ctx * ctx)53 sss_status_t se050_rotate_scp03_keys(struct sss_se05x_ctx *ctx)
54 {
55 	struct s050_scp_rotate_cmd cmd = { };
56 	sss_status_t status = kStatus_SSS_Fail;
57 	struct se050_scp_key cur_keys = { };
58 	struct se050_scp_key new_keys = { };
59 	SE_Connect_Ctx_t *connect_ctx = NULL;
60 	sss_se05x_session_t *session = NULL;
61 
62 	if (!ctx)
63 		return kStatus_SSS_Fail;
64 
65 	if (IS_ENABLED(CFG_CORE_SE05X_SCP03_PROVISION_WITH_FACTORY_KEYS)) {
66 		/* Public */
67 		status = se050_scp03_get_keys(&new_keys, SCP03_OFID);
68 		if (status != kStatus_SSS_Success)
69 			return status;
70 	} else {
71 		/* Secret */
72 		status = se050_scp03_subkey_derive(&new_keys);
73 		if (status != kStatus_SSS_Success)
74 			return status;
75 	}
76 
77 	status = se050_scp03_get_current_keys(&cur_keys);
78 	if (status != kStatus_SSS_Success)
79 		return status;
80 
81 	if (IS_ENABLED(CFG_CORE_SE05X_DISPLAY_SCP03_KEYS)) {
82 		IMSG("scp03: current keys");
83 		nLog_au8("scp03", 0xff, "dek: ",
84 			 cur_keys.dek, SE050_SCP03_KEY_SZ);
85 		nLog_au8("scp03", 0xff, "mac: ",
86 			 cur_keys.mac, SE050_SCP03_KEY_SZ);
87 		nLog_au8("scp03", 0xff, "enc: ",
88 			 cur_keys.enc, SE050_SCP03_KEY_SZ);
89 		IMSG("scp03: proposed new keys");
90 		nLog_au8("scp03", 0xff, "dek: ",
91 			 new_keys.dek, SE050_SCP03_KEY_SZ);
92 		nLog_au8("scp03", 0xff, "mac: ",
93 			 new_keys.mac, SE050_SCP03_KEY_SZ);
94 		nLog_au8("scp03", 0xff, "enc: ",
95 			 new_keys.enc, SE050_SCP03_KEY_SZ);
96 	}
97 
98 	if (!consttime_memcmp(new_keys.enc, cur_keys.enc, SE050_SCP03_KEY_SZ) &&
99 	    !consttime_memcmp(new_keys.mac, cur_keys.mac, SE050_SCP03_KEY_SZ) &&
100 	    !consttime_memcmp(new_keys.dek, cur_keys.dek, SE050_SCP03_KEY_SZ))
101 		return kStatus_SSS_Success;
102 
103 	connect_ctx = &ctx->open_ctx;
104 	session = &ctx->session;
105 
106 	status = se050_scp03_prepare_rotate_cmd(ctx, &cmd, &new_keys);
107 	if (status != kStatus_SSS_Success)
108 		return status;
109 
110 	sss_se05x_refresh_session(se050_session, NULL);
111 	sss_se05x_session_close(session);
112 
113 	/* re-open session with same keys */
114 	connect_ctx->skip_select_applet = 1;
115 	status = sss_se05x_session_open(session, kType_SSS_SE_SE05x, 0,
116 					kSSS_ConnectionType_Encrypted,
117 					connect_ctx);
118 	if (status != kStatus_SSS_Success) {
119 		se050_scp03_set_disable();
120 		EMSG("scp03 re-open failed, session lost");
121 		return kStatus_SSS_Fail;
122 	}
123 
124 	status = se050_scp03_send_rotate_cmd(&session->s_ctx, &cmd);
125 	if (status != kStatus_SSS_Success) {
126 		EMSG("scp03 keys not updated");
127 		return kStatus_SSS_Fail;
128 	}
129 
130 	sss_host_session_close(&ctx->host_session);
131 	sss_se05x_session_close(se050_session);
132 	memset(ctx, 0, sizeof(*ctx));
133 
134 	/* open session with new keys */
135 	if (IS_ENABLED(CFG_CORE_SE05X_SCP03_PROVISION_WITH_FACTORY_KEYS))
136 		se050_scp03_set_enable(SCP03_OFID);
137 	else
138 		se050_scp03_set_enable(SCP03_DERIVED);
139 
140 	if (se050_core_early_init(&new_keys)) {
141 		se050_scp03_set_disable();
142 		EMSG("scp03 keys rejected, session lost");
143 		return kStatus_SSS_Fail;
144 	}
145 
146 	return kStatus_SSS_Success;
147 }
148 
se050_enable_scp03(sss_se05x_session_t * session)149 sss_status_t se050_enable_scp03(sss_se05x_session_t *session)
150 {
151 	struct se050_scp_key keys = { };
152 	sss_status_t status = kStatus_SSS_Success;
153 	enum se050_scp03_ksrc key_src[] = { SCP03_DERIVED, SCP03_CFG,
154 		SCP03_OFID };
155 	size_t i = 0;
156 
157 	if (se050_scp03_enabled())
158 		return kStatus_SSS_Success;
159 
160 	for (i = 0; i < ARRAY_SIZE(key_src); i++) {
161 		status = se050_scp03_get_keys(&keys, key_src[i]);
162 		if (status != kStatus_SSS_Success)
163 			continue;
164 
165 		if (session->subsystem)
166 			sss_se05x_session_close(session);
167 
168 		if (!se050_core_early_init(&keys)) {
169 			se050_scp03_set_enable(key_src[i]);
170 			goto out;
171 		}
172 
173 		sss_host_session_close(&se050_ctx.host_session);
174 	}
175 
176 	return kStatus_SSS_Fail;
177 out:
178 	if (IS_ENABLED(CFG_CORE_SE05X_SCP03_PROVISION_ON_INIT))
179 		return se050_rotate_scp03_keys(&se050_ctx);
180 
181 	return kStatus_SSS_Success;
182 }
183 
se050_session_open(struct sss_se05x_ctx * ctx,struct se050_scp_key * current_keys)184 sss_status_t se050_session_open(struct sss_se05x_ctx *ctx,
185 				struct se050_scp_key *current_keys)
186 {
187 	sss_status_t status = kStatus_SSS_Fail;
188 	SE_Connect_Ctx_t *connect_ctx = NULL;
189 	sss_se05x_session_t *session = NULL;
190 
191 	if (!ctx)
192 		return kStatus_SSS_Fail;
193 
194 	connect_ctx = &ctx->open_ctx;
195 	session = &ctx->session;
196 	connect_ctx->connType = kType_SE_Conn_Type_T1oI2C;
197 	connect_ctx->portName = NULL;
198 
199 	if (!current_keys) {
200 		return sss_se05x_session_open(session, kType_SSS_SE_SE05x, 0,
201 					      kSSS_ConnectionType_Plain,
202 					      connect_ctx);
203 	}
204 
205 	status = se050_configure_host(&ctx->host_session,
206 				      &ctx->host_ks,
207 				      &ctx->open_ctx,
208 				      &ctx->se05x_auth,
209 				      kSSS_AuthType_SCP03,
210 				      current_keys);
211 	if (status != kStatus_SSS_Success)
212 		return status;
213 
214 	return sss_se05x_session_open(session, kType_SSS_SE_SE05x, 0,
215 				      kSSS_ConnectionType_Encrypted,
216 				      connect_ctx);
217 }
218 
se050_key_store_and_object_init(struct sss_se05x_ctx * ctx)219 sss_status_t se050_key_store_and_object_init(struct sss_se05x_ctx *ctx)
220 {
221 	if (!ctx)
222 		return kStatus_SSS_Fail;
223 
224 	return sss_se05x_key_store_context_init(&ctx->ks, &ctx->session);
225 }
226