forked from nrfconnect/sdk-trusted-firmware-m
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcrypto_key_management.c
More file actions
172 lines (154 loc) · 5.31 KB
/
crypto_key_management.c
File metadata and controls
172 lines (154 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "config_tfm.h"
#include "tfm_mbedcrypto_include.h"
#include "tfm_crypto_api.h"
#include "tfm_crypto_key.h"
#include "tfm_crypto_defs.h"
#include "crypto_library.h"
/*!
* \addtogroup tfm_crypto_api_shim_layer
*
*/
/*!@{*/
#if CRYPTO_KEY_MODULE_ENABLED
psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
psa_outvec out_vec[],
struct tfm_crypto_key_id_s *encoded_key)
{
const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
/* Build a key_id in the library key format, i.e. (owner, key_id) */
tfm_crypto_library_key_id_t library_key = tfm_crypto_library_key_id_init(
encoded_key->owner, encoded_key->key_id);
psa_key_attributes_t srv_key_attr;
switch (iov->function_id) {
case TFM_CRYPTO_IMPORT_KEY_SID:
case TFM_CRYPTO_COPY_KEY_SID:
case TFM_CRYPTO_GENERATE_KEY_SID:
if ((in_vec[1].base == NULL) ||
(in_vec[1].len != (sizeof(srv_key_attr) - TFM_CRYPTO_KEY_ATTR_OFFSET_CLIENT_SERVER))) {
return PSA_ERROR_PROGRAMMER_ERROR;
}
memcpy(&srv_key_attr, in_vec[1].base, in_vec[1].len);
tfm_crypto_library_get_library_key_id_set_owner(encoded_key->owner, &srv_key_attr);
break;
default:
break;
}
switch (iov->function_id) {
case TFM_CRYPTO_IMPORT_KEY_SID:
{
const uint8_t *data = in_vec[2].base;
size_t data_length = in_vec[2].len;
psa_key_id_t *key_id = out_vec[0].base;
if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
return PSA_ERROR_PROGRAMMER_ERROR;
}
status = psa_import_key(&srv_key_attr,
data, data_length, &library_key);
/* Update the imported key id */
*key_id = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
}
break;
case TFM_CRYPTO_DESTROY_KEY_SID:
{
status = psa_destroy_key(library_key);
}
break;
case TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID:
{
psa_key_attributes_t *key_attributes = out_vec[0].base;
status = psa_get_key_attributes(library_key, &srv_key_attr);
/* Note that we just copy out_vec[0].len, because in this context
* sizeof(psa_key_attributes_t) would return the size of the service
* view of the attributes, while we are passing back to the caller
* only the client view of it, i.e. without the owner field at the
* end of the structure
*/
if ((out_vec[0].base == NULL) || (out_vec[0].len > sizeof(psa_key_attributes_t))) {
return PSA_ERROR_PROGRAMMER_ERROR;
}
memcpy(key_attributes, &srv_key_attr, out_vec[0].len);
}
break;
case TFM_CRYPTO_EXPORT_KEY_SID:
{
uint8_t *data = out_vec[0].base;
size_t data_size = out_vec[0].len;
status = psa_export_key(library_key, data, data_size,
&(out_vec[0].len));
if (status != PSA_SUCCESS) {
out_vec[0].len = 0;
}
}
break;
case TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID:
{
uint8_t *data = out_vec[0].base;
size_t data_size = out_vec[0].len;
status = psa_export_public_key(library_key, data, data_size,
&(out_vec[0].len));
if (status != PSA_SUCCESS) {
out_vec[0].len = 0;
}
}
break;
case TFM_CRYPTO_PURGE_KEY_SID:
{
status = psa_purge_key(library_key);
}
break;
case TFM_CRYPTO_COPY_KEY_SID:
{
psa_key_id_t *target_key_id = out_vec[0].base;
tfm_crypto_library_key_id_t target_key = tfm_crypto_library_key_id_init_default();
if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
return PSA_ERROR_PROGRAMMER_ERROR;
}
status = psa_copy_key(library_key,
&srv_key_attr,
&target_key);
if (status != PSA_SUCCESS) {
return status;
}
*target_key_id = CRYPTO_LIBRARY_GET_KEY_ID(target_key);
}
break;
case TFM_CRYPTO_GENERATE_KEY_SID:
{
psa_key_id_t *key_handle = out_vec[0].base;
if ((out_vec[0].base == NULL) || (out_vec[0].len < sizeof(psa_key_id_t))) {
return PSA_ERROR_PROGRAMMER_ERROR;
}
status = psa_generate_key(&srv_key_attr, &library_key);
if (status != PSA_SUCCESS) {
return status;
}
*key_handle = CRYPTO_LIBRARY_GET_KEY_ID(library_key);
}
break;
default:
return PSA_ERROR_NOT_SUPPORTED;
}
return status;
}
#else /* CRYPTO_KEY_MODULE_ENABLED */
psa_status_t tfm_crypto_key_management_interface(psa_invec in_vec[],
psa_outvec out_vec[],
struct tfm_crypto_key_id_s *encoded_key)
{
(void)in_vec;
(void)out_vec;
(void)encoded_key;
return PSA_ERROR_NOT_SUPPORTED;
}
#endif /* CRYPTO_KEY_MODULE_ENABLED */
/*!@}*/