in core/asn1/dice/x509_extension_builder_mbedtls_dice_tcbinfo.c [27:156]
int x509_extension_builder_mbedtls_dice_tcbinfo_create_extension (
const struct x509_extension_builder_mbedtls_dice_tcbinfo *dice, uint8_t *buffer, size_t length,
struct x509_extension *extension)
{
uint8_t *pos;
int enc_length = 0;
mbedtls_mpi svn;
int fwid_length;
char *fwid_oid;
size_t fwid_oid_length;
int ret;
if (dice->tcb == NULL) {
return DICE_TCBINFO_EXTENSION_INVALID_ARGUMENT;
}
if (dice->tcb->version == NULL) {
return DICE_TCBINFO_EXTENSION_NO_VERSION;
}
if ((dice->tcb->svn == NULL) || (dice->tcb->svn_length == 0)) {
return DICE_TCBINFO_EXTENSION_NO_SVN;
}
if (dice->tcb->fwid == NULL) {
return DICE_TCBINFO_EXTENSION_NO_FWID;
}
switch (dice->tcb->fwid_hash) {
case HASH_TYPE_SHA1:
fwid_length = SHA1_HASH_LENGTH;
fwid_oid = MBEDTLS_OID_DIGEST_ALG_SHA1;
fwid_oid_length = MBEDTLS_OID_SIZE (MBEDTLS_OID_DIGEST_ALG_SHA1);
break;
case HASH_TYPE_SHA256:
fwid_length = SHA256_HASH_LENGTH;
fwid_oid = MBEDTLS_OID_DIGEST_ALG_SHA256;
fwid_oid_length = MBEDTLS_OID_SIZE (MBEDTLS_OID_DIGEST_ALG_SHA256);
break;
case HASH_TYPE_SHA384:
fwid_length = SHA384_HASH_LENGTH;
fwid_oid = MBEDTLS_OID_DIGEST_ALG_SHA384;
fwid_oid_length = MBEDTLS_OID_SIZE (MBEDTLS_OID_DIGEST_ALG_SHA384);
break;
case HASH_TYPE_SHA512:
fwid_length = SHA512_HASH_LENGTH;
fwid_oid = MBEDTLS_OID_DIGEST_ALG_SHA512;
fwid_oid_length = MBEDTLS_OID_SIZE (MBEDTLS_OID_DIGEST_ALG_SHA512);
break;
default:
return DICE_TCBINFO_EXTENSION_UNKNOWN_FWID;
}
pos = buffer + length;
/* fwids Fwids OPTIONAL */
/* fwid OCTET_STRING */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_raw_buffer (&pos, buffer, dice->tcb->fwid, fwid_length));
ret = x509_mbedtls_close_asn1_object (&pos, buffer, MBEDTLS_ASN1_OCTET_STRING, &enc_length);
if (ret != 0) {
return ret;
}
/* hashAlg OBJECT IDENTIFIER */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_oid (&pos, buffer, fwid_oid, fwid_oid_length));
/* fwid SEQUENCE */
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), &enc_length);
if (ret != 0) {
return ret;
}
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 6), &enc_length);
if (ret != 0) {
return ret;
}
/* svn INTEGER OPTIONAL */
/* mbedtls_asn1_write_int only writes 1 byte integers. MPI is needed for larger ones. */
mbedtls_mpi_init (&svn);
ret = mbedtls_mpi_read_binary (&svn, dice->tcb->svn, dice->tcb->svn_length);
if (ret != 0) {
if (ret == MBEDTLS_ERR_MPI_ALLOC_FAILED) {
ret = DICE_TCBINFO_EXTENSION_NO_MEMORY;
}
return ret;
}
ret = mbedtls_asn1_write_mpi (&pos, buffer, &svn);
mbedtls_mpi_free (&svn);
if (ret < 0) {
return ret;
}
enc_length += ret;
*pos = (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 3);
/* version IA5String OPTIONAL */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_ia5_string (&pos, buffer, dice->tcb->version,
strlen (dice->tcb->version)));
*pos = (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2);
/* DiceTcbInfo ::= SEQUENCE */
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), &enc_length);
if (ret != 0) {
return ret;
}
if (pos != buffer) {
memmove (buffer, pos, enc_length);
}
x509_extension_builder_init_extension_descriptor (extension, false,
X509_EXTENSION_BUILDER_DICE_TCBINFO_OID, X509_EXTENSION_BUILDER_DICE_TCBINFO_OID_LENGTH,
buffer, enc_length);
return 0;
}