5 #include "sw/device/silicon_creator/manuf/base/perso_tlv_data.h"
7 #include "sw/device/silicon_creator/lib/cert/cert.h"
8 #include "sw/device/silicon_creator/lib/error.h"
10 rom_error_t perso_tlv_get_cert_obj(uint8_t *buf,
size_t ltv_buf_size,
12 perso_tlv_object_header_t objh;
13 perso_tlv_object_type_t obj_type;
17 if (ltv_buf_size <
sizeof(perso_tlv_object_header_t)) {
18 return kErrorPersoTlvInternal;
21 memcpy(&objh, buf,
sizeof(perso_tlv_object_header_t));
23 PERSO_TLV_GET_FIELD(Objh, Size, objh, &obj_size);
25 return kErrorPersoTlvCertObjNotFound;
26 if (obj_size > ltv_buf_size)
27 return kErrorPersoTlvInternal;
30 PERSO_TLV_GET_FIELD(Objh, Type, objh, &obj_type);
32 if (obj_type != kPersoObjectTypeX509Cert &&
33 obj_type != kPersoObjectTypeCwtCert) {
34 return kErrorPersoTlvCertObjNotFound;
36 buf +=
sizeof(perso_tlv_object_header_t);
37 ltv_buf_size -=
sizeof(perso_tlv_object_header_t);
42 perso_tlv_cert_header_t crth;
43 uint16_t wrapped_cert_size;
48 if (ltv_buf_size <
sizeof(perso_tlv_cert_header_t)) {
49 return kErrorPersoTlvInternal;
51 memcpy(&crth, buf,
sizeof(perso_tlv_cert_header_t));
53 PERSO_TLV_GET_FIELD(Crth, NameSize, crth, &name_len);
55 PERSO_TLV_GET_FIELD(Crth, Size, crth, &wrapped_cert_size);
58 if ((wrapped_cert_size < (
sizeof(perso_tlv_cert_header_t) + name_len + 4)) ||
59 (wrapped_cert_size > ltv_buf_size))
60 return kErrorPersoTlvInternal;
61 buf +=
sizeof(perso_tlv_cert_header_t);
62 ltv_buf_size -=
sizeof(perso_tlv_cert_header_t);
64 if (ltv_buf_size < name_len) {
65 return kErrorPersoTlvInternal;
68 obj->
name[name_len] =
'\0';
70 ltv_buf_size -= name_len;
73 wrapped_cert_size -
sizeof(perso_tlv_cert_header_t) - name_len;
78 if (obj_type == kPersoObjectTypeX509Cert) {
79 size_t decoded_cert_size =
80 cert_x509_asn1_decode_size_header(obj->
cert_body_p);
82 return kErrorPersoTlvInternal;
89 rom_error_t perso_tlv_cert_obj_build(
const char *name,
90 const perso_tlv_object_type_t obj_type,
91 const uint8_t *cert,
size_t cert_size,
92 uint8_t *buf,
size_t *buf_size) {
93 perso_tlv_object_header_t obj_header = 0;
94 perso_tlv_cert_header_t cert_header = 0;
96 size_t wrapped_cert_size;
100 while (name[name_len])
102 if (name_len > kCrthNameSizeFieldMask)
103 return kErrorPersoTlvCertNameTooLong;
107 wrapped_cert_size =
sizeof(perso_tlv_cert_header_t) + name_len + cert_size;
108 obj_size = wrapped_cert_size +
sizeof(perso_tlv_object_header_t);
111 if (obj_size > *buf_size)
112 return kErrorPersoTlvOutputBufTooSmall;
115 PERSO_TLV_SET_FIELD(Objh, Type, obj_header, obj_type);
116 PERSO_TLV_SET_FIELD(Objh, Size, obj_header, obj_size);
119 PERSO_TLV_SET_FIELD(Crth, Size, cert_header, wrapped_cert_size);
120 PERSO_TLV_SET_FIELD(Crth, NameSize, cert_header, name_len);
125 memcpy(buf + *buf_size, &obj_header,
sizeof(perso_tlv_object_header_t));
126 *buf_size +=
sizeof(perso_tlv_object_header_t);
127 memcpy(buf + *buf_size, &cert_header,
sizeof(perso_tlv_cert_header_t));
128 *buf_size +=
sizeof(perso_tlv_cert_header_t);
129 memcpy(buf + *buf_size, name, name_len);
130 *buf_size += name_len;
131 memcpy(buf + *buf_size, cert, cert_size);
132 *buf_size += cert_size;
137 rom_error_t perso_tlv_push_cert_to_perso_blob(
138 const char *name,
bool needs_endorsement,
139 const dice_cert_format_t dice_format,
const uint8_t *cert,
size_t cert_size,
141 if (pb->next_free >
sizeof(pb->body)) {
142 return kErrorPersoTlvInternal;
145 size_t obj_size =
sizeof(pb->body) - pb->next_free;
146 perso_tlv_object_type_t obj_type = kPersoObjectTypeCwtCert;
147 if (dice_format == kDiceCertFormatX509TcbInfo) {
148 if (needs_endorsement) {
149 obj_type = kPersoObjectTypeX509Tbs;
151 obj_type = kPersoObjectTypeX509Cert;
154 HARDENED_RETURN_IF_ERROR(perso_tlv_cert_obj_build(
155 name, obj_type, cert, cert_size, pb->body + pb->next_free, &obj_size));
158 pb->next_free += obj_size;
164 rom_error_t perso_tlv_push_to_perso_blob(
const void *data,
size_t size,
165 perso_blob_t *perso_blob) {
166 if (perso_blob->next_free >
sizeof(perso_blob->body)) {
167 return kErrorPersoTlvInternal;
169 size_t room =
sizeof(perso_blob->body) - perso_blob->next_free;
171 return kErrorPersoTlvOutputBufTooSmall;
172 memcpy(perso_blob->body + perso_blob->next_free, data, size);
173 perso_blob->next_free += size;