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 <nxScp03_Apis.h>
8 #include <se050_user_apis.h>
9 #include <se050_utils.h>
10 #include <string.h>
11 
alloc_scp_key_to_auth(sss_object_t * k_object,sss_key_store_t * k_store,uint32_t key_id)12 static sss_status_t alloc_scp_key_to_auth(sss_object_t *k_object,
13 					  sss_key_store_t *k_store,
14 					  uint32_t key_id)
15 {
16 	sss_status_t status = kStatus_SSS_Fail;
17 
18 	if (!k_object || !k_store)
19 		return kStatus_SSS_Fail;
20 
21 	status = sss_host_key_object_init(k_object, k_store);
22 	if (status != kStatus_SSS_Success)
23 		return status;
24 
25 	return sss_host_key_object_allocate_handle(k_object, key_id,
26 						   kSSS_KeyPart_Default,
27 						   kSSS_CipherType_AES, 16,
28 						   kKeyObject_Mode_Transient);
29 }
30 
prepare_host_scp(NXSCP03_AuthCtx_t * scp,struct se050_auth_ctx * auth,sss_key_store_t * k_store,struct se050_scp_key * keys,uint32_t oid)31 static sss_status_t prepare_host_scp(NXSCP03_AuthCtx_t *scp,
32 				     struct se050_auth_ctx *auth,
33 				     sss_key_store_t *k_store,
34 				     struct se050_scp_key *keys,
35 				     uint32_t oid)
36 {
37 	sss_status_t status = kStatus_SSS_Fail;
38 	NXSCP03_StaticCtx_t *pStatic_ctx = NULL;
39 	NXSCP03_DynCtx_t *pDyn_ctx = NULL;
40 	size_t len = 0;
41 
42 	if (!scp || !auth || !k_store)
43 		return kStatus_SSS_Fail;
44 
45 	pStatic_ctx = &auth->static_ctx;
46 	pDyn_ctx = &auth->dynamic_ctx;
47 
48 	scp->pStatic_ctx = pStatic_ctx;
49 	scp->pDyn_ctx = pDyn_ctx;
50 	pStatic_ctx->keyVerNo = 0x0B;
51 
52 	status = alloc_scp_key_to_auth(&pStatic_ctx->Enc, k_store, oid++);
53 	if (status != kStatus_SSS_Success)
54 		return status;
55 
56 	len = sizeof(keys->enc);
57 	status = sss_host_key_store_set_key(k_store, &pStatic_ctx->Enc,
58 					    keys->enc, len, len * 8, NULL, 0);
59 	if (status != kStatus_SSS_Success)
60 		return status;
61 
62 	status = alloc_scp_key_to_auth(&pStatic_ctx->Mac, k_store, oid++);
63 	if (status != kStatus_SSS_Success)
64 		return status;
65 
66 	len = sizeof(keys->mac);
67 	status = sss_host_key_store_set_key(k_store, &pStatic_ctx->Mac,
68 					    keys->mac, len, len * 8, NULL, 0);
69 	if (status != kStatus_SSS_Success)
70 		return status;
71 
72 	status = alloc_scp_key_to_auth(&pStatic_ctx->Dek, k_store, oid++);
73 	if (status != kStatus_SSS_Success)
74 		return status;
75 
76 	len = sizeof(keys->dek);
77 	status = sss_host_key_store_set_key(k_store, &pStatic_ctx->Dek,
78 					    keys->dek, len, len * 8, NULL, 0);
79 	if (status != kStatus_SSS_Success)
80 		return status;
81 
82 	status = alloc_scp_key_to_auth(&pDyn_ctx->Enc, k_store, oid++);
83 	if (status != kStatus_SSS_Success)
84 		return status;
85 
86 	status = alloc_scp_key_to_auth(&pDyn_ctx->Mac, k_store, oid++);
87 	if (status != kStatus_SSS_Success)
88 		return status;
89 
90 	return alloc_scp_key_to_auth(&pDyn_ctx->Rmac, k_store, oid++);
91 }
92 
se050_configure_host(sss_user_impl_session_t * host_session,sss_key_store_t * host_ks,SE_Connect_Ctx_t * open_ctx,struct se050_auth_ctx * auth,SE_AuthType_t auth_type,struct se050_scp_key * keys)93 sss_status_t se050_configure_host(sss_user_impl_session_t *host_session,
94 				  sss_key_store_t *host_ks,
95 				  SE_Connect_Ctx_t *open_ctx,
96 				  struct se050_auth_ctx *auth,
97 				  SE_AuthType_t auth_type,
98 				  struct se050_scp_key *keys)
99 {
100 	sss_status_t status = kStatus_SSS_Fail;
101 	uint32_t host_oid = 0;
102 
103 	if (!host_session || !host_ks || !open_ctx || !auth)
104 		return kStatus_SSS_Fail;
105 
106 	if (host_session->subsystem != kType_SSS_SubSystem_NONE)
107 		goto prepare;
108 
109 	status = sss_host_session_open(host_session, kType_SSS_Software, 0,
110 				       kSSS_ConnectionType_Plain, NULL);
111 	if (status != kStatus_SSS_Success)
112 		return status;
113 
114 	status = sss_host_key_store_context_init(host_ks, host_session);
115 	if (status != kStatus_SSS_Success)
116 		goto error;
117 
118 	status = sss_host_key_store_allocate(host_ks, host_oid++);
119 	if (status != kStatus_SSS_Success)
120 		goto error;
121 prepare:
122 	status = prepare_host_scp(&open_ctx->auth.ctx.scp03, auth, host_ks,
123 				  keys, host_oid);
124 	if (status != kStatus_SSS_Success)
125 		goto error;
126 
127 	open_ctx->auth.authType = auth_type;
128 	return status;
129 
130 error:
131 	sss_host_session_close(host_session);
132 	return status;
133 }
134 
se050_host_key_store_get_key(sss_key_store_t * ks __unused,sss_object_t * ko,uint8_t * data,size_t * byte_len,size_t * bit_len)135 TEE_Result se050_host_key_store_get_key(sss_key_store_t *ks __unused,
136 					sss_object_t *ko, uint8_t *data,
137 					size_t *byte_len, size_t *bit_len)
138 {
139 	sss_user_impl_object_t *key_object = (sss_user_impl_object_t *)ko;
140 
141 	if (!ko)
142 		return TEE_ERROR_GENERIC;
143 
144 	if (*byte_len < sizeof(key_object->key))
145 		return TEE_ERROR_EXCESS_DATA;
146 
147 	memcpy(data, key_object->key, sizeof(key_object->key));
148 	*byte_len = sizeof(key_object->key);
149 	*bit_len = 8 * sizeof(key_object->key);
150 
151 	return TEE_SUCCESS;
152 }
153