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 #include <assert.h>
7 #include <bitstring.h>
8 #include <config.h>
9 #include <crypto/crypto.h>
10 #include <kernel/huk_subkey.h>
11 #include <kernel/mutex.h>
12 #include <kernel/refcount.h>
13 #include <kernel/tee_common_otp.h>
14 #include <kernel/thread.h>
15 #include <mm/mobj.h>
16 #include <optee_rpc_cmd.h>
17 #include <se050.h>
18 #include <se050_utils.h>
19 #include <scp.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <tee_api_defines_extensions.h>
24 #include <tee/tee_cryp_utl.h>
25 #include <utee_defines.h>
26
27 static enum se050_scp03_ksrc scp03_ksrc;
28 static bool scp03_enabled;
29
30 #define SE050A1_ID 0xA204
31 #define SE050A2_ID 0xA205
32 #define SE050B1_ID 0xA202
33 #define SE050B2_ID 0xA203
34 #define SE050C1_ID 0xA200
35 #define SE050C2_ID 0xA201
36 #define SE050DV_ID 0xA1F4
37 #define SE051A2_ID 0xA565
38 #define SE051C2_ID 0xA564
39
40 #define SE050A1 0
41 #define SE050A2 1
42 #define SE050B1 2
43 #define SE050B2 3
44 #define SE050C1 4
45 #define SE050C2 5
46 #define SE050DV 6
47 #define SE051A2 7
48 #define SE051C2 8
49
50 static const struct se050_scp_key se050_default_keys[] = {
51 [SE050A1] = {
52 .enc = { 0x34, 0xae, 0x09, 0x67, 0xe3, 0x29, 0xe9, 0x51,
53 0x8e, 0x72, 0x65, 0xd5, 0xad, 0xcc, 0x01, 0xc2 },
54 .mac = { 0x52, 0xb2, 0x53, 0xca, 0xdf, 0x47, 0x2b, 0xdb,
55 0x3d, 0x0f, 0xb3, 0x8e, 0x09, 0x77, 0x00, 0x99 },
56 .dek = { 0xac, 0xc9, 0x14, 0x31, 0xfe, 0x26, 0x81, 0x1b,
57 0x5e, 0xcb, 0xc8, 0x45, 0x62, 0x0d, 0x83, 0x44 },
58 },
59 [SE050A2] = {
60 .enc = { 0x46, 0xa9, 0xc4, 0x8c, 0x34, 0xef, 0xe3, 0x44,
61 0xa5, 0x22, 0xe6, 0x67, 0x44, 0xf8, 0x99, 0x6a },
62 .mac = { 0x12, 0x03, 0xff, 0x61, 0xdf, 0xbc, 0x9c, 0x86,
63 0x19, 0x6a, 0x22, 0x74, 0xae, 0xf4, 0xed, 0x28 },
64 .dek = { 0xf7, 0x56, 0x1c, 0x6f, 0x48, 0x33, 0x61, 0x19,
65 0xee, 0x39, 0x43, 0x9a, 0xab, 0x34, 0x09, 0x8e },
66 },
67 [SE050B1] = {
68 .enc = { 0xd4, 0x99, 0xbc, 0x90, 0xde, 0xa5, 0x42, 0xcf,
69 0x78, 0xd2, 0x5e, 0x13, 0xd6, 0x4c, 0xbb, 0x1f },
70 .mac = { 0x08, 0x15, 0x55, 0x96, 0x43, 0xfb, 0x79, 0xeb,
71 0x85, 0x01, 0xa0, 0xdc, 0x83, 0x3d, 0x90, 0x1f },
72 .dek = { 0xbe, 0x7d, 0xdf, 0xb4, 0x06, 0xe8, 0x1a, 0xe4,
73 0xe9, 0x66, 0x5a, 0x9f, 0xed, 0x64, 0x26, 0x7c },
74 },
75 [SE050B2] = {
76 .enc = { 0x5f, 0xa4, 0x3d, 0x82, 0x02, 0xd2, 0x5e, 0x9a,
77 0x85, 0xb1, 0xfe, 0x7e, 0x2d, 0x26, 0x47, 0x8d },
78 .mac = { 0x10, 0x5c, 0xea, 0x22, 0x19, 0xf5, 0x2b, 0xd1,
79 0x67, 0xa0, 0x74, 0x63, 0xc6, 0x93, 0x79, 0xc3 },
80 .dek = { 0xd7, 0x02, 0x81, 0x57, 0xf2, 0xad, 0x37, 0x2c,
81 0x74, 0xbe, 0x96, 0x9b, 0xcc, 0x39, 0x06, 0x27 },
82 },
83 [SE050C1] = {
84 .enc = { 0x85, 0x2b, 0x59, 0x62, 0xe9, 0xcc, 0xe5, 0xd0,
85 0xbe, 0x74, 0x6b, 0x83, 0x3b, 0xcc, 0x62, 0x87 },
86 .mac = { 0xdb, 0x0a, 0xa3, 0x19, 0xa4, 0x08, 0x69, 0x6c,
87 0x8e, 0x10, 0x7a, 0xb4, 0xe3, 0xc2, 0x6b, 0x47 },
88 .dek = { 0x4c, 0x2f, 0x75, 0xc6, 0xa2, 0x78, 0xa4, 0xae,
89 0xe5, 0xc9, 0xaf, 0x7c, 0x50, 0xee, 0xa8, 0x0c },
90 },
91 [SE050C2] = {
92 .enc = { 0xbd, 0x1d, 0xe2, 0x0a, 0x81, 0xea, 0xb2, 0xbf,
93 0x3b, 0x70, 0x9a, 0x9d, 0x69, 0xa3, 0x12, 0x54 },
94 .mac = { 0x9a, 0x76, 0x1b, 0x8d, 0xba, 0x6b, 0xed, 0xf2,
95 0x27, 0x41, 0xe4, 0x5d, 0x8d, 0x42, 0x36, 0xf5 },
96 .dek = { 0x9b, 0x99, 0x3b, 0x60, 0x0f, 0x1c, 0x64, 0xf5,
97 0xad, 0xc0, 0x63, 0x19, 0x2a, 0x96, 0xc9, 0x47 },
98 },
99 [SE050DV] = {
100 .enc = { 0x35, 0xc2, 0x56, 0x45, 0x89, 0x58, 0xa3, 0x4f,
101 0x61, 0x36, 0x15, 0x5f, 0x82, 0x09, 0xd6, 0xcd },
102 .mac = { 0xaf, 0x17, 0x7d, 0x5d, 0xbd, 0xf7, 0xc0, 0xd5,
103 0xc1, 0x0a, 0x05, 0xb9, 0xf1, 0x60, 0x7f, 0x78 },
104 .dek = { 0xa1, 0xbc, 0x84, 0x38, 0xbf, 0x77, 0x93, 0x5b,
105 0x36, 0x1a, 0x44, 0x25, 0xfe, 0x79, 0xfa, 0x29 },
106 },
107 [SE051A2] = {
108 .enc = { 0x84, 0x0a, 0x5d, 0x51, 0x79, 0x55, 0x11, 0xc9,
109 0xce, 0xf0, 0xc9, 0x6f, 0xd2, 0xcb, 0xf0, 0x41 },
110 .mac = { 0x64, 0x6b, 0xc2, 0xb8, 0xc3, 0xa4, 0xd9, 0xc1,
111 0xfa, 0x8d, 0x71, 0x16, 0xbe, 0x04, 0xfd, 0xfe },
112 .dek = { 0x03, 0xe6, 0x69, 0x9a, 0xca, 0x94, 0x26, 0xd9,
113 0xc3, 0x89, 0x22, 0xf8, 0x91, 0x4c, 0xe5, 0xf7 },
114 },
115 [SE051C2] = {
116 .enc = { 0x88, 0xdb, 0xcd, 0x65, 0x82, 0x0d, 0x2a, 0xa0,
117 0x6f, 0xfa, 0xb9, 0x2a, 0xa8, 0xe7, 0x93, 0x64 },
118 .mac = { 0xa8, 0x64, 0x4e, 0x2a, 0x04, 0xd9, 0xe9, 0xc8,
119 0xc0, 0xea, 0x60, 0x86, 0x68, 0x29, 0x99, 0xe5 },
120 .dek = { 0x8a, 0x38, 0x72, 0x38, 0x99, 0x88, 0x18, 0x44,
121 0xe2, 0xc1, 0x51, 0x3d, 0xac, 0xd9, 0xf8, 0x0d },
122 },
123 };
124
get_id_from_ofid(uint32_t ofid,uint32_t * id)125 static sss_status_t get_id_from_ofid(uint32_t ofid, uint32_t *id)
126 {
127 switch (ofid) {
128 case SE050A1_ID:
129 *id = SE050A1;
130 break;
131 case SE050A2_ID:
132 *id = SE050A2;
133 break;
134 case SE050B1_ID:
135 *id = SE050B1;
136 break;
137 case SE050B2_ID:
138 *id = SE050B2;
139 break;
140 case SE050C1_ID:
141 *id = SE050C1;
142 break;
143 case SE050C2_ID:
144 *id = SE050C2;
145 break;
146 case SE050DV_ID:
147 *id = SE050DV;
148 break;
149 case SE051A2_ID:
150 *id = SE051A2;
151 break;
152 case SE051C2_ID:
153 *id = SE051C2;
154 break;
155 default:
156 return kStatus_SSS_Fail;
157 }
158
159 return kStatus_SSS_Success;
160 }
161
encrypt_key_and_get_kcv(uint8_t * enc,uint8_t * kc,uint8_t * key,struct sss_se05x_ctx * ctx,uint32_t id)162 static sss_status_t encrypt_key_and_get_kcv(uint8_t *enc, uint8_t *kc,
163 uint8_t *key,
164 struct sss_se05x_ctx *ctx,
165 uint32_t id)
166 {
167 static const uint8_t ones[] = { [0 ... AES_KEY_LEN_nBYTE - 1] = 1 };
168 uint8_t enc_len = AES_KEY_LEN_nBYTE;
169 uint8_t kc_len = AES_KEY_LEN_nBYTE;
170 sss_status_t st = kStatus_SSS_Fail;
171 sss_object_t *dek_object = NULL;
172 sss_se05x_symmetric_t symm = { };
173 sss_se05x_object_t ko = { };
174 uint8_t dek[AES_KEY_LEN_nBYTE] = { 0 };
175 size_t dek_len = sizeof(dek);
176 size_t dek_bit_len = dek_len * 8;
177
178 st = sss_se05x_key_object_init(&ko, &ctx->ks);
179 if (st != kStatus_SSS_Success)
180 return kStatus_SSS_Fail;
181
182 st = sss_se05x_key_object_allocate_handle(&ko, id,
183 kSSS_KeyPart_Default,
184 kSSS_CipherType_AES,
185 AES_KEY_LEN_nBYTE,
186 kKeyObject_Mode_Transient);
187 if (st != kStatus_SSS_Success)
188 return kStatus_SSS_Fail;
189
190 st = sss_se05x_key_store_set_key(&ctx->ks, &ko, key, AES_KEY_LEN_nBYTE,
191 AES_KEY_LEN_nBYTE * 8, NULL, 0);
192 if (st != kStatus_SSS_Success)
193 goto out;
194
195 st = sss_se05x_symmetric_context_init(&symm, &ctx->session, &ko,
196 kAlgorithm_SSS_AES_ECB,
197 kMode_SSS_Encrypt);
198 if (st != kStatus_SSS_Success)
199 goto out;
200
201 st = sss_se05x_cipher_one_go(&symm, NULL, 0, ones, kc, kc_len);
202 if (st != kStatus_SSS_Success)
203 goto out;
204
205 dek_object = &ctx->open_ctx.auth.ctx.scp03.pStatic_ctx->Dek;
206 if (se050_host_key_store_get_key(&ctx->host_ks, dek_object,
207 dek, &dek_len, &dek_bit_len))
208 goto out;
209
210 st = sss_se05x_key_store_set_key(&ctx->ks, &ko, dek, AES_KEY_LEN_nBYTE,
211 AES_KEY_LEN_nBYTE * 8, NULL, 0);
212 if (st != kStatus_SSS_Success)
213 goto out;
214
215 st = sss_se05x_cipher_one_go(&symm, NULL, 0, key, enc, enc_len);
216 out:
217 if (symm.keyObject)
218 sss_se05x_symmetric_context_free(&symm);
219
220 sss_se05x_key_object_free(&ko);
221
222 Se05x_API_DeleteSecureObject(&ctx->session.s_ctx, id);
223
224 return st;
225 }
226
prepare_key_data(uint8_t * key,uint8_t * cmd,struct sss_se05x_ctx * ctx,uint32_t id)227 static sss_status_t prepare_key_data(uint8_t *key, uint8_t *cmd,
228 struct sss_se05x_ctx *ctx, uint32_t id)
229 {
230 uint8_t kc[AES_KEY_LEN_nBYTE] = { 0 };
231 sss_status_t status = kStatus_SSS_Fail;
232
233 cmd[0] = PUT_KEYS_KEY_TYPE_CODING_AES;
234 cmd[1] = AES_KEY_LEN_nBYTE + 1;
235 cmd[2] = AES_KEY_LEN_nBYTE;
236 cmd[3 + AES_KEY_LEN_nBYTE] = CRYPTO_KEY_CHECK_LEN;
237
238 status = encrypt_key_and_get_kcv(&cmd[3], kc, key, ctx, id);
239 if (status != kStatus_SSS_Success)
240 return status;
241
242 memcpy(&cmd[3 + AES_KEY_LEN_nBYTE + 1], kc, CRYPTO_KEY_CHECK_LEN);
243
244 return kStatus_SSS_Success;
245 }
246
se050_scp03_prepare_rotate_cmd(struct sss_se05x_ctx * ctx,struct s050_scp_rotate_cmd * cmd,struct se050_scp_key * keys)247 sss_status_t se050_scp03_prepare_rotate_cmd(struct sss_se05x_ctx *ctx,
248 struct s050_scp_rotate_cmd *cmd,
249 struct se050_scp_key *keys)
250
251 {
252 sss_status_t status = kStatus_SSS_Fail;
253 size_t kcv_len = 0;
254 size_t cmd_len = 0;
255 uint8_t key_version = 0;
256 uint8_t *key[] = {
257 [0] = keys->enc,
258 [1] = keys->mac,
259 [2] = keys->dek,
260 };
261 uint32_t oid = 0;
262 size_t i = 0;
263
264 key_version = ctx->open_ctx.auth.ctx.scp03.pStatic_ctx->keyVerNo;
265 cmd->cmd[cmd_len] = key_version;
266 cmd_len += 1;
267
268 cmd->kcv[kcv_len] = key_version;
269 kcv_len += 1;
270
271 for (i = 0; i < ARRAY_SIZE(key); i++) {
272 status = se050_get_oid(&oid);
273 if (status != kStatus_SSS_Success)
274 return kStatus_SSS_Fail;
275
276 status = prepare_key_data(key[i], &cmd->cmd[cmd_len], ctx, oid);
277 if (status != kStatus_SSS_Success)
278 return kStatus_SSS_Fail;
279
280 memcpy(&cmd->kcv[kcv_len],
281 &cmd->cmd[cmd_len + 3 + AES_KEY_LEN_nBYTE + 1],
282 CRYPTO_KEY_CHECK_LEN);
283
284 cmd_len += 3 + AES_KEY_LEN_nBYTE + 1 + CRYPTO_KEY_CHECK_LEN;
285 kcv_len += CRYPTO_KEY_CHECK_LEN;
286 }
287
288 cmd->cmd_len = cmd_len;
289 cmd->kcv_len = kcv_len;
290
291 return kStatus_SSS_Success;
292 }
293
get_ofid_key(struct se050_scp_key * keys)294 static sss_status_t get_ofid_key(struct se050_scp_key *keys)
295 {
296 uint32_t oefid = SHIFT_U32(se050_ctx.se_info.oefid[0], 8) |
297 SHIFT_U32(se050_ctx.se_info.oefid[1], 0);
298 sss_status_t status = kStatus_SSS_Success;
299 uint32_t id = 0;
300
301 status = get_id_from_ofid(oefid, &id);
302 if (status != kStatus_SSS_Success)
303 return status;
304
305 memcpy(keys, &se050_default_keys[id], sizeof(*keys));
306 return kStatus_SSS_Success;
307 }
308
get_config_key(struct se050_scp_key * keys __maybe_unused)309 static sss_status_t get_config_key(struct se050_scp_key *keys __maybe_unused)
310 {
311 #ifdef CFG_CORE_SE05X_SCP03_CURRENT_DEK
312 struct se050_scp_key current_keys = {
313 .dek = { CFG_CORE_SE05X_SCP03_CURRENT_DEK },
314 .mac = { CFG_CORE_SE05X_SCP03_CURRENT_MAC },
315 .enc = { CFG_CORE_SE05X_SCP03_CURRENT_ENC },
316 };
317
318 memcpy(keys, ¤t_keys, sizeof(*keys));
319 return kStatus_SSS_Success;
320 #else
321 return kStatus_SSS_Fail;
322 #endif
323 }
324
se050_scp03_subkey_derive(struct se050_scp_key * keys)325 sss_status_t se050_scp03_subkey_derive(struct se050_scp_key *keys)
326 {
327 struct {
328 const char *name;
329 uint8_t *data;
330 } key[3] = {
331 [0] = { .name = "dek", .data = keys->dek },
332 [1] = { .name = "mac", .data = keys->mac },
333 [2] = { .name = "enc", .data = keys->enc },
334 };
335 uint8_t msg[SE050_SCP03_KEY_SZ + 3] = { 0 };
336 size_t i = 0;
337
338 if (tee_otp_get_die_id(msg + 3, SE050_SCP03_KEY_SZ))
339 return kStatus_SSS_Fail;
340
341 for (i = 0; i < ARRAY_SIZE(key); i++) {
342 memcpy(msg, key[i].name, 3);
343 if (huk_subkey_derive(HUK_SUBKEY_SE050, msg, sizeof(msg),
344 key[i].data, SE050_SCP03_KEY_SZ))
345 return kStatus_SSS_Fail;
346 }
347
348 return kStatus_SSS_Success;
349 }
350
se050_scp03_enabled(void)351 bool se050_scp03_enabled(void)
352 {
353 return scp03_enabled;
354 }
355
se050_scp03_set_enable(enum se050_scp03_ksrc ksrc)356 void se050_scp03_set_enable(enum se050_scp03_ksrc ksrc)
357 {
358 scp03_enabled = true;
359 scp03_ksrc = ksrc;
360 }
361
se050_scp03_set_disable(void)362 void se050_scp03_set_disable(void)
363 {
364 scp03_enabled = false;
365 }
366
se050_scp03_get_keys(struct se050_scp_key * keys,enum se050_scp03_ksrc ksrc)367 sss_status_t se050_scp03_get_keys(struct se050_scp_key *keys,
368 enum se050_scp03_ksrc ksrc)
369 {
370 switch (ksrc) {
371 case SCP03_CFG:
372 return get_config_key(keys);
373 case SCP03_DERIVED:
374 return se050_scp03_subkey_derive(keys);
375 case SCP03_OFID:
376 return get_ofid_key(keys);
377 default:
378 return kStatus_SSS_Fail;
379 }
380 }
381
se050_scp03_get_current_keys(struct se050_scp_key * keys)382 sss_status_t se050_scp03_get_current_keys(struct se050_scp_key *keys)
383 {
384 if (se050_scp03_enabled())
385 return se050_scp03_get_keys(keys, scp03_ksrc);
386
387 return kStatus_SSS_Fail;
388 }
389