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 <adaptors.h>
8 #include <fsl_sss_api.h>
9 #include <scp.h>
10 #include <se050_apdu_apis.h>
11 #include <string.h>
12 
se050_factory_reset(pSe05xSession_t ctx)13 sss_status_t se050_factory_reset(pSe05xSession_t ctx)
14 {
15 	if (!ctx)
16 		return kStatus_SSS_Fail;
17 
18 	if (Se05x_API_DeleteAll_Iterative(ctx) == SM_OK)
19 		return kStatus_SSS_Success;
20 
21 	return kStatus_SSS_Fail;
22 }
23 
se050_key_exists(uint32_t key_id,pSe05xSession_t ctx)24 bool se050_key_exists(uint32_t key_id, pSe05xSession_t ctx)
25 {
26 	SE05x_Result_t inuse = kSE05x_Result_FAILURE;
27 	smStatus_t status = SM_OK;
28 
29 	if (!ctx)
30 		return false;
31 
32 	status = Se05x_API_CheckObjectExists(ctx, key_id, &inuse);
33 	if (status != SM_OK)
34 		return false;
35 
36 	if (inuse == kSE05x_Result_SUCCESS)
37 		return true;
38 
39 	return false;
40 }
41 
set_rsa_public(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,struct se050_rsa_keypub * keypub,size_t key_bit_len)42 static sss_status_t set_rsa_public(Se05xSession_t *s_ctx,
43 				   Se05xPolicy_t *policy,
44 				   sss_se05x_object_t *k_object,
45 				   struct se050_rsa_keypub *keypub,
46 				   size_t key_bit_len)
47 {
48 	SE05x_TransientType_t type = kSE05x_TransientType_Transient;
49 	SE05x_RSAKeyFormat_t rsa_format = kSE05x_RSAKeyFormat_RAW;
50 	smStatus_t status = SM_OK;
51 
52 	if (k_object->isPersistant)
53 		type = kSE05x_TransientType_Persistent;
54 
55 	switch (k_object->cipherType) {
56 	case kSSS_CipherType_RSA:
57 		rsa_format = kSE05x_RSAKeyFormat_RAW;
58 		break;
59 	case kSSS_CipherType_RSA_CRT:
60 		rsa_format = kSE05x_RSAKeyFormat_CRT;
61 		break;
62 	default:
63 		return kStatus_SSS_Fail;
64 	}
65 
66 	status = Se05x_API_WriteRSAKey(s_ctx, policy, k_object->keyId,
67 				       (U16)key_bit_len,
68 				       SE05X_RSA_NO_p,
69 				       SE05X_RSA_NO_q,
70 				       SE05X_RSA_NO_dp,
71 				       SE05X_RSA_NO_dq,
72 				       SE05X_RSA_NO_qInv,
73 				       keypub->e, keypub->e_len,
74 				       SE05X_RSA_NO_priv,
75 				       SE05X_RSA_NO_pubMod,
76 				       (SE05x_INS_t)type,
77 				       kSE05x_KeyPart_Public,
78 				       rsa_format);
79 	if (status != SM_OK)
80 		return kStatus_SSS_Fail;
81 
82 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
83 				       0,
84 				       SE05X_RSA_NO_p,
85 				       SE05X_RSA_NO_q,
86 				       SE05X_RSA_NO_dp,
87 				       SE05X_RSA_NO_dq,
88 				       SE05X_RSA_NO_qInv,
89 				       SE05X_RSA_NO_pubExp,
90 				       SE05X_RSA_NO_priv,
91 				       keypub->n, keypub->n_len,
92 				       (SE05x_INS_t)type,
93 				       kSE05x_KeyPart_NA,
94 				       rsa_format);
95 	if (status != SM_OK)
96 		return kStatus_SSS_Fail;
97 
98 	return kStatus_SSS_Success;
99 }
100 
set_rsa_private_rsa(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,struct se050_rsa_keypair * keypair,size_t key_bit_len)101 static sss_status_t set_rsa_private_rsa(Se05xSession_t *s_ctx,
102 					Se05xPolicy_t *policy,
103 					sss_se05x_object_t *k_object,
104 					struct se050_rsa_keypair *keypair,
105 					size_t key_bit_len)
106 {
107 	SE05x_TransientType_t type = kSE05x_TransientType_Transient;
108 	smStatus_t status = SM_OK;
109 
110 	if (k_object->isPersistant)
111 		type = kSE05x_TransientType_Persistent;
112 
113 	status = Se05x_API_WriteRSAKey(s_ctx, policy, k_object->keyId,
114 				       (U16)key_bit_len,
115 				       SE05X_RSA_NO_p,
116 				       SE05X_RSA_NO_q,
117 				       SE05X_RSA_NO_dp,
118 				       SE05X_RSA_NO_dq,
119 				       SE05X_RSA_NO_qInv,
120 				       SE05X_RSA_NO_pubExp,
121 				       keypair->d, keypair->d_len,
122 				       SE05X_RSA_NO_pubMod,
123 				       (SE05x_INS_t)type,
124 				       kSE05x_KeyPart_Pair,
125 				       kSE05x_RSAKeyFormat_RAW);
126 	if (status != SM_OK)
127 		return kStatus_SSS_Fail;
128 
129 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
130 				       0,
131 				       SE05X_RSA_NO_p,
132 				       SE05X_RSA_NO_q,
133 				       SE05X_RSA_NO_dp,
134 				       SE05X_RSA_NO_dq,
135 				       SE05X_RSA_NO_qInv,
136 				       SE05X_RSA_NO_pubExp,
137 				       SE05X_RSA_NO_priv,
138 				       keypair->n, keypair->n_len,
139 				       (SE05x_INS_t)type,
140 				       kSE05x_KeyPart_NA,
141 				       kSE05x_RSAKeyFormat_RAW);
142 	if (status != SM_OK)
143 		return kStatus_SSS_Fail;
144 
145 	return kStatus_SSS_Success;
146 }
147 
set_rsa_private_rsa_crt(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,struct se050_rsa_keypair * keypair,size_t key_bit_len)148 static sss_status_t set_rsa_private_rsa_crt(Se05xSession_t *s_ctx,
149 					    Se05xPolicy_t *policy,
150 					    sss_se05x_object_t *k_object,
151 					    struct se050_rsa_keypair *keypair,
152 					    size_t key_bit_len)
153 {
154 	SE05x_TransientType_t type = kSE05x_TransientType_Transient;
155 	smStatus_t status = SM_OK;
156 
157 	if (k_object->isPersistant)
158 		type = kSE05x_TransientType_Persistent;
159 
160 	status = Se05x_API_WriteRSAKey(s_ctx, policy, k_object->keyId,
161 				       (U16)key_bit_len,
162 				       keypair->p,
163 				       keypair->p_len,
164 				       SE05X_RSA_NO_q,
165 				       SE05X_RSA_NO_dp,
166 				       SE05X_RSA_NO_dq,
167 				       SE05X_RSA_NO_qInv,
168 				       SE05X_RSA_NO_pubExp,
169 				       SE05X_RSA_NO_priv,
170 				       SE05X_RSA_NO_pubMod,
171 				       (SE05x_INS_t)type,
172 				       kSE05x_KeyPart_Private,
173 				       kSE05x_RSAKeyFormat_CRT);
174 	if (status != SM_OK)
175 		return kStatus_SSS_Fail;
176 
177 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
178 				       0,
179 				       SE05X_RSA_NO_p,
180 				       keypair->q,
181 				       keypair->q_len,
182 				       SE05X_RSA_NO_dp,
183 				       SE05X_RSA_NO_dq,
184 				       SE05X_RSA_NO_qInv,
185 				       SE05X_RSA_NO_pubExp,
186 				       SE05X_RSA_NO_priv,
187 				       SE05X_RSA_NO_pubMod,
188 				       (SE05x_INS_t)type,
189 				       kSE05x_KeyPart_NA,
190 				       kSE05x_RSAKeyFormat_CRT);
191 	if (status != SM_OK)
192 		return kStatus_SSS_Fail;
193 
194 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
195 				       0,
196 				       SE05X_RSA_NO_p,
197 				       SE05X_RSA_NO_q,
198 				       keypair->dp,
199 				       keypair->dp_len,
200 				       SE05X_RSA_NO_dq,
201 				       SE05X_RSA_NO_qInv,
202 				       SE05X_RSA_NO_pubExp,
203 				       SE05X_RSA_NO_priv,
204 				       SE05X_RSA_NO_pubMod,
205 				       (SE05x_INS_t)type,
206 				       kSE05x_KeyPart_NA,
207 				       kSE05x_RSAKeyFormat_CRT);
208 	if (status != SM_OK)
209 		return kStatus_SSS_Fail;
210 
211 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
212 				       0,
213 				       SE05X_RSA_NO_p,
214 				       SE05X_RSA_NO_q,
215 				       SE05X_RSA_NO_dp,
216 				       keypair->dq,
217 				       keypair->dq_len,
218 				       SE05X_RSA_NO_qInv,
219 				       SE05X_RSA_NO_pubExp,
220 				       SE05X_RSA_NO_priv,
221 				       SE05X_RSA_NO_pubMod,
222 				       (SE05x_INS_t)type,
223 				       kSE05x_KeyPart_NA,
224 				       kSE05x_RSAKeyFormat_CRT);
225 	if (status != SM_OK)
226 		return kStatus_SSS_Fail;
227 
228 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
229 				       0,
230 				       SE05X_RSA_NO_p,
231 				       SE05X_RSA_NO_q,
232 				       SE05X_RSA_NO_dp,
233 				       SE05X_RSA_NO_dq,
234 				       keypair->qp,
235 				       keypair->qp_len,
236 				       SE05X_RSA_NO_pubExp,
237 				       SE05X_RSA_NO_priv,
238 				       SE05X_RSA_NO_pubMod,
239 				       (SE05x_INS_t)type,
240 				       kSE05x_KeyPart_NA,
241 				       kSE05x_RSAKeyFormat_CRT);
242 	if (status != SM_OK)
243 		return kStatus_SSS_Fail;
244 
245 	return kStatus_SSS_Success;
246 }
247 
set_rsa_keypair_rsa(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,struct se050_rsa_keypair * keypair,size_t key_bit_len)248 static sss_status_t set_rsa_keypair_rsa(Se05xSession_t *s_ctx,
249 					Se05xPolicy_t *policy,
250 					sss_se05x_object_t *k_object,
251 					struct se050_rsa_keypair *keypair,
252 					size_t key_bit_len)
253 {
254 	SE05x_TransientType_t type = kSE05x_TransientType_Transient;
255 	smStatus_t status = SM_OK;
256 
257 	if (k_object->isPersistant)
258 		type = kSE05x_TransientType_Persistent;
259 
260 	status = Se05x_API_WriteRSAKey(s_ctx, policy, k_object->keyId,
261 				       (U16)key_bit_len,
262 				       SE05X_RSA_NO_p,
263 				       SE05X_RSA_NO_q,
264 				       SE05X_RSA_NO_dp,
265 				       SE05X_RSA_NO_dq,
266 				       SE05X_RSA_NO_qInv,
267 				       keypair->e, keypair->e_len,
268 				       SE05X_RSA_NO_priv,
269 				       SE05X_RSA_NO_pubMod,
270 				       (SE05x_INS_t)type,
271 				       kSE05x_KeyPart_Pair,
272 				       kSE05x_RSAKeyFormat_RAW);
273 	if (status != SM_OK)
274 		return kStatus_SSS_Fail;
275 
276 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
277 				       0,
278 				       SE05X_RSA_NO_p,
279 				       SE05X_RSA_NO_q,
280 				       SE05X_RSA_NO_dp,
281 				       SE05X_RSA_NO_dq,
282 				       SE05X_RSA_NO_qInv,
283 				       SE05X_RSA_NO_pubExp,
284 				       keypair->d, keypair->d_len,
285 				       SE05X_RSA_NO_pubMod,
286 				       (SE05x_INS_t)type,
287 				       kSE05x_KeyPart_NA,
288 				       kSE05x_RSAKeyFormat_RAW);
289 	if (status != SM_OK)
290 		return kStatus_SSS_Fail;
291 
292 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
293 				       0,
294 				       SE05X_RSA_NO_p,
295 				       SE05X_RSA_NO_q,
296 				       SE05X_RSA_NO_dp,
297 				       SE05X_RSA_NO_dq,
298 				       SE05X_RSA_NO_qInv,
299 				       SE05X_RSA_NO_pubExp,
300 				       SE05X_RSA_NO_priv,
301 				       keypair->n, keypair->n_len,
302 				       (SE05x_INS_t)type,
303 				       kSE05x_KeyPart_NA,
304 				       kSE05x_RSAKeyFormat_RAW);
305 	if (status != SM_OK)
306 		return kStatus_SSS_Fail;
307 
308 	return kStatus_SSS_Success;
309 }
310 
set_rsa_keypair_rsa_crt(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,struct se050_rsa_keypair * keypair,size_t key_bit_len)311 static sss_status_t set_rsa_keypair_rsa_crt(Se05xSession_t *s_ctx,
312 					    Se05xPolicy_t *policy,
313 					    sss_se05x_object_t *k_object,
314 					    struct se050_rsa_keypair *keypair,
315 					    size_t key_bit_len)
316 {
317 	SE05x_TransientType_t type = kSE05x_TransientType_Transient;
318 	smStatus_t status = SM_OK;
319 
320 	if (k_object->isPersistant)
321 		type = kSE05x_TransientType_Persistent;
322 
323 	status = Se05x_API_WriteRSAKey(s_ctx, policy, k_object->keyId,
324 				       (U16)key_bit_len,
325 				       keypair->p, keypair->p_len,
326 				       SE05X_RSA_NO_q,
327 				       SE05X_RSA_NO_dp,
328 				       SE05X_RSA_NO_dq,
329 				       SE05X_RSA_NO_qInv,
330 				       SE05X_RSA_NO_pubExp,
331 				       SE05X_RSA_NO_priv,
332 				       SE05X_RSA_NO_pubMod,
333 				       (SE05x_INS_t)type,
334 				       kSE05x_KeyPart_Pair,
335 				       kSE05x_RSAKeyFormat_CRT);
336 	if (status != SM_OK)
337 		return kStatus_SSS_Fail;
338 
339 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
340 				       0,
341 				       SE05X_RSA_NO_p,
342 				       keypair->q, keypair->q_len,
343 				       SE05X_RSA_NO_dp,
344 				       SE05X_RSA_NO_dq,
345 				       SE05X_RSA_NO_qInv,
346 				       SE05X_RSA_NO_pubExp,
347 				       SE05X_RSA_NO_priv,
348 				       SE05X_RSA_NO_pubMod,
349 				       (SE05x_INS_t)type,
350 				       kSE05x_KeyPart_NA,
351 				       kSE05x_RSAKeyFormat_CRT);
352 	if (status != SM_OK)
353 		return kStatus_SSS_Fail;
354 
355 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
356 				       0,
357 				       SE05X_RSA_NO_p,
358 				       SE05X_RSA_NO_q,
359 				       keypair->dp, keypair->dp_len,
360 				       SE05X_RSA_NO_dq,
361 				       SE05X_RSA_NO_qInv,
362 				       SE05X_RSA_NO_pubExp,
363 				       SE05X_RSA_NO_priv,
364 				       SE05X_RSA_NO_pubMod,
365 				       (SE05x_INS_t)type,
366 				       kSE05x_KeyPart_NA,
367 				       kSE05x_RSAKeyFormat_CRT);
368 	if (status != SM_OK)
369 		return kStatus_SSS_Fail;
370 
371 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
372 				       0,
373 				       SE05X_RSA_NO_p,
374 				       SE05X_RSA_NO_q,
375 				       SE05X_RSA_NO_dp,
376 				       keypair->dq, keypair->dq_len,
377 				       SE05X_RSA_NO_qInv,
378 				       SE05X_RSA_NO_pubExp,
379 				       SE05X_RSA_NO_priv,
380 				       SE05X_RSA_NO_pubMod,
381 				       (SE05x_INS_t)type,
382 				       kSE05x_KeyPart_NA,
383 				       kSE05x_RSAKeyFormat_CRT);
384 	if (status != SM_OK)
385 		return kStatus_SSS_Fail;
386 
387 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
388 				       0,
389 				       SE05X_RSA_NO_p,
390 				       SE05X_RSA_NO_q,
391 				       SE05X_RSA_NO_dp,
392 				       SE05X_RSA_NO_dq,
393 				       keypair->qp, keypair->qp_len,
394 				       SE05X_RSA_NO_pubExp,
395 				       SE05X_RSA_NO_priv,
396 				       SE05X_RSA_NO_pubMod,
397 				       (SE05x_INS_t)type,
398 				       kSE05x_KeyPart_NA,
399 				       kSE05x_RSAKeyFormat_CRT);
400 	if (status != SM_OK)
401 		return kStatus_SSS_Fail;
402 
403 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
404 				       0,
405 				       SE05X_RSA_NO_p,
406 				       SE05X_RSA_NO_q,
407 				       SE05X_RSA_NO_dp,
408 				       SE05X_RSA_NO_dq,
409 				       SE05X_RSA_NO_qInv,
410 				       keypair->e, keypair->e_len,
411 				       SE05X_RSA_NO_priv,
412 				       SE05X_RSA_NO_pubMod,
413 				       (SE05x_INS_t)type,
414 				       kSE05x_KeyPart_NA,
415 				       kSE05x_RSAKeyFormat_CRT);
416 	if (status != SM_OK)
417 		return kStatus_SSS_Fail;
418 
419 	status = Se05x_API_WriteRSAKey(s_ctx, NULL, k_object->keyId,
420 				       0,
421 				       SE05X_RSA_NO_p,
422 				       SE05X_RSA_NO_q,
423 				       SE05X_RSA_NO_dp,
424 				       SE05X_RSA_NO_dq,
425 				       SE05X_RSA_NO_qInv,
426 				       SE05X_RSA_NO_pubExp,
427 				       SE05X_RSA_NO_priv,
428 				       keypair->n, keypair->n_len,
429 				       (SE05x_INS_t)type,
430 				       kSE05x_KeyPart_NA,
431 				       kSE05x_RSAKeyFormat_CRT);
432 	if (status != SM_OK)
433 		return kStatus_SSS_Fail;
434 
435 	return kStatus_SSS_Success;
436 }
437 
se050_key_store_set_rsa_key_bin(sss_se05x_key_store_t * store,sss_se05x_object_t * k_object,struct se050_rsa_keypair * keypair,struct se050_rsa_keypub * keypub,size_t key_bit_len)438 sss_status_t se050_key_store_set_rsa_key_bin(sss_se05x_key_store_t *store,
439 					     sss_se05x_object_t *k_object,
440 					     struct se050_rsa_keypair *keypair,
441 					     struct se050_rsa_keypub *keypub,
442 					     size_t key_bit_len)
443 {
444 	Se05xPolicy_t policy = { };
445 
446 	if (!store || !store->session || !k_object)
447 		return kStatus_SSS_Fail;
448 
449 	if (se050_key_exists(k_object->keyId, &store->session->s_ctx))
450 		key_bit_len = 0;
451 
452 	switch (k_object->objectType) {
453 	case kSSS_KeyPart_Public:
454 		return set_rsa_public(&store->session->s_ctx,
455 				      &policy, k_object,
456 				      keypub, key_bit_len);
457 	case kSSS_KeyPart_Private:
458 		if (k_object->cipherType == kSSS_CipherType_RSA)
459 			return set_rsa_private_rsa(&store->session->s_ctx,
460 						   &policy, k_object,
461 						   keypair, key_bit_len);
462 
463 		if (k_object->cipherType == kSSS_CipherType_RSA_CRT)
464 			return set_rsa_private_rsa_crt(&store->session->s_ctx,
465 						       &policy, k_object,
466 						       keypair, key_bit_len);
467 		return kStatus_SSS_Fail;
468 	case kSSS_KeyPart_Pair:
469 		if (k_object->cipherType == kSSS_CipherType_RSA)
470 			return set_rsa_keypair_rsa(&store->session->s_ctx,
471 						   &policy, k_object,
472 						   keypair, key_bit_len);
473 
474 		if (k_object->cipherType == kSSS_CipherType_RSA_CRT)
475 			return set_rsa_keypair_rsa_crt(&store->session->s_ctx,
476 						       &policy, k_object,
477 						       keypair, key_bit_len);
478 		return kStatus_SSS_Fail;
479 	default:
480 		return kStatus_SSS_Fail;
481 	}
482 }
483 
se050_get_free_memory(pSe05xSession_t ctx,uint16_t * p,SE05x_MemoryType_t type)484 sss_status_t  se050_get_free_memory(pSe05xSession_t ctx, uint16_t *p,
485 				    SE05x_MemoryType_t type)
486 {
487 	if (p && ctx && Se05x_API_GetFreeMemory(ctx, type, p) == SM_OK)
488 		return kStatus_SSS_Success;
489 
490 	return kStatus_SSS_Fail;
491 }
492 
se050_scp03_send_rotate_cmd(pSe05xSession_t ctx,struct s050_scp_rotate_cmd * cmd)493 sss_status_t se050_scp03_send_rotate_cmd(pSe05xSession_t ctx,
494 					 struct s050_scp_rotate_cmd *cmd)
495 {
496 	uint8_t rsp[64] = { 0 };
497 	size_t rsp_len = sizeof(rsp);
498 	tlvHeader_t hdr = {
499 		.hdr = {
500 			[0] = 0x80,
501 			[1] = 0xd8,
502 			[2] = 0,
503 			[3] = PUT_KEYS_KEY_IDENTIFIER,
504 		},
505 	};
506 	smStatus_t st = SM_NOT_OK;
507 
508 	if (!ctx || !cmd)
509 		return kStatus_SSS_Fail;
510 
511 	hdr.hdr[2] = cmd->cmd[0];
512 	st = DoAPDUTxRx_s_Case4(ctx, &hdr, cmd->cmd, cmd->cmd_len,
513 				rsp, &rsp_len);
514 
515 	if ((rsp_len - 1 > sizeof(rsp)) || rsp_len < 2)
516 		return kStatus_SSS_Fail;
517 
518 	st = (rsp[rsp_len - 2] << 8) + rsp[rsp_len - 1];
519 	if (st != SM_OK)
520 		return kStatus_SSS_Fail;
521 
522 	if (!memcmp(rsp, cmd->kcv, cmd->kcv_len))
523 		return kStatus_SSS_Success;
524 
525 	return kStatus_SSS_Fail;
526 }
527 
alloc_pubkey_buf(struct se050_ecc_keypub * keypub,size_t * len)528 static uint8_t *alloc_pubkey_buf(struct se050_ecc_keypub *keypub, size_t *len)
529 {
530 	size_t pubkey_len = 0;
531 	uint8_t *pubkey = NULL;
532 	uint8_t *buf = NULL;
533 
534 	pubkey_len = keypub->x_len + keypub->y_len + 1;
535 	buf = malloc(pubkey_len);
536 	if (!buf)
537 		return NULL;
538 
539 	*buf = 0x04;
540 	pubkey = buf + 1;
541 	memcpy(pubkey, keypub->x, keypub->x_len);
542 	memcpy(pubkey + keypub->x_len, keypub->y, keypub->y_len);
543 	*len = pubkey_len;
544 
545 	return buf;
546 }
547 
se050_ecc_gen_shared_secret(pSe05xSession_t ctx,uint32_t kid,struct se050_ecc_keypub * keypub,uint8_t * secret,size_t * len)548 sss_status_t se050_ecc_gen_shared_secret(pSe05xSession_t ctx, uint32_t kid,
549 					 struct se050_ecc_keypub *keypub,
550 					 uint8_t *secret, size_t *len)
551 {
552 	smStatus_t status = SM_OK;
553 	uint8_t *buf = NULL;
554 	size_t pubkey_len = 0;
555 
556 	if (!keypub || !secret || !len)
557 		return kStatus_SSS_Fail;
558 
559 	buf = alloc_pubkey_buf(keypub, &pubkey_len);
560 	if (!buf)
561 		return kStatus_SSS_Fail;
562 
563 	status = Se05x_API_ECGenSharedSecret(ctx, kid,
564 					     buf, pubkey_len, secret, len);
565 	free(buf);
566 	if (status != SM_OK)
567 		return kStatus_SSS_Fail;
568 
569 	return kStatus_SSS_Success;
570 }
571 
set_ecc_public(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,SE05x_TransientType_t type,struct se050_ecc_keypub * keypub)572 static sss_status_t set_ecc_public(Se05xSession_t *s_ctx,
573 				   Se05xPolicy_t *policy,
574 				   sss_se05x_object_t *k_object,
575 				   SE05x_TransientType_t type,
576 				   struct se050_ecc_keypub *keypub)
577 {
578 	size_t pubkey_len = 0;
579 	smStatus_t status = SM_NOT_OK;
580 	uint8_t *buf = NULL;
581 
582 	buf = alloc_pubkey_buf(keypub, &pubkey_len);
583 	if (!buf)
584 		return kStatus_SSS_Fail;
585 
586 	k_object->curve_id = keypub->curve;
587 	status = Se05x_API_WriteECKey(s_ctx, policy, SE05x_MaxAttemps_UNLIMITED,
588 				      k_object->keyId,
589 				      keypub->curve,
590 				      NULL,
591 				      0,
592 				      buf,
593 				      pubkey_len,
594 				      (SE05x_INS_t)type,
595 				      kSE05x_KeyPart_Public);
596 	free(buf);
597 	if (status != SM_OK)
598 		return kStatus_SSS_Fail;
599 
600 	return kStatus_SSS_Success;
601 }
602 
set_ecc_private(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,SE05x_TransientType_t type,struct se050_ecc_keypair * keypair)603 static sss_status_t set_ecc_private(Se05xSession_t *s_ctx,
604 				    Se05xPolicy_t *policy,
605 				    sss_se05x_object_t *k_object,
606 				    SE05x_TransientType_t type,
607 				    struct se050_ecc_keypair *keypair)
608 {
609 	smStatus_t status = SM_NOT_OK;
610 
611 	k_object->curve_id = keypair->pub.curve;
612 	status = Se05x_API_WriteECKey(s_ctx, policy, SE05x_MaxAttemps_UNLIMITED,
613 				      k_object->keyId,
614 				      keypair->pub.curve,
615 				      keypair->d,
616 				      keypair->d_len,
617 				      NULL,
618 				      0,
619 				      (SE05x_INS_t)type,
620 				      kSE05x_KeyPart_Private);
621 	if (status != SM_OK)
622 		return kStatus_SSS_Fail;
623 
624 	return kStatus_SSS_Success;
625 }
626 
set_ecc_pair(Se05xSession_t * s_ctx,Se05xPolicy_t * policy,sss_se05x_object_t * k_object,SE05x_TransientType_t type,struct se050_ecc_keypair * keypair)627 static sss_status_t set_ecc_pair(Se05xSession_t *s_ctx,
628 				 Se05xPolicy_t *policy,
629 				 sss_se05x_object_t *k_object,
630 				 SE05x_TransientType_t type,
631 				 struct se050_ecc_keypair *keypair)
632 {
633 	size_t pubkey_len = 0;
634 	smStatus_t status = SM_NOT_OK;
635 	uint8_t *buf = NULL;
636 
637 	buf = alloc_pubkey_buf(&keypair->pub, &pubkey_len);
638 	if (!buf)
639 		return kStatus_SSS_Fail;
640 
641 	k_object->curve_id = keypair->pub.curve;
642 	status = Se05x_API_WriteECKey(s_ctx, policy, SE05x_MaxAttemps_UNLIMITED,
643 				      k_object->keyId,
644 				      keypair->pub.curve,
645 				      keypair->d,
646 				      keypair->d_len,
647 				      buf,
648 				      pubkey_len,
649 				      (SE05x_INS_t)type,
650 				      kSE05x_KeyPart_Pair);
651 	free(buf);
652 	if (status != SM_OK)
653 		return kStatus_SSS_Fail;
654 
655 	return kStatus_SSS_Success;
656 }
657 
se050_key_store_set_ecc_key_bin(sss_se05x_key_store_t * store,sss_se05x_object_t * k_object,struct se050_ecc_keypair * keypair,struct se050_ecc_keypub * keypub)658 sss_status_t se050_key_store_set_ecc_key_bin(sss_se05x_key_store_t *store,
659 					     sss_se05x_object_t *k_object,
660 					     struct se050_ecc_keypair *keypair,
661 					     struct se050_ecc_keypub *keypub)
662 {
663 	SE05x_TransientType_t type = kSE05x_TransientType_Transient;
664 	Se05xPolicy_t policy = { };
665 
666 	if (!store || !store->session || !k_object)
667 		return kStatus_SSS_Fail;
668 
669 	if (k_object->isPersistant)
670 		type = kSE05x_TransientType_Persistent;
671 
672 	switch (k_object->objectType) {
673 	case kSSS_KeyPart_Public:
674 		if (!keypub)
675 			return kStatus_SSS_Fail;
676 
677 		return set_ecc_public(&store->session->s_ctx,
678 				      &policy, k_object, type, keypub);
679 	case kSSS_KeyPart_Private:
680 		if (!keypair)
681 			return kStatus_SSS_Fail;
682 
683 		return set_ecc_private(&store->session->s_ctx,
684 				       &policy, k_object, type, keypair);
685 	case kSSS_KeyPart_Pair:
686 		if (!keypair)
687 			return kStatus_SSS_Fail;
688 
689 		return set_ecc_pair(&store->session->s_ctx,
690 				    &policy, k_object, type, keypair);
691 	default:
692 		return  kStatus_SSS_Fail;
693 	}
694 }
695 
se050_key_store_get_ecc_key_bin(sss_se05x_key_store_t * store,sss_se05x_object_t * k_object,uint8_t * key,size_t * key_len)696 sss_status_t se050_key_store_get_ecc_key_bin(sss_se05x_key_store_t *store,
697 					     sss_se05x_object_t *k_object,
698 					     uint8_t *key, size_t *key_len)
699 {
700 	smStatus_t status = SM_NOT_OK;
701 	uint8_t *buf = NULL;
702 	size_t buflen = 0;
703 
704 	if (!store || !store->session || !k_object || !key || !key_len)
705 		return kStatus_SSS_Fail;
706 
707 	switch (k_object->cipherType) {
708 	case kSSS_CipherType_EC_NIST_P:
709 	case kSSS_CipherType_EC_NIST_K:
710 	case kSSS_CipherType_EC_BRAINPOOL:
711 	case kSSS_CipherType_EC_BARRETO_NAEHRIG:
712 	case kSSS_CipherType_EC_MONTGOMERY:
713 	case kSSS_CipherType_EC_TWISTED_ED:
714 		add_ecc_header(key, key_len, &buf, &buflen, k_object->curve_id);
715 		status = Se05x_API_ReadObject(&store->session->s_ctx,
716 					      k_object->keyId, 0, 0,
717 					      buf, key_len);
718 		if (status != SM_OK)
719 			return kStatus_SSS_Fail;
720 
721 		*key_len += buflen;
722 		buflen = *key_len;
723 		get_ecc_raw_data(key, *key_len, &buf, &buflen,
724 				 k_object->curve_id);
725 
726 		/* return only the binary data */
727 		*key_len = buflen;
728 		memcpy(key, buf, buflen);
729 		return kStatus_SSS_Success;
730 	default:
731 		return kStatus_SSS_Fail;
732 	}
733 }
734