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