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