blob: 53f02d10c02a5274e8a3c75d2443260e880da85f [file] [log] [blame]
jk-arm957cfea2021-06-18 15:52:12 +05301/** @file
2 * Copyright (c) 2021 Arm Limited or its affiliates. All rights reserved.
3 * SPDX-License-Identifier : Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16**/
17
18#include <val_adac.h>
19#include <psa_adac_cryptosystems.h>
20#include <psa_adac_sdm.h>
21#include <psa_adac_debug.h>
22#include <pal_interfaces.h>
23
24void val_adac_host_init(void)
25{
26 psa_adac_platform_init();
27 psa_crypto_init();
28}
29
30psa_status_t val_load_certificate_chain(const char *chain_file, uint8_t **chain, size_t *chain_size)
31{
32 int ret_val;
33 psa_status_t r = PSA_SUCCESS;
34
35 if (chain_file == NULL) {
36 printf("Error:Path not found\n");
37 r = PSA_ERROR_INVALID_ARGUMENT;
38 return r;
39 }
40 ret_val = load_trust_chain(chain_file, chain, chain_size);
41 if (ret_val != 0) {
42 printf("Error loading trust chain (%s)\n", chain_file);
43 r = PSA_ERROR_GENERIC_ERROR;
44 }
45 return r;
46}
47
48psa_status_t val_infer_cryptosystem(uint32_t *chain, size_t chain_size, psa_tlv_t **extns_list,
49 size_t *extns_count, uint8_t *key_system)
50{
51 int ret_val;
52 psa_status_t r = PSA_SUCCESS;
53 uint8_t key_type;
54 size_t count, i;
55 psa_tlv_t *current_extn;
56
57 ret_val = split_tlv_static(chain, chain_size, extns_list, MAX_EXTENSIONS, extns_count);
58 if (ret_val != 0) {
59 PSA_ADAC_LOG_ERR("host", "Error parsing trust chain\n");
60 r = PSA_ERROR_GENERIC_ERROR;
61 return r;
62 }
63 count = *extns_count;
64 if (count > MAX_EXTENSIONS) {
65 printf("Error:Extension count exceeded maximum allowed\n");
66 r = PSA_ERROR_NOT_PERMITTED;
67 return r;
68 }
69
70 PSA_ADAC_LOG_INFO("host", "Found %zu certificates\n", count);
71 for (i = 0; i < count; i++) {
72 current_extn = extns_list[i];
73 if ((current_extn)->type_id == 0x0201)
74 key_type = ((certificate_header_t *) current_extn->value)->key_type;
75 }
76 *key_system = key_type;
77 PSA_ADAC_LOG_INFO("host", "Cryptosystem detected: %d\n", key_type);
78 return r;
79}
80
81psa_status_t val_get_private_key(const char *key_file, uint8_t *type, psa_key_handle_t *handle,
82 uint8_t **key_ptr, size_t *size)
83{
84 int ret_val;
85 psa_status_t r = PSA_SUCCESS;
86 uint8_t key_type = *type;
87
88 if (key_file == NULL) {
89 printf("Error:Path not found\n");
90 r = PSA_ERROR_INVALID_ARGUMENT;
91 return r;
92 }
93
94 switch (key_type) {
95 case ECDSA_P256_SHA256:
96 case ECDSA_P521_SHA512:
97 case RSA_3072_SHA256:
98 case RSA_4096_SHA256:
99 case ED_25519_SHA512:
100 case ED_448_SHAKE256:
101 case SM_SM2_SM3:
102 ret_val = import_private_key(key_file, type, handle);
103 if (ret_val != 0) {
104 printf("Error importing private key (%s)\n", key_file);
105 r = PSA_ERROR_GENERIC_ERROR;
106 } else {
107 key_ptr = NULL;
108 size = 0;
109 }
110 break;
111
112 case CMAC_AES:
113 case HMAC_SHA256:
114 ret_val = load_secret_key(key_file, key_type, key_ptr, size);
115 if (ret_val != 0) {
116 printf("Error importing secret key (%s)\n", key_file);
117 r = PSA_ERROR_GENERIC_ERROR;
118 } else {
119 handle = NULL;
120 }
121 break;
122
123 default:
124 printf("Error: unsupported key type (0x%x)\n", key_type);
125 r = PSA_ERROR_NOT_SUPPORTED;
126 }
127 return r;
128}
129
130request_packet_t *val_construct_command(uint16_t cmd_type, uint8_t *data, size_t data_size)
131{
132 request_packet_t *packet = NULL;
133
134 switch (cmd_type) {
135 case SDP_RESUME_BOOT_CMD:
136 case SDP_LOCK_DEBUG_CMD:
137 case SDP_DISCOVERY_CMD:
138 case SDP_AUTH_START_CMD:
139 packet = request_packet_build(cmd_type, NULL, 0);
140 break;
141 case SDP_AUTH_RESPONSE_CMD:
142 if (data == NULL || data_size == 0) {
143 printf("Error: No payload specified\n");
144 break;
145 }
146 packet = request_packet_build((uint16_t)cmd_type, data, data_size);
147 break;
148 default:
149 //TO DO: Callback for vendor specific command construction
150 printf("Error: Unrecognized command. ID=(0x%x)\n", cmd_type);
151 }
152 return packet;
153}
154
155psa_status_t val_issue_command(uint32_t command, request_packet_t *packet,
156 uint8_t *data, size_t data_size)
157{
158 int ret_val;
159 psa_status_t r = PSA_SUCCESS;
160
161 packet = val_construct_command((uint16_t)command, data, data_size);
162
163 if (packet == NULL) {
164 printf("Command construction failed\n");
165 r = PSA_ERROR_GENERIC_ERROR;
166 return r;
167 }
168
169 switch (command) {
170 case SDP_DISCOVERY_CMD:
171 printf("Sending discovery request\n");
172 break;
173 case SDP_AUTH_START_CMD:
174 printf("Sending challenge request\n");
175 break;
176 case SDP_AUTH_RESPONSE_CMD:
177 printf("Sending authentication response\n");
178 break;
179 case SDP_RESUME_BOOT_CMD:
180 printf("Sending close session command\n");
181 break;
182 case SDP_LOCK_DEBUG_CMD:
183 printf("Sending lock debug request\n");
184 default:
185 //TO DO: Vendor specific message
186 printf("Error: Unrecognized command. ID=(0x%x)\n", command);
187 r = PSA_ERROR_NOT_SUPPORTED;
188 }
189 ret_val = request_packet_send(packet);
190 if (ret_val < 0)
191 r = PSA_ERROR_GENERIC_ERROR;
192
193 request_packet_release(packet);
194 return r;
195}
196
197response_packet_t *val_await_response(void)
198{
199 return response_packet_receive();
200}
201
202psa_status_t val_parse_response(uint32_t command, response_packet_t *packet)
203{
204 int ret_val;
205 psa_status_t r = PSA_SUCCESS;
206 size_t i;
207 psa_tlv_t *tlv;
208 psa_auth_challenge_t *challenge;
209
210 if (packet == NULL) {
211 printf("Error: Target response not obtained\n");
212 r = PSA_ERROR_COMMUNICATION_FAILURE;
213 return r;
214 }
215
216 switch (command) {
217 case SDP_DISCOVERY_CMD:
218 printf("Receiving discovery response...\n");
219 for (i = 0; (i + 4) < (packet->data_count * 4);) {
220 tlv = (psa_tlv_t *) (((uint8_t *)packet->data) + i);
221 i += sizeof(psa_tlv_t) + tlv->length_in_bytes;
222 }
223 break;
224 case SDP_AUTH_START_CMD:
225 printf("Receiving challenge\n");
226 printf("status = 0x%04x, data_count = %d\n", packet->status, packet->data_count);
227 if (packet->data_count * 4 != sizeof(psa_auth_challenge_t)) {
228 r = PSA_ERROR_GENERIC_ERROR;
229 return r;
230 }
231 challenge = (psa_auth_challenge_t *) packet->data;
232 PSA_ADAC_LOG_DUMP("host", "challenge", challenge->challenge_vector,
233 sizeof(challenge->challenge_vector));
234 break;
235 case SDP_AUTH_RESPONSE_CMD:
236 case SDP_RESUME_BOOT_CMD:
237 case SDP_LOCK_DEBUG_CMD:
238 printf("status = 0x%04x, data_count = %d\n", packet->status, packet->data_count);
239 break;
240 default:
241 r = PSA_ERROR_NOT_SUPPORTED;
242 }
243 return r;
244}
245
246psa_status_t val_sign_token(uint8_t challenge[], size_t challenge_size, uint8_t signature_type,
247 uint8_t exts[], size_t exts_size, uint8_t *fragment[],
248 size_t *fragment_size, psa_key_handle_t handle,
249 uint8_t *key, size_t key_size)
250{
251 psa_status_t r;
252
253 r = psa_adac_sign_token(challenge, challenge_size, signature_type, exts, exts_size,
254 fragment, fragment_size, handle, key, key_size);
255 if (r == PSA_SUCCESS) {
256 PSA_ADAC_LOG_DUMP("host", "token", *fragment, *fragment_size);
257 } else {
258 PSA_ADAC_LOG_ERR("host", "Error signing token\n");
259 r = PSA_ERROR_GENERIC_ERROR;
260 }
261 return r;
262}
263
264psa_status_t val_send_certificate(psa_tlv_t **extns_list, size_t extns_count)
265{
266 request_packet_t *request;
267 response_packet_t *response;
268 psa_status_t r;
269 uint8_t *payload;
270 size_t i, payload_size;
271 psa_tlv_t *current_extn;
272
273 for (size_t i = 0; i < extns_count; i++) {
274 current_extn = extns_list[i];
275 if (current_extn->type_id == 0x0201) {
276 payload = (uint8_t *)current_extn;
277 payload_size = current_extn->length_in_bytes + sizeof(psa_tlv_t);
278
279 printf("Sending Certificate\n");
280 r = val_issue_command(SDP_AUTH_RESPONSE_CMD, request, payload, payload_size);
281 if (r != PSA_SUCCESS)
282 return r;
283
284 printf("Receiving token_authentication response\n");
285 response = val_await_response();
286 r = val_parse_response(SDP_AUTH_RESPONSE_CMD, response);
287 if (r != PSA_SUCCESS)
288 return r;
289
290 if (response->status == SDP_NEED_MORE_DATA)
291 response_packet_release(response);
292 }
293 }
294 if (response->status != SDP_NEED_MORE_DATA) {
295 PSA_ADAC_LOG_ERR("host", "Unexpected response status %x\n", response->status);
296 r = PSA_ERROR_GENERIC_ERROR;
297 return r;
298 }
299 response_packet_release(response);
300 return r;
301}
302
303int val_check_cryptosystem_support(response_packet_t *packet, uint8_t key_system)
304{
305 int found = 0, j;
306 size_t i = 0;
307 psa_tlv_t *tlv;
308 uint8_t *key_support_types = NULL;
309
310 while ((i + 4) < (packet->data_count * 4)) {
311 tlv = (psa_tlv_t *) (((uint8_t *)packet->data) + i);
312 if (tlv->type_id == 0x0102) {
313 key_support_types = tlv->value;
314 for (j = 0; j < (tlv->length_in_bytes); j++) {
315 if (*(key_support_types+j) == key_system) {
316 found = 1;
317 break;
318 }
319 }
320 }
321 i += sizeof(psa_tlv_t) + tlv->length_in_bytes;
322 }
323
324 if (key_support_types == NULL)
325 printf("Cryptosystem Type ID not found in target's response\n");
326 else if (!found)
327 printf("Cryptosystem not supported by target\n");
328 else
329 printf("Cryptosystem supported by target\n");
330
331 return found;
332}