blob: 2ba5cf7aad59d282c9d028f575f7e252f77e15dd [file] [log] [blame]
Jamie Foxab30e712023-03-30 17:48:36 +01001/*
Tamas Band0983e92024-01-25 16:32:51 +01002 * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
Jamie Foxab30e712023-03-30 17:48:36 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "dpe_cmd_decode.h"
9
10#include <string.h>
11
12#include "dpe_client.h"
Maulik Patelad2f3db2023-05-17 15:41:36 +010013#include "dpe_context_mngr.h"
Maulik Patele6adc112023-08-18 14:21:51 +010014#include "dpe_crypto_config.h"
Jamie Foxab30e712023-03-30 17:48:36 +010015#include "qcbor/qcbor_encode.h"
16#include "qcbor/qcbor_decode.h"
17#include "qcbor/qcbor_spiffy_decode.h"
18
Tamas Band0983e92024-01-25 16:32:51 +010019/*
20 * The goal to reuse the cmd_buf allocated in dpe_req_mngr.c to create the
21 * big objects (certificate, certificate_chain) in place rather then allocate
22 * a separate buffer on the stack and later copy them to cmd_buf.
23 *
24 * The temporary buffer is allocated from the end of the cmd_buf. When the
25 * reply is encoded then the content of the temp buf is moved to its final
26 * place in the cmd_buf.
27 *
28 * Overlapping copy is not an issue because QCBOR relies on memmove under the
29 * hood which handles this scenario.
30 *
31 * Note:
32 * Make sure that the beginning of the encoded reply does not overwrite the
33 * data in the temp buf. That is why the temp buff is allocated at the end of
34 * cmd_buf.
35 */
36#define REUSE_CMD_BUF(size) (uint8_t *)encode_ctx->OutBuf.UB.ptr + \
37 encode_ctx->OutBuf.UB.len - \
38 (size)
39
Jamie Foxab30e712023-03-30 17:48:36 +010040static dpe_error_t decode_dice_inputs(QCBORDecodeContext *decode_ctx,
41 DiceInputValues *input)
42{
43 QCBORError qcbor_err;
44 UsefulBufC out = { NULL, 0 };
45 int64_t out_int;
46
47 /* The DICE inputs are encoded as a map wrapped into a byte string */
48 QCBORDecode_EnterBstrWrappedFromMapN(decode_ctx,
Maulik Patela81605b2023-10-24 12:17:03 +010049 DPE_DERIVE_CONTEXT_INPUT_DATA,
Jamie Foxab30e712023-03-30 17:48:36 +010050 QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
51 QCBORDecode_EnterMap(decode_ctx, NULL);
52
53 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_CODE_HASH, &out);
54 if (out.len != sizeof(input->code_hash)) {
55 return DPE_INVALID_COMMAND;
56 }
57 memcpy(input->code_hash, out.ptr, out.len);
58
59 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_CODE_DESCRIPTOR, &out);
60 input->code_descriptor = out.ptr;
61 input->code_descriptor_size = out.len;
62
63 QCBORDecode_GetInt64InMapN(decode_ctx, DICE_CONFIG_TYPE, &out_int);
64
65 /* Check error state before interpreting config type */
66 qcbor_err = QCBORDecode_GetError(decode_ctx);
67 if (qcbor_err != QCBOR_SUCCESS) {
68 return DPE_INVALID_COMMAND;
69 }
70
71 if (out_int < kDiceConfigTypeInline ||
72 out_int > kDiceConfigTypeDescriptor) {
73 return DPE_INVALID_COMMAND;
74 }
75 input->config_type = (DiceConfigType)out_int;
76
77 /* Only one of config value or config descriptor needs to be provided */
78 if (input->config_type == kDiceConfigTypeInline) {
79 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_CONFIG_VALUE, &out);
80 if (out.len != sizeof(input->config_value)) {
81 return DPE_INVALID_COMMAND;
82 }
83 memcpy(input->config_value, out.ptr, out.len);
84
85 /* Config descriptor is not provided */
86 input->config_descriptor = NULL;
87 input->config_descriptor_size = 0;
88 } else {
89 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_CONFIG_DESCRIPTOR,
90 &out);
91 input->config_descriptor = out.ptr;
92 input->config_descriptor_size = out.len;
93
94 /* Config value is not provided */
95 memset(input->config_value, 0, sizeof(input->config_value));
96 }
97
98 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_AUTHORITY_HASH, &out);
99 if (out.len != sizeof(input->authority_hash)) {
100 return DPE_INVALID_COMMAND;
101 }
102 memcpy(input->authority_hash, out.ptr, out.len);
103
104 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_AUTHORITY_DESCRIPTOR,
105 &out);
106 input->authority_descriptor = out.ptr;
107 input->authority_descriptor_size = out.len;
108
109 QCBORDecode_GetInt64InMapN(decode_ctx, DICE_MODE, &out_int);
110 if (out_int < kDiceModeNotInitialized || out_int > kDiceModeMaintenance) {
111 return DPE_INVALID_COMMAND;
112 }
113 input->mode = (DiceMode)out_int;
114
115 QCBORDecode_GetByteStringInMapN(decode_ctx, DICE_HIDDEN, &out);
116 if (out.len != sizeof(input->hidden)) {
117 return DPE_INVALID_COMMAND;
118 }
119 memcpy(input->hidden, out.ptr, out.len);
120
121 QCBORDecode_ExitMap(decode_ctx);
122 QCBORDecode_ExitBstrWrapped(decode_ctx);
123
124 return DPE_NO_ERROR;
125}
126
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000127//TODO: Handle the omission of parameters from DPE commands.
Maulik Patela81605b2023-10-24 12:17:03 +0100128static dpe_error_t decode_derive_context(QCBORDecodeContext *decode_ctx,
129 QCBOREncodeContext *encode_ctx,
130 int32_t client_id)
Jamie Foxab30e712023-03-30 17:48:36 +0100131{
132 dpe_error_t dpe_err;
133 QCBORError qcbor_err;
134 UsefulBufC out;
135 int context_handle;
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000136 int32_t target_locality;
Jamie Foxab30e712023-03-30 17:48:36 +0100137 bool retain_parent_context;
Maulik Patela81605b2023-10-24 12:17:03 +0100138 bool allow_new_context_to_derive;
Jamie Foxab30e712023-03-30 17:48:36 +0100139 bool create_certificate;
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000140 bool return_certificate;
141 bool allow_new_context_to_export;
142 bool export_cdi;
Jamie Foxab30e712023-03-30 17:48:36 +0100143 DiceInputValues dice_inputs;
Maulik Patela81605b2023-10-24 12:17:03 +0100144 int new_context_handle;
Jamie Foxab30e712023-03-30 17:48:36 +0100145 int new_parent_context_handle;
Tamas Band0983e92024-01-25 16:32:51 +0100146 uint8_t *new_certificate_buf = REUSE_CMD_BUF(DICE_CERT_SIZE);
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000147 uint8_t exported_cdi_buf[DICE_MAX_ENCODED_CDI_SIZE];
148 size_t new_certificate_actual_size = 0;
149 size_t exported_cdi_actual_size = 0;
Jamie Foxab30e712023-03-30 17:48:36 +0100150
Maulik Patela81605b2023-10-24 12:17:03 +0100151 /* Decode DeriveContext command */
Jamie Foxab30e712023-03-30 17:48:36 +0100152 QCBORDecode_EnterMap(decode_ctx, NULL);
153
Maulik Patela81605b2023-10-24 12:17:03 +0100154 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_DERIVE_CONTEXT_CONTEXT_HANDLE,
Jamie Foxab30e712023-03-30 17:48:36 +0100155 &out);
156 if (out.len != sizeof(context_handle)) {
157 return DPE_INVALID_COMMAND;
158 }
159 memcpy(&context_handle, out.ptr, out.len);
160
Maulik Patela81605b2023-10-24 12:17:03 +0100161 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT,
Jamie Foxab30e712023-03-30 17:48:36 +0100162 &retain_parent_context);
163
Maulik Patela81605b2023-10-24 12:17:03 +0100164 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE,
165 &allow_new_context_to_derive);
Jamie Foxab30e712023-03-30 17:48:36 +0100166
Maulik Patela81605b2023-10-24 12:17:03 +0100167 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE,
Jamie Foxab30e712023-03-30 17:48:36 +0100168 &create_certificate);
169
170 dpe_err = decode_dice_inputs(decode_ctx, &dice_inputs);
171 if (dpe_err != DPE_NO_ERROR) {
172 return dpe_err;
173 }
174
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000175 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_DERIVE_CONTEXT_TARGET_LOCALITY,
176 &out);
177 if (out.len != sizeof(target_locality)) {
178 return DPE_INVALID_COMMAND;
179 }
180 memcpy(&target_locality, out.ptr, out.len);
181
182 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE,
183 &return_certificate);
184
185 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT,
186 &allow_new_context_to_export);
187
188 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_EXPORT_CDI,
189 &export_cdi);
190
Jamie Foxab30e712023-03-30 17:48:36 +0100191 QCBORDecode_ExitMap(decode_ctx);
192
193 /* Exit top level array */
194 QCBORDecode_ExitArray(decode_ctx);
195
196 /* Finish and check for errors before using decoded values */
197 qcbor_err = QCBORDecode_Finish(decode_ctx);
198 if (qcbor_err != QCBOR_SUCCESS) {
199 return DPE_INVALID_COMMAND;
200 }
201
Maulik Patela81605b2023-10-24 12:17:03 +0100202 dpe_err = derive_context_request(context_handle, retain_parent_context,
203 allow_new_context_to_derive, create_certificate,
204 &dice_inputs, client_id,
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000205 target_locality,
206 return_certificate,
207 allow_new_context_to_export,
208 export_cdi,
Maulik Patela81605b2023-10-24 12:17:03 +0100209 &new_context_handle,
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000210 &new_parent_context_handle,
211 new_certificate_buf,
Tamas Band0983e92024-01-25 16:32:51 +0100212 DICE_CERT_SIZE,
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000213 &new_certificate_actual_size,
214 exported_cdi_buf,
215 sizeof(exported_cdi_buf),
216 &exported_cdi_actual_size);
Jamie Foxab30e712023-03-30 17:48:36 +0100217 if (dpe_err != DPE_NO_ERROR) {
218 return dpe_err;
219 }
220
221 /* Encode response */
222 QCBOREncode_OpenArray(encode_ctx);
223 QCBOREncode_AddInt64(encode_ctx, DPE_NO_ERROR);
224
225 QCBOREncode_OpenMap(encode_ctx);
Maulik Patela81605b2023-10-24 12:17:03 +0100226 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE,
227 (UsefulBufC){ &new_context_handle,
228 sizeof(new_context_handle) });
Jamie Foxab30e712023-03-30 17:48:36 +0100229 QCBOREncode_AddBytesToMapN(encode_ctx,
Maulik Patela81605b2023-10-24 12:17:03 +0100230 DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE,
Jamie Foxab30e712023-03-30 17:48:36 +0100231 (UsefulBufC){ &new_parent_context_handle,
232 sizeof(new_parent_context_handle) });
Maulik Patel9fd8bd22023-10-30 10:58:30 +0000233
234 /* The certificate is already encoded into a CBOR array by the function
235 * add_encoded_layer_certificate. Add it as a byte string so that its
236 * decoding can be skipped and the CBOR returned to the caller.
237 */
238 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_DERIVE_CONTEXT_NEW_CERTIFICATE,
239 (UsefulBufC){ new_certificate_buf,
240 new_certificate_actual_size });
241
242 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_DERIVE_CONTEXT_EXPORTED_CDI,
243 (UsefulBufC){ exported_cdi_buf,
244 exported_cdi_actual_size });
245
Jamie Foxab30e712023-03-30 17:48:36 +0100246 QCBOREncode_CloseMap(encode_ctx);
247
248 QCBOREncode_CloseArray(encode_ctx);
249
250 return DPE_NO_ERROR;
251}
252
Maulik Patel54d65f72023-06-28 13:04:36 +0100253static dpe_error_t decode_destroy_context(QCBORDecodeContext *decode_ctx,
254 QCBOREncodeContext *encode_ctx)
255{
256 dpe_error_t dpe_err;
257 QCBORError qcbor_err;
258 UsefulBufC out;
259 int context_handle;
260 bool destroy_recursively;
261
262 /* Decode Destroy context command */
263 QCBORDecode_EnterMap(decode_ctx, NULL);
264
265 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_DESTROY_CONTEXT_HANDLE,
266 &out);
267 if (out.len != sizeof(context_handle)) {
268 return DPE_INVALID_COMMAND;
269 }
270 memcpy(&context_handle, out.ptr, out.len);
271
272 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DESTROY_CONTEXT_RECURSIVELY,
273 &destroy_recursively);
274
275 QCBORDecode_ExitMap(decode_ctx);
276
277 /* Exit top level array */
278 QCBORDecode_ExitArray(decode_ctx);
279
280 /* Finish and check for errors before using decoded values */
281 qcbor_err = QCBORDecode_Finish(decode_ctx);
282 if (qcbor_err != QCBOR_SUCCESS) {
283 return DPE_INVALID_COMMAND;
284 }
285
286 dpe_err = destroy_context_request(context_handle, destroy_recursively);
287 if (dpe_err != DPE_NO_ERROR) {
288 return dpe_err;
289 }
290
291 /* Encode response */
292 QCBOREncode_OpenArray(encode_ctx);
293 QCBOREncode_AddInt64(encode_ctx, DPE_NO_ERROR);
294 QCBOREncode_CloseArray(encode_ctx);
295
296 return DPE_NO_ERROR;
297}
298
Jamie Foxab30e712023-03-30 17:48:36 +0100299static dpe_error_t decode_certify_key(QCBORDecodeContext *decode_ctx,
300 QCBOREncodeContext *encode_ctx)
301{
302 QCBORError qcbor_err;
303 UsefulBufC out;
304 dpe_error_t dpe_err;
305 int context_handle;
306 bool retain_context;
307 const uint8_t *public_key;
308 size_t public_key_size;
309 const uint8_t *label;
310 size_t label_size;
Tamas Band0983e92024-01-25 16:32:51 +0100311 uint8_t *certificate_buf = REUSE_CMD_BUF(DICE_CERT_SIZE);
Maulik Patelcbded682023-12-07 11:50:16 +0000312 size_t certificate_actual_size;
Maulik Patele6adc112023-08-18 14:21:51 +0100313 uint8_t derived_public_key_buf[DPE_ATTEST_PUB_KEY_SIZE];
Jamie Foxab30e712023-03-30 17:48:36 +0100314 size_t derived_public_key_actual_size;
315 int new_context_handle;
316
317 /* Decode CertifyKey command */
318 QCBORDecode_EnterMap(decode_ctx, NULL);
319
320 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_CERTIFY_KEY_CONTEXT_HANDLE,
321 &out);
322 if (out.len != sizeof(context_handle)) {
323 return DPE_INVALID_COMMAND;
324 }
325 memcpy(&context_handle, out.ptr, out.len);
326
327 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_CERTIFY_KEY_RETAIN_CONTEXT,
328 &retain_context);
329
330 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_CERTIFY_KEY_PUBLIC_KEY,
331 &out);
332 public_key = out.ptr;
333 public_key_size = out.len;
334
335 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_CERTIFY_KEY_LABEL, &out);
336 label = out.ptr;
337 label_size = out.len;
338
339 QCBORDecode_ExitMap(decode_ctx);
340
341 /* Exit top level array */
342 QCBORDecode_ExitArray(decode_ctx);
343
344 /* Finish and check for errors before using decoded values */
345 qcbor_err = QCBORDecode_Finish(decode_ctx);
346 if (qcbor_err != QCBOR_SUCCESS) {
347 return DPE_INVALID_COMMAND;
348 }
349
Maulik Patele6adc112023-08-18 14:21:51 +0100350 dpe_err = certify_key_request(context_handle, retain_context, public_key,
351 public_key_size, label, label_size,
Maulik Patelcbded682023-12-07 11:50:16 +0000352 certificate_buf,
Tamas Band0983e92024-01-25 16:32:51 +0100353 DICE_CERT_SIZE,
Maulik Patelcbded682023-12-07 11:50:16 +0000354 &certificate_actual_size,
Maulik Patele6adc112023-08-18 14:21:51 +0100355 derived_public_key_buf,
356 sizeof(derived_public_key_buf),
357 &derived_public_key_actual_size,
358 &new_context_handle);
Jamie Foxab30e712023-03-30 17:48:36 +0100359 if (dpe_err != DPE_NO_ERROR) {
360 return dpe_err;
361 }
362
363 /* Encode response */
364 QCBOREncode_OpenArray(encode_ctx);
365 QCBOREncode_AddInt64(encode_ctx, DPE_NO_ERROR);
366
367 QCBOREncode_OpenMap(encode_ctx);
368
369 /* The certificate chain is already encoded into a CBOR array by the certify
370 * key implementation. Add it as a byte string so that its decoding can be
371 * skipped and the CBOR returned to the caller.
372 */
Maulik Patelcbded682023-12-07 11:50:16 +0000373 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_CERTIFY_KEY_CERTIFICATE,
374 (UsefulBufC){ certificate_buf,
375 certificate_actual_size });
Jamie Foxab30e712023-03-30 17:48:36 +0100376
377 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_CERTIFY_KEY_DERIVED_PUBLIC_KEY,
378 (UsefulBufC){ derived_public_key_buf,
379 derived_public_key_actual_size });
380 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_CERTIFY_KEY_NEW_CONTEXT_HANDLE,
381 (UsefulBufC){ &new_context_handle,
382 sizeof(new_context_handle) });
383
384 QCBOREncode_CloseMap(encode_ctx);
385
386 QCBOREncode_CloseArray(encode_ctx);
387
388 return DPE_NO_ERROR;
389}
390
Maulik Patel83a6b592023-12-05 15:20:30 +0000391static dpe_error_t decode_get_certificate_chain(QCBORDecodeContext *decode_ctx,
392 QCBOREncodeContext *encode_ctx)
393{
394 QCBORError qcbor_err;
395 UsefulBufC out;
396 dpe_error_t dpe_err;
397 int context_handle;
398 bool retain_context;
399 bool clear_from_context;
Tamas Band0983e92024-01-25 16:32:51 +0100400 uint8_t *certificate_chain_buf = REUSE_CMD_BUF(DICE_CERT_CHAIN_SIZE);
Maulik Patel83a6b592023-12-05 15:20:30 +0000401 size_t certificate_chain_actual_size;
402 int new_context_handle;
403
404 /* Decode GetCertificateChain command */
405 QCBORDecode_EnterMap(decode_ctx, NULL);
406
407 QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_GET_CERTIFICATE_CHAIN_CONTEXT_HANDLE,
408 &out);
409 if (out.len != sizeof(context_handle)) {
410 return DPE_INVALID_COMMAND;
411 }
412 memcpy(&context_handle, out.ptr, out.len);
413
414 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_GET_CERTIFICATE_CHAIN_RETAIN_CONTEXT,
415 &retain_context);
416
417 QCBORDecode_GetBoolInMapN(decode_ctx, DPE_GET_CERTIFICATE_CHAIN_CLEAR_FROM_CONTEXT,
418 &clear_from_context);
419
420 QCBORDecode_ExitMap(decode_ctx);
421
422 /* Exit top level array */
423 QCBORDecode_ExitArray(decode_ctx);
424
425 /* Finish and check for errors before using decoded values */
426 qcbor_err = QCBORDecode_Finish(decode_ctx);
427 if (qcbor_err != QCBOR_SUCCESS) {
428 return DPE_INVALID_COMMAND;
429 }
430
431 dpe_err = get_certificate_chain_request(context_handle,
432 retain_context,
433 clear_from_context,
434 certificate_chain_buf,
Tamas Band0983e92024-01-25 16:32:51 +0100435 DICE_CERT_CHAIN_SIZE,
Maulik Patel83a6b592023-12-05 15:20:30 +0000436 &certificate_chain_actual_size,
437 &new_context_handle);
438 if (dpe_err != DPE_NO_ERROR) {
439 return dpe_err;
440 }
441
442 /* Encode response */
443 QCBOREncode_OpenArray(encode_ctx);
444 QCBOREncode_AddInt64(encode_ctx, DPE_NO_ERROR);
445
446 QCBOREncode_OpenMap(encode_ctx);
447
448 /* The certificate chain is already encoded into a CBOR array by the get certificate
449 * chain implementation. Add it as a byte string so that its decoding can be
450 * skipped and the CBOR returned to the caller.
451 */
452 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_GET_CERTIFICATE_CHAIN_CERTIFICATE_CHAIN,
453 (UsefulBufC){ certificate_chain_buf,
454 certificate_chain_actual_size });
455
456 QCBOREncode_AddBytesToMapN(encode_ctx, DPE_GET_CERTIFICATE_CHAIN_NEW_CONTEXT_HANDLE,
457 (UsefulBufC){ &new_context_handle,
458 sizeof(new_context_handle) });
459
460 QCBOREncode_CloseMap(encode_ctx);
461
462 QCBOREncode_CloseArray(encode_ctx);
463
464 return DPE_NO_ERROR;
465}
466
Jamie Foxab30e712023-03-30 17:48:36 +0100467static void encode_error_only(QCBOREncodeContext *encode_ctx,
468 dpe_error_t dpe_err)
469{
470 QCBOREncode_OpenArray(encode_ctx);
471 QCBOREncode_AddInt64(encode_ctx, dpe_err);
472 QCBOREncode_CloseArray(encode_ctx);
473}
474
475int32_t dpe_command_decode(int32_t client_id,
476 const char *cmd_input, size_t cmd_input_size,
477 char *cmd_output, size_t *cmd_output_size)
478{
479 dpe_error_t dpe_err;
480 QCBORError qcbor_err;
481 QCBORDecodeContext decode_ctx;
482 QCBOREncodeContext encode_ctx;
483 UsefulBufC out;
484 uint64_t command_id;
485
486 QCBORDecode_Init(&decode_ctx, (UsefulBufC){ cmd_input, cmd_input_size },
487 QCBOR_DECODE_MODE_NORMAL);
488 QCBOREncode_Init(&encode_ctx, (UsefulBuf){ cmd_output, *cmd_output_size });
489
490 /* Enter top level array */
491 QCBORDecode_EnterArray(&decode_ctx, NULL);
492
493 /* Get the command ID */
494 QCBORDecode_GetUInt64(&decode_ctx, &command_id);
495
496 /* Check for errors before interpreting the decoded command ID */
497 qcbor_err = QCBORDecode_GetError(&decode_ctx);
498
499 if (qcbor_err == QCBOR_SUCCESS) {
500 switch (command_id) {
Maulik Patela81605b2023-10-24 12:17:03 +0100501 case DPE_DERIVE_CONTEXT:
502 dpe_err = decode_derive_context(&decode_ctx, &encode_ctx, client_id);
Jamie Foxab30e712023-03-30 17:48:36 +0100503 break;
504 case DPE_CERTIFY_KEY:
505 dpe_err = decode_certify_key(&decode_ctx, &encode_ctx);
506 break;
Maulik Patel83a6b592023-12-05 15:20:30 +0000507 case DPE_GET_CERTIFICATE_CHAIN:
508 dpe_err = decode_get_certificate_chain(&decode_ctx, &encode_ctx);
509 break;
Maulik Patel54d65f72023-06-28 13:04:36 +0100510 case DPE_DESTROY_CONTEXT:
511 dpe_err = decode_destroy_context(&decode_ctx, &encode_ctx);
512 break;
Jamie Foxab30e712023-03-30 17:48:36 +0100513 default:
514 dpe_err = DPE_INVALID_COMMAND;
515 break;
516 }
517 } else {
518 dpe_err = DPE_INVALID_COMMAND;
519 }
520
521 /* If an unhandled DPE error was returned, then encode it into a response */
522 if (dpe_err != DPE_NO_ERROR) {
523 encode_error_only(&encode_ctx, dpe_err);
524 }
525
526 qcbor_err = QCBOREncode_Finish(&encode_ctx, &out);
527 if (qcbor_err != QCBOR_SUCCESS) {
528 return -1;
529 }
530
531 *cmd_output_size = out.len;
532
533 return 0;
534}