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 <crypto/crypto.h>
8 #include <mm/core_mmu.h>
9 #include <se050.h>
10 #include <se050_utils.h>
11 #include <string.h>
12 #include <tee/tee_fs.h>
13 #include <tee/tee_obj.h>
14 #include <tee/tee_pobj.h>
15 
crypto_storage_obj_del(struct tee_obj * o)16 TEE_Result crypto_storage_obj_del(struct tee_obj *o)
17 {
18 	sss_status_t status = kStatus_SSS_Success;
19 	uint32_t val = SE050_KEY_WATERMARK;
20 	TEE_Result ret = TEE_ERROR_GENERIC;
21 	sss_se05x_object_t k_object = { };
22 	uint8_t *data = NULL;
23 	uint8_t *p = NULL;
24 	bool found = false;
25 	size_t len = 0;
26 
27 	if (!o)
28 		return TEE_ERROR_BAD_PARAMETERS;
29 
30 	len = o->info.dataSize;
31 
32 	/* Supported keys (ECC/RSA) require less than 4KB of storage */
33 	if (len > SMALL_PAGE_SIZE || len <= sizeof(uint64_t))
34 		return TEE_SUCCESS;
35 
36 	data = calloc(1, len);
37 	if (!data)
38 		return TEE_ERROR_OUT_OF_MEMORY;
39 
40 	/* Read the object into memory */
41 	ret = o->pobj->fops->read(o->fh, o->info.dataPosition, data, &len);
42 	if (ret) {
43 		EMSG("se05x: can not read the object prior removal");
44 		free(data);
45 		goto out;
46 	}
47 
48 	/* Scan the object for the watermark */
49 	p = data;
50 	while (len >= sizeof(uint32_t) && !found) {
51 		if (memcmp(p, &val, sizeof(val)) != 0) {
52 			p++;
53 			len--;
54 			continue;
55 		}
56 		found = true;
57 	}
58 
59 	if (!found) {
60 		free(data);
61 		return TEE_SUCCESS;
62 	}
63 
64 	/* Retrieve the object identifier */
65 	p = p - 4;
66 	memcpy((void *)&val, p, sizeof(val));
67 	free(data);
68 
69 	if (val < OID_MIN || val > OID_MAX)
70 		return TEE_SUCCESS;
71 
72 	status = sss_se05x_key_object_init(&k_object, se050_kstore);
73 	if (status != kStatus_SSS_Success) {
74 		ret = TEE_ERROR_BAD_STATE;
75 		goto out;
76 	}
77 
78 	status = sss_se05x_key_object_get_handle(&k_object, val);
79 	if (status != kStatus_SSS_Success) {
80 		EMSG("se05x: can not communicate with the secure element");
81 		ret = TEE_ERROR_BAD_STATE;
82 		goto out;
83 	}
84 
85 	status = sss_se05x_key_store_erase_key(se050_kstore, &k_object);
86 	if (status != kStatus_SSS_Success) {
87 		EMSG("se05x: can not communicate with the secure element");
88 		ret = TEE_ERROR_BAD_STATE;
89 		goto out;
90 	}
91 
92 out:
93 	/*
94 	 * Users can delete the SE05X NVM objects during boot using a built
95 	 * time configuration flag (CFG_CORE_SE05X_INIT_NVM).
96 	 *
97 	 * This could cause the deletion of the secure storage objects holding
98 	 * references to those IDs via crypto_storage_obj_del() to fail, leaving
99 	 * broken links in the file system.
100 	 *
101 	 * Therefore we only permit this call to block the deletion upon an
102 	 * additional specific config.
103 	 */
104 	if (ret && IS_ENABLED(CFG_CORE_SE05X_BLOCK_OBJ_DEL_ON_ERROR))
105 		return ret;
106 
107 	return TEE_SUCCESS;
108 }
109