From 8521459c18dd4d2800f98e0e35ed9a83adf0cc27 Mon Sep 17 00:00:00 2001 From: Tommy Chiu Date: Fri, 20 Sep 2024 14:05:49 +0800 Subject: [PATCH] [dice] Add CWT COSE_Key implementation for Uds_pub For dice_lib to support different formats including X509 and CWT(CBOR). Bug: 356532759 Bug: lowRISC/opentitan:#24281 Test: ft_provision_dice_cwt_fpga_cw340_rom_with_fake_keys Signed-off-by: Tommy Chiu (cherry picked from commit fbe88bb7234dc4569bff3e7b9d7e4c6bfdf8301f) --- sw/device/silicon_creator/lib/cert/BUILD | 11 +++ sw/device/silicon_creator/lib/cert/cbor.h | 69 +++++++++++++++++++ sw/device/silicon_creator/lib/cert/dice_cwt.c | 44 +++++++++++- 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 sw/device/silicon_creator/lib/cert/cbor.h diff --git a/sw/device/silicon_creator/lib/cert/BUILD b/sw/device/silicon_creator/lib/cert/BUILD index 8a09b0e3b0a3d0..7296ea6ad66f21 100644 --- a/sw/device/silicon_creator/lib/cert/BUILD +++ b/sw/device/silicon_creator/lib/cert/BUILD @@ -112,11 +112,22 @@ cc_library( ], ) +cc_library( + name = "cbor", + hdrs = ["cbor.h"], + deps = [ + "//sw/device/lib/base:status", + "//sw/device/lib/runtime:log", + "@open-dice//:cbor_reader_writer", + ], +) + cc_library( name = "dice_cwt", srcs = ["dice_cwt.c"], hdrs = ["dice.h"], deps = [ + ":cbor", ":cert", "//hw/ip/otp_ctrl/data:otp_ctrl_c_regs", "//sw/device/lib/base:status", diff --git a/sw/device/silicon_creator/lib/cert/cbor.h b/sw/device/silicon_creator/lib/cert/cbor.h new file mode 100644 index 00000000000000..99328287b25475 --- /dev/null +++ b/sw/device/silicon_creator/lib/cert/cbor.h @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_CERT_CBOR_H_ +#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_CERT_CBOR_H_ + +#include "include/dice/cbor_writer.h" +#include "sw/device/lib/runtime/log.h" +#include "sw/device/silicon_creator/lib/error.h" + +#define CBOR_CHECK_OVERFLOWED_AND_RETURN(p) \ + do { \ + if (CborOutOverflowed(p)) { \ + LOG_ERROR("CborOutOverflowed!!"); \ + return kErrorCertInvalidSize; \ + } \ + return kErrorOk; \ + } while (0) + +// Wrappers for each CBOR type and CBOR handle initialization +static inline rom_error_t cbor_write_out_init(struct CborOut *p, void *buf, + const size_t buf_size) { + CborOutInit(buf, buf_size, p); + CBOR_CHECK_OVERFLOWED_AND_RETURN(p); +} + +static inline rom_error_t cbor_map_init(struct CborOut *p, + const size_t num_pairs) { + CborWriteMap(num_pairs, p); + CBOR_CHECK_OVERFLOWED_AND_RETURN(p); +} + +// Wrappers to encode a pair of data for cbor-map +static inline rom_error_t cbor_write_pair_uint_uint(struct CborOut *p, + uint64_t key, + uint64_t value) { + CborWriteUint(key, p); + CborWriteUint(value, p); + CBOR_CHECK_OVERFLOWED_AND_RETURN(p); +} + +static inline rom_error_t cbor_write_pair_int_uint(struct CborOut *p, + int64_t key, + uint64_t value) { + CborWriteInt(key, p); + CborWriteUint(value, p); + CBOR_CHECK_OVERFLOWED_AND_RETURN(p); +} + +static inline rom_error_t cbor_write_pair_uint_int(struct CborOut *p, + uint64_t key, + int64_t value) { + CborWriteUint(key, p); + CborWriteInt(value, p); + CBOR_CHECK_OVERFLOWED_AND_RETURN(p); +} + +static inline rom_error_t cbor_write_pair_int_bytes(struct CborOut *p, + int64_t key, uint8_t *value, + size_t value_size) { + CborWriteInt(key, p); + CborWriteBstr(value_size, value, p); + CBOR_CHECK_OVERFLOWED_AND_RETURN(p); +} + +#undef CBOR_CHECK_OVERFLOWED_AND_RETURN + +#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_CERT_CBOR_H_ diff --git a/sw/device/silicon_creator/lib/cert/dice_cwt.c b/sw/device/silicon_creator/lib/cert/dice_cwt.c index d56e9e7e7b5525..45377b806a5d11 100644 --- a/sw/device/silicon_creator/lib/cert/dice_cwt.c +++ b/sw/device/silicon_creator/lib/cert/dice_cwt.c @@ -2,11 +2,10 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 -#include "sw/device/silicon_creator/lib/cert/dice.h" - #include #include "sw/device/lib/base/memory.h" +#include "sw/device/silicon_creator/lib/cert/cbor.h" #include "sw/device/silicon_creator/lib/cert/cert.h" #include "sw/device/silicon_creator/lib/cert/dice.h" #include "sw/device/silicon_creator/lib/drivers/hmac.h" @@ -18,6 +17,18 @@ #include "otp_ctrl_regs.h" // Generated. +// Keys +const int64_t kCoseKeyKtyLabel = 1; +const int64_t kCoseKeyAlgLabel = 3; +const int64_t kCoseEc2CrvLabel = -1; +const int64_t kCoseEc2XLabel = -2; +const int64_t kCoseEc2YLabel = -3; + +// Values +const int64_t kCoseKeyAlgEcdsa256 = -7; +const int64_t kCoseEc2CrvP256 = 1; +const int64_t kCoseKeyKtyEc2 = 2; + // UDS (Creator) attestation key diverisfier constants. // Note: versions are always set to 0 so these keys are always valid from the // perspective of the keymgr hardware. @@ -85,10 +96,37 @@ const sc_keymgr_ecc_key_t kDiceKeyCdi1 = { .required_keymgr_state = kScKeymgrStateOwnerKey, }; - +// PubKeyECDSA256 = { ; COSE_Key [RFC9052 s7] +// 1 : 2, ; Key type : EC2 +// 3 : AlgorithmES256, ; Algorithm : ECDSA w/ SHA-256 +// -1 : 1, ; Curve: P256 +// -2 : bstr, ; X coordinate, big-endian +// -3 : bstr ; Y coordinate, big-endian +// } rom_error_t dice_uds_tbs_cert_build(cert_key_id_pair_t *key_ids, ecdsa_p256_public_key_t *uds_pubkey, uint8_t *tbs_cert, size_t *tbs_cert_size) { + struct CborOut kCborOutHandle; + + struct CborOut *pCborOut = &kCborOutHandle; + + HARDENED_RETURN_IF_ERROR( + cbor_write_out_init(pCborOut, tbs_cert, *tbs_cert_size)); + HARDENED_RETURN_IF_ERROR(cbor_map_init(pCborOut, 5)); + HARDENED_RETURN_IF_ERROR( + cbor_write_pair_uint_uint(pCborOut, kCoseKeyKtyLabel, kCoseKeyKtyEc2)); + HARDENED_RETURN_IF_ERROR(cbor_write_pair_uint_int(pCborOut, kCoseKeyAlgLabel, + kCoseKeyAlgEcdsa256)); + HARDENED_RETURN_IF_ERROR( + cbor_write_pair_int_uint(pCborOut, kCoseEc2CrvLabel, kCoseEc2CrvP256)); + HARDENED_RETURN_IF_ERROR(cbor_write_pair_int_bytes(pCborOut, kCoseEc2XLabel, + (uint8_t *)uds_pubkey->x, + sizeof(uds_pubkey->x))); + HARDENED_RETURN_IF_ERROR(cbor_write_pair_int_bytes(pCborOut, kCoseEc2YLabel, + (uint8_t *)uds_pubkey->y, + sizeof(uds_pubkey->y))); + *tbs_cert_size = CborOutSize(pCborOut); + return kErrorOk; }