Create extension builders and DME structure handlers to construct a DME extension.

The contents vary based on structure format, key size, and optional fields, but the DME extension structure is fixed.  The DME extension builders are set up to create a DME extension for any arbitrary DME key and structure based on an abstracted set of pointers.  Individual DME implementations will provide appropriate data to the generic extension builder.

Handlers for the currently defined DME structure formats have been added.  These handlers will take input from boot code to populate the generic structure for inclusion in a DME extension.

In addition, some clean-up was performed on the existing DICE extension builders:
- Fixed errors in comments.
- Better dynamic buffer size management for TcbInfo extension.
- Refactored some shared ASN.1 build functions for mbedtls and openssl that are used by both X.509 and extension builders.
- Cleaned up some formatting.
This commit is contained in:
Christopher Weimer 2023-07-20 21:10:53 +00:00
Родитель 77da5bd897
Коммит 3a09ea17fd
45 изменённых файлов: 8573 добавлений и 102 удалений

47
core/asn1/asn1_oid.c Normal file
Просмотреть файл

@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include "asn1_oid.h"
/**
* AlgorithmIdentifier OID for an ECDSA signature using SHA2-256.
*
* 1.2.840.10045.4.3.2
*/
const uint8_t ASN1_OID_ECDSA_WITH_SHA256[] = {
0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02
};
/**
* Length of the ecdsa-with-SHA256 OID.
*/
const size_t ASN1_OID_ECDSA_WITH_SHA256_LENGTH = sizeof (ASN1_OID_ECDSA_WITH_SHA256);
/**
* AlgorithmIdentifier OID for an ECDSA signature using SHA2-384.
*
* 1.2.840.10045.4.3.3
*/
const uint8_t ASN1_OID_ECDSA_WITH_SHA384[] = {
0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x03
};
/**
* Length of the ecdsa-with-SHA384 OID.
*/
const size_t ASN1_OID_ECDSA_WITH_SHA384_LENGTH = sizeof (ASN1_OID_ECDSA_WITH_SHA384);
/**
* AlgorithmIdentifier OID for an ECDSA signature using SHA2-512.
*
* 1.2.840.10045.4.3.4
*/
const uint8_t ASN1_OID_ECDSA_WITH_SHA512[] = {
0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x04
};
/**
* Length of the ecdsa-with-SHA512 OID.
*/
const size_t ASN1_OID_ECDSA_WITH_SHA512_LENGTH = sizeof (ASN1_OID_ECDSA_WITH_SHA512);

22
core/asn1/asn1_oid.h Normal file
Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef ASN1_OID_H_
#define ASN1_OID_H_
#include <stdint.h>
#include <stddef.h>
/* AlgorithmIdentifier OIDs */
extern const uint8_t ASN1_OID_ECDSA_WITH_SHA256[];
extern const size_t ASN1_OID_ECDSA_WITH_SHA256_LENGTH;
extern const uint8_t ASN1_OID_ECDSA_WITH_SHA384[];
extern const size_t ASN1_OID_ECDSA_WITH_SHA384_LENGTH;
extern const uint8_t ASN1_OID_ECDSA_WITH_SHA512[];
extern const size_t ASN1_OID_ECDSA_WITH_SHA512_LENGTH;
#endif /* ASN1_OID_H_ */

Просмотреть файл

@ -25,12 +25,6 @@
*/
#define X509_EXTENSION_BUILDER_DICE_TCBINFO_BUFFER_PADDING 32
/**
* Buffer space to allocate for dynamic extension buffers.
*/
#define X509_EXTENSION_BUILDER_DICE_TCBINFO_DATA_LENGTH \
(256 + X509_EXTENSION_BUILDER_DICE_TCBINFO_BUFFER_PADDING)
/**
* The encoded OID for the TCG DICE TcbInfo extension: 2.23.133.5.4.1
@ -39,6 +33,12 @@ const uint8_t X509_EXTENSION_BUILDER_DICE_TCBINFO_OID[] = {
0x67,0x81,0x05,0x05,0x04,0x01
};
/**
* Length of the encoded TCG DICE TcbInfo extension OID.
*/
const size_t X509_EXTENSION_BUILDER_DICE_TCBINFO_OID_LENGTH =
sizeof (X509_EXTENSION_BUILDER_DICE_TCBINFO_OID);
/**
* Create the TCG DICE TcbInfo extension.
@ -133,7 +133,8 @@ int x509_extension_builder_dice_tcbinfo_build_dynamic (const struct x509_extensi
return DICE_TCBINFO_EXTENSION_INVALID_ARGUMENT;
}
length = X509_EXTENSION_BUILDER_DICE_TCBINFO_DATA_LENGTH;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (dice->tcb) +
X509_EXTENSION_BUILDER_DICE_TCBINFO_BUFFER_PADDING;
buffer = platform_malloc (length);
if (buffer == NULL) {
return DICE_TCBINFO_EXTENSION_NO_MEMORY;
@ -247,3 +248,33 @@ void x509_extension_builder_dice_tcbinfo_release (
{
UNUSED (builder);
}
/**
* Determine an appropriately sized buffer to use for TCG DICE TcbInfo extension building based on
* the TCB information. This is not an exact extension length, but will provide sufficient space to
* fit the encoded extension.
*
* @param tcb The TCG DICE TCB information that will be encoded into an extension.
*
* @return The buffer length needed for the TCG DICE TcbInfo extension.
*/
size_t x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (
const struct tcg_dice_tcbinfo *tcb)
{
size_t length = 4; /* Space for the top-level sequence header. */
if (tcb != NULL) {
if (tcb->version != NULL) {
length += strlen (tcb->version);
}
length += sizeof (tcb->svn);
length += 9; /* Worst-case FWID OID length. */
length += SHA512_HASH_LENGTH; /* Worst-case FWID length */
/* Extra space for headers and sequence tags. */
length += (4 * 4) + (4 * 2);
}
return length;
}

Просмотреть файл

@ -16,7 +16,7 @@ struct x509_extension_builder_dice_tcbinfo {
struct x509_extension_builder base; /**< Base extension builder API. */
const struct tcg_dice_tcbinfo *tcb; /**< The TCB information to encode in the extension. */
uint8_t *ext_buffer; /**< Buffer to use for building the extension data. */
size_t ext_length; /**< Length of th extension data duffer. */
size_t ext_length; /**< Length of the extension data duffer. */
};
@ -28,14 +28,13 @@ int x509_extension_builder_dice_tcbinfo_init_with_buffer (
void x509_extension_builder_dice_tcbinfo_release (
const struct x509_extension_builder_dice_tcbinfo *builder);
size_t x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (
const struct tcg_dice_tcbinfo *tcb);
/* Internal definitions for use by Ueid extension builders. */
/* Internal definitions for use by TcbInfo extension builders. */
extern const uint8_t X509_EXTENSION_BUILDER_DICE_TCBINFO_OID[];
/**
* Length of the encoded TCG DICE Ueid extension OID.
*/
#define X509_EXTENSION_BUILDER_DICE_TCBINFO_OID_LENGTH 6
extern const size_t X509_EXTENSION_BUILDER_DICE_TCBINFO_OID_LENGTH;
#define DICE_TCBINFO_EXTENSION_ERROR(code) ROT_ERROR (ROT_MODULE_DICE_TCBINFO_EXTENSION, code)

Просмотреть файл

@ -42,9 +42,8 @@ void x509_extension_builder_dice_tcbinfo_free_static (const struct x509_extensio
*
* There is no validation done on the arguments.
*
* @param tcb_ptr The device unique identifier that should be encoded in the extension. This
* does not need to be constant. The contents can be updated at run-time to affect what will be
* encoded in the extension.
* @param tcb_ptr The firmware TCB to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
*/
#define x509_extension_builder_dice_tcbinfo_static_init(tcb_ptr) { \
.base = X509_EXTENSION_BUILDER_DICE_TCBINFO_DYNAMIC_API_INIT, \
@ -59,9 +58,8 @@ void x509_extension_builder_dice_tcbinfo_free_static (const struct x509_extensio
*
* There is no validation done on the arguments.
*
* @param tcb_ptr The device unique identifier that should be encoded in the extension. This
* does not need to be constant. The contents can be updated at run-time to affect what will be
* encoded in the extension.
* @param tcb_ptr The firmware TCB to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
* @param ext_buffer_ptr Buffer for the encoded TcbInfo extension data.
* @param buffer_length Length of the extension data buffer.
*/

Просмотреть файл

@ -25,6 +25,12 @@ const uint8_t X509_EXTENSION_BUILDER_DICE_UEID_OID[] = {
0x67,0x81,0x05,0x05,0x04,0x04
};
/**
* Length of the encoded TCG DICE Ueid extension OID.
*/
const size_t X509_EXTENSION_BUILDER_DICE_UEID_OID_LENGTH =
sizeof (X509_EXTENSION_BUILDER_DICE_UEID_OID);
/**
* Create the TCG DICE Ueid extension.

Просмотреть файл

@ -33,7 +33,7 @@ struct x509_extension_builder_dice_ueid {
const uint8_t *ueid; /**< The UEID to encode in the extension. */
size_t ueid_length; /**< Length of the UEID. */
uint8_t *ext_buffer; /**< Buffer to use for building the extension data. */
size_t ext_length; /**< Length of th extension data duffer. */
size_t ext_length; /**< Length of the extension data duffer. */
};
@ -48,11 +48,7 @@ void x509_extension_builder_dice_ueid_release (
/* Internal definitions for use by Ueid extension builders. */
extern const uint8_t X509_EXTENSION_BUILDER_DICE_UEID_OID[];
/**
* Length of the encoded TCG DICE Ueid extension OID.
*/
#define X509_EXTENSION_BUILDER_DICE_UEID_OID_LENGTH 6
extern const size_t X509_EXTENSION_BUILDER_DICE_UEID_OID_LENGTH;
#define DICE_UEID_EXTENSION_ERROR(code) ROT_ERROR (ROT_MODULE_DICE_UEID_EXTENSION, code)

Просмотреть файл

@ -7,41 +7,13 @@
#include "platform_api.h"
#include "x509_extension_builder_dice_tcbinfo.h"
#include "x509_extension_builder_mbedtls_dice_tcbinfo.h"
#include "asn1/x509_mbedtls.h"
#include "common/unused.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/bignum.h"
#include "mbedtls/oid.h"
/**
* Buffer space to allocate for dynamic extension buffers.
*/
#define X509_EXTENSION_BUILDER_MBEDTLS_DICE_TCBINFO_DATA_LENGTH 256
/**
* Write the ASN.1 header to an object.
*
* TODO: Perhaps there should be a common set of mbedTLS ASN.1 utility functions?
*
* @param pos The current buffer position.
* @param start The start of the buffer.
* @param tag The object tag to write.
* @param length The length of the object, updated with the header length.
*
* @return 0 if the object header was written or an error code.
*/
static int x509_extension_builder_mbedtls_dice_tcbinfo_close_asn1_object (uint8_t **pos,
uint8_t *start, uint8_t tag, size_t *length)
{
int ret;
MBEDTLS_ASN1_CHK_ADD (*length, mbedtls_asn1_write_len (pos, start, *length));
MBEDTLS_ASN1_CHK_ADD (*length, mbedtls_asn1_write_tag (pos, start, tag));
return 0;
}
/**
* Create the TCG DICE TcbInfo extension.
*
@ -57,7 +29,7 @@ int x509_extension_builder_mbedtls_dice_tcbinfo_create_extension (
struct x509_extension *extension)
{
uint8_t *pos;
size_t enc_length = 0;
int enc_length = 0;
mbedtls_mpi svn;
uint32_t be_svn;
int fwid_length;
@ -111,26 +83,25 @@ int x509_extension_builder_mbedtls_dice_tcbinfo_create_extension (
/* 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_extension_builder_mbedtls_dice_tcbinfo_close_asn1_object (&pos, buffer,
MBEDTLS_ASN1_OCTET_STRING, &enc_length);
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));
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_oid (&pos, buffer, fwid_oid, fwid_oid_length));
/* fwid SEQUENCE */
ret = x509_extension_builder_mbedtls_dice_tcbinfo_close_asn1_object (&pos, buffer,
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), &enc_length);
if (ret != 0) {
return ret;
}
ret = x509_extension_builder_mbedtls_dice_tcbinfo_close_asn1_object (&pos, buffer,
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 6), &enc_length);
if (ret != 0) {
return ret;
@ -159,12 +130,13 @@ int x509_extension_builder_mbedtls_dice_tcbinfo_create_extension (
*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)));
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_extension_builder_mbedtls_dice_tcbinfo_close_asn1_object (&pos, buffer,
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), &enc_length);
if (ret != 0) {
return ret;
@ -194,7 +166,7 @@ int x509_extension_builder_mbedtls_dice_tcbinfo_build_dynamic (
return DICE_TCBINFO_EXTENSION_INVALID_ARGUMENT;
}
length = X509_EXTENSION_BUILDER_MBEDTLS_DICE_TCBINFO_DATA_LENGTH;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (dice->tcb);
buffer = platform_malloc (length);
if (buffer == NULL) {
return DICE_TCBINFO_EXTENSION_NO_MEMORY;

Просмотреть файл

@ -16,7 +16,7 @@ struct x509_extension_builder_mbedtls_dice_tcbinfo {
struct x509_extension_builder base; /**< Base extension builder API. */
const struct tcg_dice_tcbinfo *tcb; /**< The TCB information to encode in the extension. */
uint8_t *ext_buffer; /**< Buffer to use for building the extension data. */
size_t ext_length; /**< Length of th extension data duffer. */
size_t ext_length; /**< Length of the extension data duffer. */
};

Просмотреть файл

@ -42,9 +42,8 @@ void x509_extension_builder_mbedtls_dice_tcbinfo_free_static (
*
* There is no validation done on the arguments.
*
* @param tcb_ptr The device unique identifier that should be encoded in the extension. This
* does not need to be constant. The contents can be updated at run-time to affect what will be
* encoded in the extension.
* @param tcb_ptr The firmware TCB to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
*/
#define x509_extension_builder_mbedtls_dice_tcbinfo_static_init(tcb_ptr) { \
.base = X509_EXTENSION_BUILDER_MBEDTLS_DICE_TCBINFO_DYNAMIC_API_INIT, \
@ -59,14 +58,13 @@ void x509_extension_builder_mbedtls_dice_tcbinfo_free_static (
*
* There is no validation done on the arguments.
*
* @param tcb_ptr The device unique identifier that should be encoded in the extension. This
* does not need to be constant. The contents can be updated at run-time to affect what will be
* encoded in the extension.
* @param tcb_ptr The firmware TCB to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
* @param ext_buffer_ptr Buffer for the encoded TcbInfo extension data.
* @param buffer_length Length of the extension data buffer.
*/
#define x509_extension_builder_mbedtls_dice_tcbinfo_static_init_with_buffer(tcb_ptr, ext_buffer_ptr, \
buffer_length) { \
#define x509_extension_builder_mbedtls_dice_tcbinfo_static_init_with_buffer(tcb_ptr, \
ext_buffer_ptr, buffer_length) { \
.base = X509_EXTENSION_BUILDER_MBEDTLS_DICE_TCBINFO_STATIC_API_INIT, \
.tcb = tcb_ptr, \
.ext_buffer = ext_buffer_ptr, \

Просмотреть файл

@ -32,13 +32,13 @@ int x509_extension_builder_mbedtls_dice_ueid_create_extension (
pos = buffer + length;
/* ueid OCTET STRING */
MBEDTLS_ASN1_CHK_ADD (enc_length, mbedtls_asn1_write_octet_string (&pos, buffer, dice->ueid,
dice->ueid_length));
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_octet_string (&pos, buffer, dice->ueid, dice->ueid_length));
/* TcgUeid ::= SEQUENCE */
MBEDTLS_ASN1_CHK_ADD (enc_length, mbedtls_asn1_write_len (&pos, buffer, enc_length));
MBEDTLS_ASN1_CHK_ADD (enc_length, mbedtls_asn1_write_tag (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)));
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_tag (&pos, buffer, (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)));
if (pos != buffer) {
memmove (buffer, pos, enc_length);

Просмотреть файл

@ -25,7 +25,7 @@ struct x509_extension_builder_mbedtls_dice_ueid {
const uint8_t *ueid; /**< The UEID to encode in the extension. */
size_t ueid_length; /**< Length of the UEID. */
uint8_t *ext_buffer; /**< Buffer to use for building the extension data. */
size_t ext_length; /**< Length of th extension data duffer. */
size_t ext_length; /**< Length of the extension data duffer. */
};

Просмотреть файл

@ -0,0 +1,343 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "dme_structure.h"
#include "asn1/asn1_oid.h"
/**
* OID to identify a SHA-384 DME structure.
*
* 1.3.6.1.4.1.311.102.3.2.1
*/
static const uint8_t DME_STRUCTURE_TYPE1_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x02,0x01
};
static const size_t DME_STRUCTURE_TYPE1_OID_LENGTH = sizeof (DME_STRUCTURE_TYPE1_OID);
/**
* Length of the SHA-384 DME structure.
*/
#define DME_STRUCTURE_TYPE1_LENGTH (SHA384_HASH_LENGTH * 2)
/**
* OID to identify a SHA-384 with challenge DME structure.
*
* 1.3.6.1.4.1.311.102.3.2.2
*/
static const uint8_t DME_STRUCTURE_TYPE2_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x02,0x02
};
static const size_t DME_STRUCTURE_TYPE2_OID_LENGTH = sizeof (DME_STRUCTURE_TYPE2_OID);
/**
* Length of the SHA-384 with challenge DME structure.
*/
#define DME_STRUCTURE_TYPE2_LENGTH ((SHA384_HASH_LENGTH * 2) + 32)
/**
* OID to identify a SHA-256 DME structure.
*
* 1.3.6.1.4.1.311.102.3.2.3
*/
static const uint8_t DME_STRUCTURE_TYPE3_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x02,0x03
};
static const size_t DME_STRUCTURE_TYPE3_OID_LENGTH = sizeof (DME_STRUCTURE_TYPE3_OID);
/**
* Length of the SHA-256 DME structure.
*/
#define DME_STRUCTURE_TYPE3_LENGTH (SHA256_HASH_LENGTH * 2)
/**
* OID to identify a SHA-256 with challenge DME structure.
*
* 1.3.6.1.4.1.311.102.3.2.4
*/
static const uint8_t DME_STRUCTURE_TYPE4_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x02,0x04
};
static const size_t DME_STRUCTURE_TYPE4_OID_LENGTH = sizeof (DME_STRUCTURE_TYPE4_OID);
/**
* Length of the SHA-256 with challenge DME structure.
*/
#define DME_STRUCTURE_TYPE4_LENGTH ((SHA256_HASH_LENGTH * 2) + 32)
/**
* OID to identify a SHA-512 DME structure.
*
* 1.3.6.1.4.1.311.102.3.2.5
*/
static const uint8_t DME_STRUCTURE_TYPE5_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x02,0x05
};
static const size_t DME_STRUCTURE_TYPE5_OID_LENGTH = sizeof (DME_STRUCTURE_TYPE5_OID);
/**
* Length of the SHA-512 DME structure.
*/
#define DME_STRUCTURE_TYPE5_LENGTH (SHA512_HASH_LENGTH * 2)
/**
* OID to identify a SHA-512 with challenge DME structure.
*
* 1.3.6.1.4.1.311.102.3.2.6
*/
static const uint8_t DME_STRUCTURE_TYPE6_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x02,0x06
};
static const size_t DME_STRUCTURE_TYPE6_OID_LENGTH = sizeof (DME_STRUCTURE_TYPE6_OID);
/**
* Length of the SHA-512 with challenge DME structure.
*/
#define DME_STRUCTURE_TYPE6_LENGTH ((SHA512_HASH_LENGTH * 2) + 32)
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-384 digest of the DICE Device ID public key.
* - SHA-384 measurement of DICE layer 0.
*
* This is DME structure type 1.
*
* @param dme The DME information to initialize.
* @param oid OID identifying the format of the DME structure data.
* @param oid_length Length of the DME structure format OID.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_struct_format Required length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
static int dme_structure_init (struct dme_structure *dme, const uint8_t *oid, size_t oid_length,
const uint8_t *dme_struct_data, size_t dme_struct_length, size_t dme_struct_format,
const uint8_t *dme_key_der, size_t key_length, const uint8_t *signature_der, size_t sig_length,
enum hash_type sig_hash)
{
if ((dme == NULL) || (dme_struct_data == NULL) || (dme_key_der == NULL) || (key_length == 0) ||
(signature_der == NULL) || (sig_length == 0)) {
return DME_STRUCTURE_INVALID_ARGUMENT;
}
if (dme_struct_length != dme_struct_format) {
return DME_STRUCTURE_BAD_LENGTH;
}
memset (dme, 0, sizeof (struct dme_structure));
dme->data_oid = oid;
dme->data_oid_length = oid_length;
dme->data = dme_struct_data;
dme->data_length = dme_struct_length;
switch (sig_hash) {
case HASH_TYPE_SHA256:
dme->sig_oid = ASN1_OID_ECDSA_WITH_SHA256;
dme->sig_oid_length = ASN1_OID_ECDSA_WITH_SHA256_LENGTH;
break;
case HASH_TYPE_SHA384:
dme->sig_oid = ASN1_OID_ECDSA_WITH_SHA384;
dme->sig_oid_length = ASN1_OID_ECDSA_WITH_SHA384_LENGTH;
break;
case HASH_TYPE_SHA512:
dme->sig_oid = ASN1_OID_ECDSA_WITH_SHA512;
dme->sig_oid_length = ASN1_OID_ECDSA_WITH_SHA512_LENGTH;
break;
default:
return DME_STRUCTURE_UNSUPPORTED_SIGNATURE;
}
dme->signature = signature_der;
dme->signature_length = sig_length;
dme->dme_pub_key = dme_key_der;
dme->key_length = key_length;
return 0;
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-384 digest of the DICE Device ID public key.
* - SHA-384 measurement of DICE layer 0.
*
* This is DME structure type 1.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_init_sha384 (struct dme_structure *dme, const uint8_t *dme_struct_data,
size_t dme_struct_length, const uint8_t *dme_key_der, size_t key_length,
const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash)
{
return dme_structure_init (dme, DME_STRUCTURE_TYPE1_OID, DME_STRUCTURE_TYPE1_OID_LENGTH,
dme_struct_data, dme_struct_length, DME_STRUCTURE_TYPE1_LENGTH, dme_key_der, key_length,
signature_der, sig_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-384 digest of the DICE Device ID public key.
* - 32-byte freshness seed
* - SHA-384 measurement of DICE layer 0.
*
* This is DME structure type 2.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_init_sha384_with_challenge (struct dme_structure *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_der,
size_t key_length, const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash)
{
return dme_structure_init (dme, DME_STRUCTURE_TYPE2_OID, DME_STRUCTURE_TYPE2_OID_LENGTH,
dme_struct_data, dme_struct_length, DME_STRUCTURE_TYPE2_LENGTH, dme_key_der, key_length,
signature_der, sig_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-256 digest of the DICE Device ID public key.
* - SHA-256 measurement of DICE layer 0.
*
* This is DME structure type 3.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_init_sha256 (struct dme_structure *dme, const uint8_t *dme_struct_data,
size_t dme_struct_length, const uint8_t *dme_key_der, size_t key_length,
const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash)
{
return dme_structure_init (dme, DME_STRUCTURE_TYPE3_OID, DME_STRUCTURE_TYPE3_OID_LENGTH,
dme_struct_data, dme_struct_length, DME_STRUCTURE_TYPE3_LENGTH, dme_key_der, key_length,
signature_der, sig_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-256 digest of the DICE Device ID public key.
* - 32-byte freshness seed
* - SHA-256 measurement of DICE layer 0.
*
* This is DME structure type 4.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_init_sha256_with_challenge (struct dme_structure *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_der,
size_t key_length, const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash)
{
return dme_structure_init (dme, DME_STRUCTURE_TYPE4_OID, DME_STRUCTURE_TYPE4_OID_LENGTH,
dme_struct_data, dme_struct_length, DME_STRUCTURE_TYPE4_LENGTH, dme_key_der, key_length,
signature_der, sig_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-512 digest of the DICE Device ID public key.
* - SHA-512 measurement of DICE layer 0.
*
* This is DME structure type 5.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_init_sha512 (struct dme_structure *dme, const uint8_t *dme_struct_data,
size_t dme_struct_length, const uint8_t *dme_key_der, size_t key_length,
const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash)
{
return dme_structure_init (dme, DME_STRUCTURE_TYPE5_OID, DME_STRUCTURE_TYPE5_OID_LENGTH,
dme_struct_data, dme_struct_length, DME_STRUCTURE_TYPE5_LENGTH, dme_key_der, key_length,
signature_der, sig_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-512 digest of the DICE Device ID public key.
* - 32-byte freshness seed
* - SHA-521 measurement of DICE layer 0.
*
* This is DME structure type 6.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_der DER encoded DME public key. This can be any key length.
* @param key_length Length of the DER encoded key.
* @param signature_der DER encoded signature of the DME structure.
* @param sig_length Length of the DER signature.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_init_sha512_with_challenge (struct dme_structure *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_der,
size_t key_length, const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash)
{
return dme_structure_init (dme, DME_STRUCTURE_TYPE6_OID, DME_STRUCTURE_TYPE6_OID_LENGTH,
dme_struct_data, dme_struct_length, DME_STRUCTURE_TYPE6_LENGTH, dme_key_der, key_length,
signature_der, sig_length, sig_hash);
}

Просмотреть файл

@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef DME_STRUCTURE_H_
#define DME_STRUCTURE_H_
#include <stdint.h>
#include <stddef.h>
#include "status/rot_status.h"
#include "crypto/hash.h"
/**
* Generic container for DME information from the device, which can accommodate DME structures and
* DME keys of any type. This information is used to build the DME extension for inclusion in
* device certificates.
*
* The required fields would generally be populated through an initialization call for a specific
* type of DME structure. The optional fields will be directly populated by the user, if required.
*/
struct dme_structure {
/**
* The OID specifying the type of DME structure contained in the data.
*/
const uint8_t *data_oid;
size_t data_oid_length; /**< Length of the DME structure type OID. */
/**
* The raw DME structure data that was signed with the DME private key. This is only the signed
* data and must not contain the signature.
*/
const uint8_t *data;
size_t data_length; /**< Length of the DME structure data. */
/**
* The OID specifying the type of signature that was generated for the DME structure.
*/
const uint8_t *sig_oid;
size_t sig_oid_length; /**< Length of the DME signature type OID. */
/**
* The signature for the DME structure using the DME private key. This must be a DER encoded
* signature.
*/
const uint8_t *signature;
size_t signature_length; /**< Length of the DER encoded DME signature. */
/**
* The DME public key that can be used to verify the signature. This must be a DER encoded
* public key.
*/
const uint8_t *dme_pub_key;
size_t key_length; /**< Length of the DER encoded DME public key. */
/**
* An optional OID specifying the type of device that generated the DME structure. If no device
* type OID is necessary, this will be null.
*/
const uint8_t *device_oid;
size_t dev_oid_length; /**< Length of the device type OID. */
/**
* An optional value specifying the current value used to renew the DME key for the device. If
* the device does not support a renewal counter, this will be null.
*/
const uint8_t *renewal_counter;
size_t counter_length; /**< Length of the DME key renewal counter. */
};
int dme_structure_init_sha384 (struct dme_structure *dme, const uint8_t *dme_struct_data,
size_t dme_struct_length, const uint8_t *dme_key_der, size_t key_length,
const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash);
int dme_structure_init_sha384_with_challenge (struct dme_structure *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_der,
size_t key_length, const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash);
int dme_structure_init_sha256 (struct dme_structure *dme, const uint8_t *dme_struct_data,
size_t dme_struct_length, const uint8_t *dme_key_der, size_t key_length,
const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash);
int dme_structure_init_sha256_with_challenge (struct dme_structure *dme,
const uint8_t *v, size_t dme_struct_length, const uint8_t *dme_key_der,
size_t key_length, const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash);
int dme_structure_init_sha512 (struct dme_structure *dme, const uint8_t *dme_struct_data,
size_t dme_struct_length, const uint8_t *dme_key_der, size_t key_length,
const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash);
int dme_structure_init_sha512_with_challenge (struct dme_structure *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_der,
size_t key_length, const uint8_t *signature_der, size_t sig_length, enum hash_type sig_hash);
#define DME_STRUCTURE_ERROR(code) ROT_ERROR (ROT_MODULE_DME_STRUCTURE, code)
/**
* Error codes that can be generated when parsing a DME structure.
*/
enum {
DME_STRUCTURE_INVALID_ARGUMENT = DME_STRUCTURE_ERROR (0x00), /**< Input parameter is null or not valid. */
DME_STRUCTURE_NO_MEMORY = DME_STRUCTURE_ERROR (0x01), /**< Memory allocation failed. */
DME_STRUCTURE_BAD_LENGTH = DME_STRUCTURE_ERROR (0x02), /**< DME structure length is not correct. */
DME_STRUCTURE_UNSUPPORTED_SIGNATURE = DME_STRUCTURE_ERROR (0x03), /**< The signature uses an unsupported digest. */
};
#endif /* DME_STRUCTURE_H_ */

Просмотреть файл

@ -0,0 +1,307 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "dme_structure_raw_ecc.h"
/**
* Encode the raw ECC DME key and ECDSA signature in DER.
*
* @param dme The DME container with buffers for DER encoding.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param key_der_length Output for the encoded length of the public key.
* @param signature_length Output for the encoded length of the signature.
*
* @return 0 if the DER encoding was successful or an error code.
*/
static int dme_structure_raw_ecc_encode_der (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_key_x, const uint8_t *dme_key_y, size_t key_length,
const uint8_t *signature_r, const uint8_t *signature_s, size_t *key_der_length,
size_t *signature_length)
{
int der_length;
if ((dme == NULL) || (dme_key_x == NULL) || (dme_key_y == NULL) || (signature_r == NULL) ||
(signature_s == NULL)) {
return DME_STRUCTURE_INVALID_ARGUMENT;
}
der_length = ecc_der_encode_public_key (dme_key_x, dme_key_y, key_length, dme->dme_key_der,
sizeof (dme->dme_key_der));
if (ROT_IS_ERROR (der_length)) {
return der_length;
}
*key_der_length = der_length;
/* It's not possible for this call to fail since the buffer will always be large enough, but
* check the return just to be sure. */
der_length = ecc_der_encode_ecdsa_signature (signature_r, signature_s, key_length,
dme->signature_der, sizeof (dme->signature_der));
if (ROT_IS_ERROR (der_length)) {
return der_length;
}
*signature_length = der_length;
return 0;
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-384 digest of the DICE Device ID public key.
* - SHA-384 measurement of DICE layer 0.
*
* This is DME structure type 1.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_raw_ecc_init_sha384 (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash)
{
size_t key_der_length;
size_t signature_length;
int status;
status = dme_structure_raw_ecc_encode_der (dme, dme_key_x, dme_key_y, key_length, signature_r,
signature_s, &key_der_length, &signature_length);
if (status != 0) {
return status;
}
return dme_structure_init_sha384 (&dme->base, dme_struct_data, dme_struct_length,
dme->dme_key_der, key_der_length, dme->signature_der, signature_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-384 digest of the DICE Device ID public key.
* - 32-byte freshness seed
* - SHA-384 measurement of DICE layer 0.
*
* This is DME structure type 2.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_raw_ecc_init_sha384_with_challenge (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash)
{
size_t key_der_length;
size_t signature_length;
int status;
status = dme_structure_raw_ecc_encode_der (dme, dme_key_x, dme_key_y, key_length, signature_r,
signature_s, &key_der_length, &signature_length);
if (status != 0) {
return status;
}
return dme_structure_init_sha384_with_challenge (&dme->base, dme_struct_data, dme_struct_length,
dme->dme_key_der, key_der_length, dme->signature_der, signature_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-256 digest of the DICE Device ID public key.
* - SHA-256 measurement of DICE layer 0.
*
* This is DME structure type 3.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_raw_ecc_init_sha256 (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash)
{
size_t key_der_length;
size_t signature_length;
int status;
status = dme_structure_raw_ecc_encode_der (dme, dme_key_x, dme_key_y, key_length, signature_r,
signature_s, &key_der_length, &signature_length);
if (status != 0) {
return status;
}
return dme_structure_init_sha256 (&dme->base, dme_struct_data, dme_struct_length,
dme->dme_key_der, key_der_length, dme->signature_der, signature_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-256 digest of the DICE Device ID public key.
* - 32-byte freshness seed
* - SHA-256 measurement of DICE layer 0.
*
* This is DME structure type 4.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_raw_ecc_init_sha256_with_challenge (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash)
{
size_t key_der_length;
size_t signature_length;
int status;
status = dme_structure_raw_ecc_encode_der (dme, dme_key_x, dme_key_y, key_length, signature_r,
signature_s, &key_der_length, &signature_length);
if (status != 0) {
return status;
}
return dme_structure_init_sha256_with_challenge (&dme->base, dme_struct_data, dme_struct_length,
dme->dme_key_der, key_der_length, dme->signature_der, signature_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-512 digest of the DICE Device ID public key.
* - SHA-512 measurement of DICE layer 0.
*
* This is DME structure type 5.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_raw_ecc_init_sha512 (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash)
{
size_t key_der_length;
size_t signature_length;
int status;
status = dme_structure_raw_ecc_encode_der (dme, dme_key_x, dme_key_y, key_length, signature_r,
signature_s, &key_der_length, &signature_length);
if (status != 0) {
return status;
}
return dme_structure_init_sha512 (&dme->base, dme_struct_data, dme_struct_length,
dme->dme_key_der, key_der_length, dme->signature_der, signature_length, sig_hash);
}
/**
* Initialize DME information for a device that uses a DME structure that contains:
* - SHA-512 digest of the DICE Device ID public key.
* - 32-byte freshness seed
* - SHA-521 measurement of DICE layer 0.
*
* This is DME structure type 6.
*
* @param dme The DME information to initialize.
* @param dme_struct_data The DME structure data signed by the DME key.
* @param dme_struct_length Length of the DME structure.
* @param dme_key_x Raw X coordinate of the DME public key.
* @param dme_key_y Raw Y coordinate of the DME public key.
* @param dme_key_length Length of the DME ECC key. This represents the length of a single public
* key coordinate.
* @param signature_r Raw r value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param signature_s Raw s value of the ECDSA signature. This must be the same length as the
* public key coordinates.
* @param sig_hash The hash algorithm that was used to generate the signature.
*
* @return 0 if the DME information was successfully initialized or an error code.
*/
int dme_structure_raw_ecc_init_sha512_with_challenge (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash)
{
size_t key_der_length;
size_t signature_length;
int status;
status = dme_structure_raw_ecc_encode_der (dme, dme_key_x, dme_key_y, key_length, signature_r,
signature_s, &key_der_length, &signature_length);
if (status != 0) {
return status;
}
return dme_structure_init_sha512_with_challenge (&dme->base, dme_struct_data, dme_struct_length,
dme->dme_key_der, key_der_length, dme->signature_der, signature_length, sig_hash);
}

Просмотреть файл

@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef DME_STRUCTURE_RAW_ECC_H_
#define DME_STRUCTURE_RAW_ECC_H_
#include "dme_structure.h"
#include "asn1/ecc_der_util.h"
/**
* Defines a DME structure that uses raw ECC key and ECDSA signature values.
*/
struct dme_structure_raw_ecc {
struct dme_structure base; /**< Base DME structure information. */
uint8_t dme_key_der[ECC_DER_MAX_PUBLIC_LENGTH]; /**< DER encoded DME public key. */
uint8_t signature_der[ECC_DER_ECDSA_MAX_LENGTH]; /**< DER encoded ECDSA signature. */
};
int dme_structure_raw_ecc_init_sha384 (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t dme_key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash);
int dme_structure_raw_ecc_init_sha384_with_challenge (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t dme_key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash);
int dme_structure_raw_ecc_init_sha256 (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t dme_key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash);
int dme_structure_raw_ecc_init_sha256_with_challenge (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t dme_key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash);
int dme_structure_raw_ecc_init_sha512 (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t dme_key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash);
int dme_structure_raw_ecc_init_sha512_with_challenge (struct dme_structure_raw_ecc *dme,
const uint8_t *dme_struct_data, size_t dme_struct_length, const uint8_t *dme_key_x,
const uint8_t *dme_key_y, size_t dme_key_length, const uint8_t *signature_r,
const uint8_t *signature_s, enum hash_type sig_hash);
#endif /* DME_STRUCTURE_RAW_ECC_H_ */

Просмотреть файл

@ -0,0 +1,275 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "platform_api.h"
#include "x509_extension_builder_dme.h"
#include "common/unused.h"
#include "riot/reference/include/RiotDerEnc.h"
#include "riot/reference/include/RiotX509Bldr.h"
/**
* Update the DER encoding and fail if the result is non-zero.
*
* TODO: Put this in a common location.
*/
#define DER_CHK_ENCODE(func) if ((status = (func)) != 0) {goto error;}
/**
* Extra buffer space to add to keep the DER encoder happy.
*
* TODO: Remove the need for the extra padding with updates to the DER encoder.
*/
#define X509_EXTENSION_BUILDER_DME_BUFFER_PADDING 32
/**
* The encoded OID for the DME extension: 1.3.6.1.4.1.311.102.3.1
*/
const uint8_t X509_EXTENSION_BUILDER_DME_OID[] = {
0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x66,0x03,0x01
};
/**
* Length of the encoded DME extension OID.
*/
const size_t X509_EXTENSION_BUILDER_DME_OID_LENGTH = sizeof (X509_EXTENSION_BUILDER_DME_OID);
/**
* Create the DME extension.
*
* @param dme The DME information to encode in the extension.
* @param buffer The buffer to use for the extension data.
* @param length Length of the extension data buffer.
* @param extension Output for extension information.
*
* @return 0 if the extension was created successfully or an error code.
*/
int x509_extension_builder_dme_create_extension (const struct dme_structure *dme, uint8_t *buffer,
size_t length, struct x509_extension *extension)
{
DERBuilderContext der;
size_t tag_pos;
int status;
if (dme == NULL) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
if (dme->data_oid == NULL) {
return DME_EXTENSION_NO_TYPE_OID;
}
if (dme->data == NULL) {
return DME_EXTENSION_NO_DATA;
}
if (dme->sig_oid == NULL) {
return DME_EXTENSION_NO_SIG_TYPE_OID;
}
if (dme->signature == NULL) {
return DME_EXTENSION_NO_SIGNATURE;
}
if (dme->dme_pub_key == NULL) {
return DME_EXTENSION_NO_DME_KEY;
}
DERInitContext (&der, buffer, length);
/* TODO: Not each of these error checks is tested. Add tests when refactoring DER encoding. */
DER_CHK_ENCODE (DERStartSequenceOrSet (&der, true));
DER_CHK_ENCODE (DERAddPublicKey (&der, dme->dme_pub_key, dme->key_length));
DER_CHK_ENCODE (DERAddEncodedOID (&der, dme->data_oid, dme->data_oid_length));
DER_CHK_ENCODE (DERAddOctetString (&der, dme->data, dme->data_length));
DER_CHK_ENCODE (DERStartSequenceOrSet (&der, true));
DER_CHK_ENCODE (DERAddEncodedOID (&der, dme->sig_oid, dme->sig_oid_length));
DER_CHK_ENCODE (DERPopNesting (&der));
DER_CHK_ENCODE (DERAddBitString (&der, dme->signature, dme->signature_length));
/* Optional fields need different tags. */
if (dme->device_oid) {
tag_pos = der.Position;
DER_CHK_ENCODE (DERAddEncodedOID (&der, dme->device_oid, dme->dev_oid_length));
der.Buffer[tag_pos] = 0x80;
}
if (dme->renewal_counter) {
tag_pos = der.Position;
DER_CHK_ENCODE (DERAddBitString (&der, dme->renewal_counter, dme->counter_length));
der.Buffer[tag_pos] = 0x81;
}
DER_CHK_ENCODE (DERPopNesting (&der));
x509_extension_builder_init_extension_descriptor (extension, false,
X509_EXTENSION_BUILDER_DME_OID, X509_EXTENSION_BUILDER_DME_OID_LENGTH, buffer,
DERGetEncodedLength (&der));
return 0;
error:
return DME_EXTENSION_SMALL_EXT_BUFFER;
}
int x509_extension_builder_dme_build_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
const struct x509_extension_builder_dme *dme_build =
(const struct x509_extension_builder_dme*) builder;
uint8_t *buffer;
size_t length;
int status;
if ((dme_build == NULL) || (extension == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
length = x509_extension_builder_dme_get_ext_buffer_length (dme_build->dme) +
X509_EXTENSION_BUILDER_DME_BUFFER_PADDING;
buffer = platform_malloc (length);
if (buffer == NULL) {
return DME_EXTENSION_NO_MEMORY;
}
status = x509_extension_builder_dme_create_extension (dme_build->dme, buffer, length,
extension);
if (status != 0) {
platform_free (buffer);
}
return status;
}
int x509_extension_builder_dme_build_static (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
const struct x509_extension_builder_dme *dme_build =
(const struct x509_extension_builder_dme*) builder;
if ((dme_build == NULL) || (extension == NULL) || (dme_build->ext_buffer == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
return x509_extension_builder_dme_create_extension (dme_build->dme, dme_build->ext_buffer,
dme_build->ext_length, extension);
}
void x509_extension_builder_dme_free_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
UNUSED (builder);
platform_free ((void*) extension->data);
}
void x509_extension_builder_dme_free_static (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
UNUSED (builder);
UNUSED (extension);
}
/**
* Initialize an extension builder for a DME extension. The buffer that will be used for the
* extension data will be dynamically allocated.
*
* @param builder The extension builder to initialize.
* @param dme The DME structure to encode in the extension. This does not need to be constant. The
* contents can be externally modified after initialization to change what will be encoded in the
* extension.
*
* @return 0 if the extension builder was initialized successfully or an error code.
*/
int x509_extension_builder_dme_init (struct x509_extension_builder_dme *builder,
const struct dme_structure *dme)
{
if ((builder == NULL) || (dme == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
memset (builder, 0, sizeof (struct x509_extension_builder_dme));
builder->base.build = x509_extension_builder_dme_build_dynamic;
builder->base.free = x509_extension_builder_dme_free_dynamic;
builder->dme = dme;
return 0;
}
/**
* Initialize an extension builder for a DME extension. The buffer used for the extension data is
* statically provided during initialization.
*
* @param builder The extension builder to initialize.
* @param dme The DME structure to encode in the extension. This does not need to be constant. The
* contents can be externally modified after initialization to change what will be encoded in the
* extension.
* @param ext_buffer Buffer for the encoded DME extension data.
* @param buffer_length Length of the extension data buffer.
*
* @return 0 if the extension builder was initialized successfully or an error code.
*/
int x509_extension_builder_dme_init_with_buffer (struct x509_extension_builder_dme *builder,
const struct dme_structure *dme, uint8_t *ext_buffer, size_t buffer_length)
{
if ((builder == NULL) || (dme == NULL) || (ext_buffer == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
memset (builder, 0, sizeof (struct x509_extension_builder_dme));
builder->base.build = x509_extension_builder_dme_build_static;
builder->base.free = x509_extension_builder_dme_free_static;
builder->dme = dme;
builder->ext_buffer = ext_buffer;
builder->ext_length = buffer_length;
return 0;
}
/**
* Release the resources used by a DME extension builder.
*
* @param builder The extension builder to release.
*/
void x509_extension_builder_dme_release (const struct x509_extension_builder_dme *builder)
{
UNUSED (builder);
}
/**
* Determine an appropriately sized buffer to use for DME extension building based on the DME
* structure values. This is not an exact extension length, but will provide sufficient space to
* fit the encoded extension.
*
* @param dme The DME structure that will be encoded into an extension.
*
* @return The buffer length needed for the DME extension.
*/
size_t x509_extension_builder_dme_get_ext_buffer_length (const struct dme_structure *dme)
{
size_t length = 4; /* Space for the top-level sequence header. */
if (dme != NULL) {
length += dme->data_oid_length;
length += dme->data_length;
length += dme->sig_oid_length;
length += dme->signature_length;
length += dme->key_length;
length += dme->dev_oid_length;
length += dme->counter_length;
/* Give everything else space for 4 header bytes, which should be more then enough, plus two
* extra bytes for BIT STRING fields. */
length += (4 * 7) + 2;
}
return length;
}

Просмотреть файл

@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_DME_H_
#define X509_EXTENSION_BUILDER_DME_H_
#include "dme_structure.h"
#include "asn1/x509_extension_builder.h"
/**
* X.509 extension handler for building a DME extension endorsing a DICE identity key. The
* extension builder does not rely on any external components or libraries.
*/
struct x509_extension_builder_dme {
struct x509_extension_builder base; /**< Base extension builder API. */
const struct dme_structure *dme; /**< The DME structure being encoded in the extension. */
uint8_t *ext_buffer; /**< Buffer to use for building the extension data. */
size_t ext_length; /**< Length of the extension data duffer. */
};
int x509_extension_builder_dme_init (struct x509_extension_builder_dme *builder,
const struct dme_structure *dme);
int x509_extension_builder_dme_init_with_buffer (struct x509_extension_builder_dme *builder,
const struct dme_structure *dme, uint8_t *ext_buffer, size_t buffer_length);
void x509_extension_builder_dme_release (const struct x509_extension_builder_dme *builder);
size_t x509_extension_builder_dme_get_ext_buffer_length (const struct dme_structure *dme);
/* Internal definitions for use by DME extension builders. */
extern const uint8_t X509_EXTENSION_BUILDER_DME_OID[];
extern const size_t X509_EXTENSION_BUILDER_DME_OID_LENGTH;
#define DME_EXTENSION_ERROR(code) ROT_ERROR (ROT_MODULE_DME_EXTENSION, code)
/**
* Error codes that can be generated by a TCG DICE Ueid extension builder.
*/
enum {
DME_EXTENSION_INVALID_ARGUMENT = DME_EXTENSION_ERROR (0x00), /**< Input parameter is null or not valid. */
DME_EXTENSION_NO_MEMORY = DME_EXTENSION_ERROR (0x01), /**< Memory allocation failed. */
DME_EXTENSION_SMALL_EXT_BUFFER = DME_EXTENSION_ERROR (0x02), /**< The extension buffer is too small for the data. */
DME_EXTENSION_NO_TYPE_OID = DME_EXTENSION_ERROR (0x03), /**< The DME structure does not specify a type identifier. */
DME_EXTENSION_NO_DATA = DME_EXTENSION_ERROR (0x04), /**< The DME structure does not provide any structure data. */
DME_EXTENSION_NO_SIG_TYPE_OID = DME_EXTENSION_ERROR (0x05), /**< The DME structure does not specify a signature type. */
DME_EXTENSION_NO_SIGNATURE = DME_EXTENSION_ERROR (0x06), /**< The DME structure does not provide a signature. */
DME_EXTENSION_NO_DME_KEY = DME_EXTENSION_ERROR (0x07), /**< The DME structure does not provide a public key. */
};
#endif /* X509_EXTENSION_BUILDER_DME_H_ */

Просмотреть файл

@ -0,0 +1,75 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_DME_STATIC_H_
#define X509_EXTENSION_BUILDER_DME_STATIC_H_
#include "x509_extension_builder_dme.h"
/* Internal functions declared to allow for static initialization. */
int x509_extension_builder_dme_build_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension);
void x509_extension_builder_dme_free_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension);
int x509_extension_builder_dme_build_static (const struct x509_extension_builder *builder,
struct x509_extension *extension);
void x509_extension_builder_dme_free_static (const struct x509_extension_builder *builder,
struct x509_extension *extension);
/**
* Constant initializer for extension builder API using dynamic buffers.
*/
#define X509_EXTENSION_BUILDER_DME_DYNAMIC_API_INIT { \
.build = x509_extension_builder_dme_build_dynamic, \
.free = x509_extension_builder_dme_free_dynamic \
}
/**
* Constant initializer for extension builder API using static buffers.
*/
#define X509_EXTENSION_BUILDER_DME_STATIC_API_INIT { \
.build = x509_extension_builder_dme_build_static, \
.free = x509_extension_builder_dme_free_static \
}
/**
* Initialize a static instance for creating a DME extension. The buffer that will be used for the
* extension data will be dynamically allocated. This can be a constant instance.
*
* There is no validation done on the arguments.
*
* @param dme_ptr The DME structure to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
*/
#define x509_extension_builder_dme_static_init(dme_ptr) { \
.base = X509_EXTENSION_BUILDER_DME_DYNAMIC_API_INIT, \
.dme = dme_ptr, \
.ext_buffer = NULL, \
.ext_length = 0, \
}
/**
* Initialize a static instance for creating a DME extension. The buffer used for the extension data
* is statically provided during initialization. This can be a constant instance.
*
* There is no validation done on the arguments.
*
* @param dme_ptr The DME structure to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
* @param ext_buffer_ptr Buffer for the encoded TcbInfo extension data.
* @param buffer_length Length of the extension data buffer.
*/
#define x509_extension_builder_dme_static_init_with_buffer(dme_ptr, ext_buffer_ptr, \
buffer_length) { \
.base = X509_EXTENSION_BUILDER_DME_STATIC_API_INIT, \
.dme = dme_ptr, \
.ext_buffer = ext_buffer_ptr, \
.ext_length = buffer_length, \
}
#endif /* X509_EXTENSION_BUILDER_DME_STATIC_H_ */

Просмотреть файл

@ -0,0 +1,253 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "platform_api.h"
#include "x509_extension_builder_dme.h"
#include "x509_extension_builder_mbedtls_dme.h"
#include "asn1/x509_mbedtls.h"
#include "common/unused.h"
#include "mbedtls/asn1write.h"
/**
* Create the DME extension.
*
* @param dme The DME information to encode in the extension.
* @param buffer The buffer to use for the extension data.
* @param length Length of the extension data buffer.
* @param extension Output for extension information.
*
* @return 0 if the extension was created successfully or an error code.
*/
int x509_extension_builder_mbedtls_dme_create_extension (const struct dme_structure *dme,
uint8_t *buffer, size_t length, struct x509_extension *extension)
{
uint8_t *pos;
int enc_length = 0;
int sig_alg_length = 0;
int ret;
if (dme == NULL) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
if (dme->data_oid == NULL) {
return DME_EXTENSION_NO_TYPE_OID;
}
if (dme->data == NULL) {
return DME_EXTENSION_NO_DATA;
}
if (dme->sig_oid == NULL) {
return DME_EXTENSION_NO_SIG_TYPE_OID;
}
if (dme->signature == NULL) {
return DME_EXTENSION_NO_SIGNATURE;
}
if (dme->dme_pub_key == NULL) {
return DME_EXTENSION_NO_DME_KEY;
}
pos = buffer + length;
/* renewalCounter [1] IMPLICIT BIT STRING OPTIONAL */
if (dme->renewal_counter != NULL) {
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_bitstring (&pos, buffer, dme->renewal_counter,
dme->counter_length * 8));
*pos = (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 1);
}
/* deviceType [0] IMPLICIT OBJECT IDENTIFIER OPTIONAL */
if (dme->device_oid != NULL) {
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_oid (&pos, buffer, (char*) dme->device_oid, dme->dev_oid_length));
*pos = (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0);
}
/* signatureValue BIT STRING */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_bitstring (&pos, buffer, dme->signature, dme->signature_length * 8));
/* signatureAlgorithm AlgorithmIdentifier */
MBEDTLS_ASN1_CHK_ADD (sig_alg_length,
mbedtls_asn1_write_oid (&pos, buffer, (char*) dme->sig_oid, dme->sig_oid_length));
ret = x509_mbedtls_close_asn1_object (&pos, buffer,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), &sig_alg_length);
if (ret != 0) {
return ret;
}
enc_length += sig_alg_length;
/* dmeStructure OCTET STRING */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_octet_string (&pos, buffer, dme->data, dme->data_length));
/* dmeStructureFormat OBJECT IDENTIFIER */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_oid (&pos, buffer, (char*) dme->data_oid, dme->data_oid_length));
/* dmePublicKey SubjectPublicKeyInfo */
MBEDTLS_ASN1_CHK_ADD (enc_length,
mbedtls_asn1_write_raw_buffer (&pos, buffer, dme->dme_pub_key, dme->key_length));
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_DME_OID, X509_EXTENSION_BUILDER_DME_OID_LENGTH, buffer, enc_length);
return 0;
}
int x509_extension_builder_mbedtls_dme_build_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
const struct x509_extension_builder_mbedtls_dme *dme_build =
(const struct x509_extension_builder_mbedtls_dme*) builder;
uint8_t *buffer;
size_t length;
int status;
if ((dme_build == NULL) || (extension == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
length = x509_extension_builder_dme_get_ext_buffer_length (dme_build->dme);
buffer = platform_malloc (length);
if (buffer == NULL) {
return DME_EXTENSION_NO_MEMORY;
}
status = x509_extension_builder_mbedtls_dme_create_extension (dme_build->dme, buffer, length,
extension);
if (status != 0) {
platform_free (buffer);
}
return status;
}
int x509_extension_builder_mbedtls_dme_build_static (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
const struct x509_extension_builder_mbedtls_dme *dme_build =
(const struct x509_extension_builder_mbedtls_dme*) builder;
int status;
if ((dme_build == NULL) || (extension == NULL) || (dme_build->ext_buffer == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
status = x509_extension_builder_mbedtls_dme_create_extension (dme_build->dme,
dme_build->ext_buffer, dme_build->ext_length, extension);
if (status == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
status = DME_EXTENSION_SMALL_EXT_BUFFER;
}
return status;
}
void x509_extension_builder_mbedtls_dme_free_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
UNUSED (builder);
platform_free ((void*) extension->data);
}
void x509_extension_builder_mbedtls_dme_free_static (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
UNUSED (builder);
UNUSED (extension);
}
/**
* Initialize an extension builder for a DME extension. The buffer that will be used for the
* extension data will be dynamically allocated.
*
* @param builder The extension builder to initialize.
* @param dme The DME structure to encode in the extension. This does not need to be constant. The
* contents can be externally modified after initialization to change what will be encoded in the
* extension.
*
* @return 0 if the extension builder was initialized successfully or an error code.
*/
int x509_extension_builder_mbedtls_dme_init (struct x509_extension_builder_mbedtls_dme *builder,
const struct dme_structure *dme)
{
if ((builder == NULL) || (dme == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
memset (builder, 0, sizeof (struct x509_extension_builder_mbedtls_dme));
builder->base.build = x509_extension_builder_mbedtls_dme_build_dynamic;
builder->base.free = x509_extension_builder_mbedtls_dme_free_dynamic;
builder->dme = dme;
return 0;
}
/**
* Initialize an extension builder for a DME extension. The buffer used for the extension data is
* statically provided during initialization.
*
* @param builder The extension builder to initialize.
* @param dme The DME structure to encode in the extension. This does not need to be constant. The
* contents can be externally modified after initialization to change what will be encoded in the
* extension.
* @param ext_buffer Buffer for the encoded DME extension data.
* @param buffer_length Length of the extension data buffer.
*
* @return 0 if the extension builder was initialized successfully or an error code.
*/
int x509_extension_builder_mbedtls_dme_init_with_buffer (
struct x509_extension_builder_mbedtls_dme *builder, const struct dme_structure *dme,
uint8_t *ext_buffer, size_t buffer_length)
{
if ((builder == NULL) || (dme == NULL) || (ext_buffer == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
memset (builder, 0, sizeof (struct x509_extension_builder_mbedtls_dme));
builder->base.build = x509_extension_builder_mbedtls_dme_build_static;
builder->base.free = x509_extension_builder_mbedtls_dme_free_static;
builder->dme = dme;
builder->ext_buffer = ext_buffer;
builder->ext_length = buffer_length;
return 0;
}
/**
* Release the resources used by a DME extension builder.
*
* @param builder The extension builder to release.
*/
void x509_extension_builder_mbedtls_dme_release (
const struct x509_extension_builder_mbedtls_dme *builder)
{
UNUSED (builder);
}

Просмотреть файл

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_MBEDTLS_DME_H_
#define X509_EXTENSION_BUILDER_MBEDTLS_DME_H_
#include "dme_structure.h"
#include "asn1/x509_extension_builder.h"
/**
* X.509 extension handler for building a DME extension endorsing a DICE identity key. The
* extension builder uses mbedTLS ASN.1/DER encoding functions.
*/
struct x509_extension_builder_mbedtls_dme {
struct x509_extension_builder base; /**< Base extension builder API. */
const struct dme_structure *dme; /**< The DME structure being encoded in the extension. */
uint8_t *ext_buffer; /**< Buffer to use for building the extension data. */
size_t ext_length; /**< Length of the extension data duffer. */
};
int x509_extension_builder_mbedtls_dme_init (struct x509_extension_builder_mbedtls_dme *builder,
const struct dme_structure *dme);
int x509_extension_builder_mbedtls_dme_init_with_buffer (
struct x509_extension_builder_mbedtls_dme *builder, const struct dme_structure *dme,
uint8_t *ext_buffer, size_t buffer_length);
void x509_extension_builder_mbedtls_dme_release (
const struct x509_extension_builder_mbedtls_dme *builder);
#endif /* X509_EXTENSION_BUILDER_MBEDTLS_DME_H_ */

Просмотреть файл

@ -0,0 +1,75 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_MBEDTLS_DME_STATIC_H_
#define X509_EXTENSION_BUILDER_MBEDTLS_DME_STATIC_H_
#include "x509_extension_builder_mbedtls_dme.h"
/* Internal functions declared to allow for static initialization. */
int x509_extension_builder_mbedtls_dme_build_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension);
void x509_extension_builder_mbedtls_dme_free_dynamic (const struct x509_extension_builder *builder,
struct x509_extension *extension);
int x509_extension_builder_mbedtls_dme_build_static (const struct x509_extension_builder *builder,
struct x509_extension *extension);
void x509_extension_builder_mbedtls_dme_free_static (const struct x509_extension_builder *builder,
struct x509_extension *extension);
/**
* Constant initializer for extension builder API using dynamic buffers.
*/
#define X509_EXTENSION_BUILDER_MBEDTLS_DME_DYNAMIC_API_INIT { \
.build = x509_extension_builder_mbedtls_dme_build_dynamic, \
.free = x509_extension_builder_mbedtls_dme_free_dynamic \
}
/**
* Constant initializer for extension builder API using static buffers.
*/
#define X509_EXTENSION_BUILDER_MBEDTLS_DME_STATIC_API_INIT { \
.build = x509_extension_builder_mbedtls_dme_build_static, \
.free = x509_extension_builder_mbedtls_dme_free_static \
}
/**
* Initialize a static instance for creating a DME extension. The buffer that will be used for the
* extension data will be dynamically allocated. This can be a constant instance.
*
* There is no validation done on the arguments.
*
* @param dme_ptr The DME structure to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
*/
#define x509_extension_builder_mbedtls_dme_static_init(dme_ptr) { \
.base = X509_EXTENSION_BUILDER_MBEDTLS_DME_DYNAMIC_API_INIT, \
.dme = dme_ptr, \
.ext_buffer = NULL, \
.ext_length = 0, \
}
/**
* Initialize a static instance for creating a DME extension. The buffer used for the extension data
* is statically provided during initialization. This can be a constant instance.
*
* There is no validation done on the arguments.
*
* @param dme_ptr The DME structure to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
* @param ext_buffer_ptr Buffer for the encoded TcbInfo extension data.
* @param buffer_length Length of the extension data buffer.
*/
#define x509_extension_builder_mbedtls_dme_static_init_with_buffer(dme_ptr, ext_buffer_ptr, \
buffer_length) { \
.base = X509_EXTENSION_BUILDER_MBEDTLS_DME_STATIC_API_INIT, \
.dme = dme_ptr, \
.ext_buffer = ext_buffer_ptr, \
.ext_length = buffer_length, \
}
#endif /* X509_EXTENSION_BUILDER_MBEDTLS_DME_STATIC_H_ */

Просмотреть файл

@ -102,8 +102,7 @@ exit:
*
* @return 0 if the object header was written or an error code.
*/
static int x509_mbedtls_close_asn1_object (uint8_t **pos, uint8_t *start, uint8_t tag,
int *length)
int x509_mbedtls_close_asn1_object (uint8_t **pos, uint8_t *start, uint8_t tag, int *length)
{
int ret;

Просмотреть файл

@ -30,5 +30,8 @@ struct x509_engine_mbedtls {
int x509_mbedtls_init (struct x509_engine_mbedtls *engine);
void x509_mbedtls_release (struct x509_engine_mbedtls *engine);
/* ASN.1 encoding helper functions. */
int x509_mbedtls_close_asn1_object (uint8_t **pos, uint8_t *start, uint8_t tag, int *length);
#endif /* X509_MBEDTLS_H_ */

Просмотреть файл

@ -122,6 +122,8 @@ enum {
ROT_MODULE_X509_EXTENSION = 0x006e, /**< Extension handler for X.509 certificates. */
ROT_MODULE_DICE_TCBINFO_EXTENSION = 0x006f, /**< Extension handler for TCG DICE TcbInfo extensions. */
ROT_MODULE_DICE_UEID_EXTENSION = 0x0070, /**< Extension handler for TCG DICE Ueid extensions. */
ROT_MODULE_DME_EXTENSION = 0x0071, /**< Extension handler for DME extensions. */
ROT_MODULE_DME_STRUCTURE = 0x0072, /**< Parsing and management of the DME structure. */
};

Просмотреть файл

@ -7,6 +7,7 @@
#include "testing.h"
#include "platform_all_tests.h"
#include "dice/asn1_dice_all_tests.h"
#include "dme/asn1_dme_all_tests.h"
/**
@ -19,6 +20,7 @@
static void add_all_asn1_tests (CuSuite *suite)
{
add_all_asn1_dice_tests (suite);
add_all_asn1_dme_tests (suite);
#if (defined TESTING_RUN_ASN1_UTIL_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_CORE_TESTS || \

Просмотреть файл

@ -1028,6 +1028,118 @@ static void x509_extension_builder_dice_tcbinfo_test_build_with_buffer_small_buf
x509_extension_builder_dice_tcbinfo_release (&builder);
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length (CuTest *test)
{
struct tcg_dice_tcbinfo tcb;
size_t length;
TEST_START;
tcb.version = X509_RIOT_VERSION;
tcb.svn = X509_RIOT_SVN;
tcb.fwid = X509_RIOT_SHA256_FWID;
tcb.fwid_hash = HASH_TYPE_SHA256;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (&tcb);
CuAssertTrue (test, (length >= X509_EXTENSION_BUILDER_DICE_TCBINFO_TESTING_DATA_SHA256_LEN));
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_sha1 (CuTest *test)
{
struct tcg_dice_tcbinfo tcb;
size_t length;
TEST_START;
tcb.version = X509_RIOT_VERSION;
tcb.svn = X509_RIOT_SVN;
tcb.fwid = X509_RIOT_SHA1_FWID;
tcb.fwid_hash = HASH_TYPE_SHA1;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (&tcb);
CuAssertTrue (test, (length >= X509_EXTENSION_BUILDER_DICE_TCBINFO_TESTING_DATA_SHA1_LEN));
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_sha384 (CuTest *test)
{
struct tcg_dice_tcbinfo tcb;
size_t length;
TEST_START;
tcb.version = X509_RIOT_VERSION;
tcb.svn = X509_RIOT_SVN;
tcb.fwid = X509_RIOT_SHA384_FWID;
tcb.fwid_hash = HASH_TYPE_SHA384;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (&tcb);
CuAssertTrue (test, (length >= X509_EXTENSION_BUILDER_DICE_TCBINFO_TESTING_DATA_SHA384_LEN));
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_sha512 (CuTest *test)
{
struct tcg_dice_tcbinfo tcb;
size_t length;
TEST_START;
tcb.version = X509_RIOT_VERSION;
tcb.svn = X509_RIOT_SVN;
tcb.fwid = X509_RIOT_SHA512_FWID;
tcb.fwid_hash = HASH_TYPE_SHA512;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (&tcb);
CuAssertTrue (test, (length >= X509_EXTENSION_BUILDER_DICE_TCBINFO_TESTING_DATA_SHA512_LEN));
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_svn_zero (CuTest *test)
{
struct tcg_dice_tcbinfo tcb;
size_t length;
TEST_START;
tcb.version = X509_RIOT_VERSION;
tcb.svn = 0;
tcb.fwid = X509_RIOT_SHA256_FWID;
tcb.fwid_hash = HASH_TYPE_SHA256;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (&tcb);
CuAssertTrue (test, (length >= X509_EXTENSION_BUILDER_DICE_TCBINFO_TESTING_DATA_SVN_ZERO_LEN));
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_version_null (
CuTest *test)
{
struct tcg_dice_tcbinfo tcb;
size_t length;
size_t min_length;
TEST_START;
tcb.version = NULL;
tcb.svn = X509_RIOT_SVN;
tcb.fwid = X509_RIOT_SHA256_FWID;
tcb.fwid_hash = HASH_TYPE_SHA256;
min_length = (X509_EXTENSION_BUILDER_DICE_TCBINFO_TESTING_DATA_SHA256_LEN -
sizeof (X509_RIOT_VERSION) + 2);
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (&tcb);
CuAssertTrue (test, (length >= min_length));
}
static void x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_null (CuTest *test)
{
size_t length;
TEST_START;
length = x509_extension_builder_dice_tcbinfo_get_ext_buffer_length (NULL);
CuAssertIntEquals (test, 4, length);
}
TEST_SUITE_START (x509_extension_builder_dice_tcbinfo);
@ -1059,5 +1171,12 @@ TEST (x509_extension_builder_dice_tcbinfo_test_build_with_buffer_null);
TEST (x509_extension_builder_dice_tcbinfo_test_build_with_buffer_static_init_null_buffer);
TEST (x509_extension_builder_dice_tcbinfo_test_build_with_buffer_static_init_null_tcb);
TEST (x509_extension_builder_dice_tcbinfo_test_build_with_buffer_small_buffer);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_sha1);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_sha384);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_sha512);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_svn_zero);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_version_null);
TEST (x509_extension_builder_dice_tcbinfo_test_get_ext_buffer_length_null);
TEST_SUITE_END;

Просмотреть файл

@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef ASN1_DME_ALL_TESTS_H_
#define ASN1_DME_ALL_TESTS_H_
#include "testing.h"
#include "platform_all_tests.h"
#include "common/unused.h"
/**
* Add all tests for components in the 'asn1/dme' directory.
*
* Be sure to keep the test suites in alphabetical order for easier management.
*
* @param suite Suite to add the tests to.
*/
static void add_all_asn1_dme_tests (CuSuite *suite)
{
/* This is unused when no tests will be executed. */
UNUSED (suite);
#if (defined TESTING_RUN_DME_STRUCTURE_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_CORE_TESTS || \
(!defined TESTING_SKIP_ALL_TESTS && !defined TESTING_SKIP_ALL_CORE_TESTS)) && \
!defined TESTING_SKIP_DME_STRUCTURE_SUITE
TESTING_RUN_SUITE (dme_structure);
#endif
#if (defined TESTING_RUN_DME_STRUCTURE_RAW_ECC_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_CORE_TESTS || \
(!defined TESTING_SKIP_ALL_TESTS && !defined TESTING_SKIP_ALL_CORE_TESTS)) && \
!defined TESTING_SKIP_DME_STRUCTURE_RAW_ECC_SUITE
TESTING_RUN_SUITE (dme_structure_raw_ecc);
#endif
#if (defined TESTING_RUN_X509_EXTENSION_BUILDER_DME_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_CORE_TESTS || \
(!defined TESTING_SKIP_ALL_TESTS && !defined TESTING_SKIP_ALL_CORE_TESTS)) && \
!defined TESTING_SKIP_X509_EXTENSION_BUILDER_DME_SUITE
TESTING_RUN_SUITE (x509_extension_builder_dme);
#endif
#if (defined TESTING_RUN_X509_EXTENSION_BUILDER_MBEDTLS_DME_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_CORE_TESTS || \
(!defined TESTING_SKIP_ALL_TESTS && !defined TESTING_SKIP_ALL_CORE_TESTS)) && \
!defined TESTING_SKIP_X509_EXTENSION_BUILDER_MBEDTLS_DME_SUITE
TESTING_RUN_SUITE (x509_extension_builder_mbedtls_dme);
#endif
}
#endif /* ASN1_DME_ALL_TESTS_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,167 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef DME_STRUCTURE_TESTING_H_
#define DME_STRUCTURE_TESTING_H_
#include <stdint.h>
#include <stddef.h>
#include "asn1/dme/dme_structure.h"
extern const uint8_t DME_STRUCTURE_TESTING_OID_TYPE[];
extern const size_t DME_STRUCTURE_TESTING_OID_TYPE_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_DATA[];
extern const size_t DME_STRUCTURE_TESTING_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_OID_SIG_ECC_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_OID_SIG_ECC_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_OID_SIG_ECC_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_OID_SIG_ECC_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_OID_SIG_ECC_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_OID_SIG_ECC_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_RENEWAL_COUNTER[];
extern const size_t DME_STRUCTURE_TESTING_RENEWAL_COUNTER_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_OID[];
extern const size_t DME_STRUCTURE_TESTING_TYPE1_OID_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_DATA[];
extern const size_t DME_STRUCTURE_TESTING_TYPE1_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC256_SHA256_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC256_SHA256_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC384_SHA384_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC384_SHA384_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC521_SHA512_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE1_SIG_ECC521_SHA512_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_OID[];
extern const size_t DME_STRUCTURE_TESTING_TYPE2_OID_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_DATA[];
extern const size_t DME_STRUCTURE_TESTING_TYPE2_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC256_SHA256_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC256_SHA256_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC384_SHA384_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC384_SHA384_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC521_SHA512_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE2_SIG_ECC521_SHA512_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_OID[];
extern const size_t DME_STRUCTURE_TESTING_TYPE3_OID_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_DATA[];
extern const size_t DME_STRUCTURE_TESTING_TYPE3_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC256_SHA256_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC256_SHA256_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC384_SHA384_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC384_SHA384_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC521_SHA512_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE3_SIG_ECC521_SHA512_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_OID[];
extern const size_t DME_STRUCTURE_TESTING_TYPE4_OID_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_DATA[];
extern const size_t DME_STRUCTURE_TESTING_TYPE4_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC256_SHA256_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC256_SHA256_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC384_SHA384_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC384_SHA384_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC521_SHA512_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE4_SIG_ECC521_SHA512_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_OID[];
extern const size_t DME_STRUCTURE_TESTING_TYPE5_OID_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_DATA[];
extern const size_t DME_STRUCTURE_TESTING_TYPE5_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC256_SHA256_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC256_SHA256_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC384_SHA384_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC384_SHA384_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC521_SHA512_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE5_SIG_ECC521_SHA512_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_OID[];
extern const size_t DME_STRUCTURE_TESTING_TYPE6_OID_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_DATA[];
extern const size_t DME_STRUCTURE_TESTING_TYPE6_DATA_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC256_SHA256[];
extern const size_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC256_SHA256_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC256_SHA256_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC256_SHA256_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC384_SHA384[];
extern const size_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC384_SHA384_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC384_SHA384_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC384_SHA384_RAW_S[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC521_SHA512[];
extern const size_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC521_SHA512_LEN;
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC521_SHA512_RAW_R[];
extern const uint8_t DME_STRUCTURE_TESTING_TYPE6_SIG_ECC521_SHA512_RAW_S[];
void dme_structure_testing_structure_ecc384_sha384 (struct dme_structure *dme);
void dme_structure_testing_structure_no_device_oid (struct dme_structure *dme);
void dme_structure_testing_structure_no_renewal (struct dme_structure *dme);
void dme_structure_testing_structure_ecc256_sha256 (struct dme_structure *dme);
void dme_structure_testing_structure_ecc521_sha512 (struct dme_structure *dme);
#endif /* DME_STRUCTURE_TESTING_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_DME_TESTING_H_
#define X509_EXTENSION_BUILDER_DME_TESTING_H_
#include <stdint.h>
#include <stddef.h>
#include "asn1/x509_extension_builder.h"
extern const uint8_t X509_EXTENSION_BUILDER_DME_TESTING_OID[];
#define X509_EXTENSION_BUILDER_DME_TESTING_OID_LEN 10
extern const uint8_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC384_SHA384[];
extern const size_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC384_SHA384_LEN;
extern const uint8_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_DEVICE_OID[];
extern const size_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_DEVICE_OID_LEN;
extern const uint8_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_RENEWAL[];
extern const size_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_RENEWAL_LEN;
extern const uint8_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC256_SHA256[];
extern const size_t X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC256_SHA256_LEN;
extern const struct x509_extension X509_EXTENSION_BUILDER_DME_TESTING_EXTENSION_ECC384_SHA384;
extern const struct x509_extension X509_EXTENSION_BUILDER_DME_TESTING_EXTENSION_NO_DEVICE_OID;
extern const struct x509_extension X509_EXTENSION_BUILDER_DME_TESTING_EXTENSION_NO_RENEWAL;
extern const struct x509_extension X509_EXTENSION_BUILDER_DME_TESTING_EXTENSION_ECC256_SHA256;
#endif /* X509_EXTENSION_BUILDER_DME_TESTING_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -205,8 +205,7 @@ void x509_extension_builder_openssl_dice_tcbinfo_free (const struct x509_extensi
}
/**
* Initialize an extension builder for a TCG DICE TcbInfo extension. The buffer that will be used
* for the extension data will be dynamically allocated.
* Initialize an extension builder for a TCG DICE TcbInfo extension.
*
* @param builder The extension builder to initialize.
* @param tcb The firmware TCB to encode in the extension. This does not need to be constant. The

Просмотреть файл

@ -9,7 +9,7 @@
/**
* Builder for the TCG DICE TcbInfo extension. The extension builder uses mbedTLS ASN.1/DER
* Builder for the TCG DICE TcbInfo extension. The extension builder uses OpenSSL ASN.1/DER
* encoding functions.
*/
struct x509_extension_builder_openssl_dice_tcbinfo {

Просмотреть файл

@ -29,9 +29,8 @@ void x509_extension_builder_openssl_dice_tcbinfo_free (const struct x509_extensi
*
* There is no validation done on the arguments.
*
* @param tcb_ptr The device unique identifier that should be encoded in the extension. This
* does not need to be constant. The contents can be updated at run-time to affect what will be
* encoded in the extension.
* @param tcb_ptr The firmware TCB to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
*/
#define x509_extension_builder_openssl_dice_tcbinfo_static_init(tcb_ptr) { \
.base = X509_EXTENSION_BUILDER_MBEDTLS_DICE_TCBINFO_API_INIT, \

Просмотреть файл

@ -15,16 +15,16 @@
/**
* Defines the structure of the Ueid extension for use with the OpenSSL ASN.1 encoding framework.
*/
typedef struct x509_ueid_st {
typedef struct dice_ueid_st {
ASN1_OCTET_STRING *ueid; /**< The UEID string. */
ASN1_ENCODING enc; /**< ASN1 encoding. */
} X509_UEID;
} DICE_UEID;
ASN1_SEQUENCE_enc (X509_UEID, enc, 0) = {
ASN1_SIMPLE (X509_UEID, ueid, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END_enc (X509_UEID, X509_UEID)
ASN1_SEQUENCE_enc (DICE_UEID, enc, 0) = {
ASN1_SIMPLE (DICE_UEID, ueid, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END_enc (DICE_UEID, DICE_UEID)
IMPLEMENT_ASN1_FUNCTIONS (X509_UEID)
IMPLEMENT_ASN1_FUNCTIONS (DICE_UEID)
int x509_extension_builder_openssl_dice_ueid_build (const struct x509_extension_builder *builder,
@ -32,7 +32,7 @@ int x509_extension_builder_openssl_dice_ueid_build (const struct x509_extension_
{
const struct x509_extension_builder_openssl_dice_ueid *dice =
(const struct x509_extension_builder_openssl_dice_ueid*) builder;
X509_UEID *ueid_ext;
DICE_UEID *ueid_ext;
int status;
uint8_t *ueid_der = NULL;
int ueid_len;
@ -41,7 +41,7 @@ int x509_extension_builder_openssl_dice_ueid_build (const struct x509_extension_
return DICE_UEID_EXTENSION_INVALID_ARGUMENT;
}
ueid_ext = X509_UEID_new ();
ueid_ext = DICE_UEID_new ();
if (ueid_ext == NULL) {
return -ERR_get_error ();
}
@ -52,7 +52,7 @@ int x509_extension_builder_openssl_dice_ueid_build (const struct x509_extension_
goto exit;
}
ueid_len = i2d_X509_UEID (ueid_ext, &ueid_der);
ueid_len = i2d_DICE_UEID (ueid_ext, &ueid_der);
if (ueid_len < 0) {
status = -ERR_get_error ();
goto exit;
@ -65,7 +65,7 @@ int x509_extension_builder_openssl_dice_ueid_build (const struct x509_extension_
status = 0;
exit:
X509_UEID_free (ueid_ext);
DICE_UEID_free (ueid_ext);
return status;
}

Просмотреть файл

@ -0,0 +1,223 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "platform_api.h"
#include "x509_extension_builder_openssl_dme.h"
#include "asn1/x509_openssl.h"
#include "asn1/dme/x509_extension_builder_dme.h"
#include "common/unused.h"
/**
* Structure of the DME extension.
*/
typedef struct dme_extension_st {
X509_PUBKEY *dme_key; /**< The DME public key for the device. */
ASN1_OBJECT *struct_format; /**< Format of the DME structure. */
ASN1_OCTET_STRING *dme_struct; /**< The DME structure data used for key endorsement. */
X509_ALGOR *sig_alg; /**< Algorithm used to generate signature for the DME structure. */
ASN1_BIT_STRING *signature; /**< Signature of the DME structure. */
ASN1_OBJECT *device_type; /**< Identifier for the type of device that generated the DME structure. */
ASN1_BIT_STRING *renewal_counter; /**< Current value of the renewal counter for the DME key. */
ASN1_ENCODING enc; /**< ASN1 encoding. */
} DME_EXTENSION;
ASN1_SEQUENCE_enc (DME_EXTENSION, enc, 0) = {
ASN1_SIMPLE (DME_EXTENSION, dme_key, X509_PUBKEY),
ASN1_SIMPLE (DME_EXTENSION, struct_format, ASN1_OBJECT),
ASN1_SIMPLE (DME_EXTENSION, dme_struct, ASN1_OCTET_STRING),
ASN1_SIMPLE (DME_EXTENSION, sig_alg, X509_ALGOR),
ASN1_SIMPLE (DME_EXTENSION, signature, ASN1_BIT_STRING),
ASN1_IMP_OPT (DME_EXTENSION, device_type, ASN1_OBJECT, 0),
ASN1_IMP_OPT (DME_EXTENSION, renewal_counter, ASN1_BIT_STRING, 1)
} ASN1_SEQUENCE_END_enc (DME_EXTENSION, DME_EXTENSION)
IMPLEMENT_ASN1_FUNCTIONS (DME_EXTENSION)
int x509_extension_builder_openssl_dme_build (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
const struct x509_extension_builder_openssl_dme *dme_build =
(const struct x509_extension_builder_openssl_dme*) builder;
DME_EXTENSION *dme_ext;
EVP_PKEY *pubkey;
ASN1_OBJECT *oid;
int status;
uint8_t *ext_der = NULL;
int ext_der_len;
if ((dme_build == NULL) || (extension == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
if (dme_build->dme == NULL) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
if (dme_build->dme->data_oid == NULL) {
return DME_EXTENSION_NO_TYPE_OID;
}
if (dme_build->dme->data == NULL) {
return DME_EXTENSION_NO_DATA;
}
if (dme_build->dme->sig_oid == NULL) {
return DME_EXTENSION_NO_SIG_TYPE_OID;
}
if (dme_build->dme->signature == NULL) {
return DME_EXTENSION_NO_SIGNATURE;
}
if (dme_build->dme->dme_pub_key == NULL) {
return DME_EXTENSION_NO_DME_KEY;
}
dme_ext = DME_EXTENSION_new ();
if (dme_ext == NULL) {
status = -ERR_get_error ();
goto err_ext;
}
pubkey = d2i_PUBKEY (NULL, (const uint8_t**) &dme_build->dme->dme_pub_key,
dme_build->dme->key_length);
if (pubkey == NULL) {
status = -ERR_get_error ();
goto err_build;
}
status = X509_PUBKEY_set (&dme_ext->dme_key, pubkey);
EVP_PKEY_free (pubkey);
if (status == 0) {
status = -ERR_get_error ();
goto err_build;
}
status = x509_openssl_parse_encoded_oid (dme_build->dme->data_oid,
dme_build->dme->data_oid_length, &oid);
if (status != 0) {
goto err_build;
}
ASN1_OBJECT_free (dme_ext->struct_format);
dme_ext->struct_format = oid;
status = ASN1_OCTET_STRING_set (dme_ext->dme_struct, dme_build->dme->data,
dme_build->dme->data_length);
if (status == 0) {
status = -ERR_get_error ();
goto err_build;
}
status = x509_openssl_parse_encoded_oid (dme_build->dme->sig_oid,
dme_build->dme->sig_oid_length, &oid);
if (status != 0) {
goto err_build;
}
status = X509_ALGOR_set0 (dme_ext->sig_alg, oid, V_ASN1_UNDEF, NULL);
if (status == 0) {
status = -ERR_get_error ();
ASN1_OBJECT_free (oid);
goto err_build;
}
status = x509_openssl_set_bit_string (dme_build->dme->signature,
dme_build->dme->signature_length, dme_ext->signature);
if (status != 0) {
goto err_build;
}
if (dme_build->dme->device_oid != NULL) {
status = x509_openssl_parse_encoded_oid (dme_build->dme->device_oid,
dme_build->dme->dev_oid_length, &dme_ext->device_type);
if (status != 0) {
goto err_build;
}
}
if (dme_build->dme->renewal_counter != NULL) {
dme_ext->renewal_counter = ASN1_BIT_STRING_new ();
if (dme_ext->renewal_counter == NULL) {
status = DME_EXTENSION_NO_MEMORY;
goto err_build;
}
status = x509_openssl_set_bit_string (dme_build->dme->renewal_counter,
dme_build->dme->counter_length, dme_ext->renewal_counter);
if (status != 0) {
goto err_build;
}
}
ext_der_len = i2d_DME_EXTENSION (dme_ext, &ext_der);
if (ext_der_len < 0) {
status = -ERR_get_error ();
goto err_build;
}
x509_extension_builder_init_extension_descriptor (extension, false,
X509_EXTENSION_BUILDER_DME_OID, X509_EXTENSION_BUILDER_DME_OID_LENGTH, ext_der,
ext_der_len);
status = 0;
err_build:
DME_EXTENSION_free (dme_ext);
err_ext:
return status;
}
void x509_extension_builder_openssl_dme_free (const struct x509_extension_builder *builder,
struct x509_extension *extension)
{
UNUSED (builder);
platform_free ((void*) extension->data);
}
/**
* Initialize an extension builder for a DME extension.
*
* @param builder The extension builder to initialize.
* @param dme The DME structure to encode in the extension. This does not need to be constant. The
* contents can be externally modified after initialization to change what will be encoded in the
* extension.
*
* @return 0 if the extension builder was initialized successfully or an error code.
*/
int x509_extension_builder_openssl_dme_init (struct x509_extension_builder_openssl_dme *builder,
const struct dme_structure *dme)
{
if ((builder == NULL) || (dme == NULL)) {
return DME_EXTENSION_INVALID_ARGUMENT;
}
memset (builder, 0, sizeof (struct x509_extension_builder_openssl_dme));
builder->base.build = x509_extension_builder_openssl_dme_build;
builder->base.free = x509_extension_builder_openssl_dme_free;
builder->dme = dme;
return 0;
}
/**
* Release the resources used by a DME extension builder.
*
* @param builder The extension builder to release.
*/
void x509_extension_builder_openssl_dme_release (
const struct x509_extension_builder_openssl_dme *builder)
{
UNUSED (builder);
}

Просмотреть файл

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_OPENSSL_DME_H_
#define X509_EXTENSION_BUILDER_OPENSSL_DME_H_
#include "asn1/x509_extension_builder.h"
#include "asn1/dme/dme_structure.h"
/**
* X.509 extension handler for building a DME extension endorsing a DICE identity key. The
* extension builder uses OpenSSL ASN.1/DER encoding functions.
*/
struct x509_extension_builder_openssl_dme {
struct x509_extension_builder base; /**< Base extension builder API. */
const struct dme_structure *dme; /**< The DME structure being encoded in the extension. */
};
int x509_extension_builder_openssl_dme_init (struct x509_extension_builder_openssl_dme *builder,
const struct dme_structure *dme);
void x509_extension_builder_openssl_dme_release (
const struct x509_extension_builder_openssl_dme *builder);
#endif /* X509_EXTENSION_BUILDER_OPENSSL_DME_H_ */

Просмотреть файл

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#ifndef X509_EXTENSION_BUILDER_OPENSSL_DME_STATIC_H_
#define X509_EXTENSION_BUILDER_OPENSSL_DME_STATIC_H_
#include "x509_extension_builder_openssl_dme.h"
/* Internal functions declared to allow for static initialization. */
int x509_extension_builder_openssl_dme_build (const struct x509_extension_builder *builder,
struct x509_extension *extension);
void x509_extension_builder_openssl_dme_free (const struct x509_extension_builder *builder,
struct x509_extension *extension);
/**
* Constant initializer for extension builder API.
*/
#define X509_EXTENSION_BUILDER_OPENSSL_DME_API_INIT { \
.build = x509_extension_builder_openssl_dme_build, \
.free = x509_extension_builder_openssl_dme_free \
}
/**
* Initialize a static instance for creating a DME extension. This can be a constant instance.
*
* There is no validation done on the arguments.
*
* @param dme_ptr The DME structure to encode in the extension. This does not need to be constant.
* The contents can be updated at run-time to affect what will be encoded in the extension.
*/
#define x509_extension_builder_openssl_dme_static_init(dme_ptr) { \
.base = X509_EXTENSION_BUILDER_OPENSSL_DME_API_INIT, \
.dme = dme_ptr, \
}
#endif /* X509_EXTENSION_BUILDER_OPENSSL_DME_STATIC_H_ */

Просмотреть файл

@ -87,8 +87,7 @@ err_bio:
*
* @return 0 if the OID was parsed successfully or an error code.
*/
static int x509_openssl_parse_encoded_oid (const uint8_t *encoded_oid, size_t length,
ASN1_OBJECT **oid)
int x509_openssl_parse_encoded_oid (const uint8_t *encoded_oid, size_t length, ASN1_OBJECT **oid)
{
uint8_t oid_der[256];
uint8_t *oid_ptr = oid_der;
@ -111,6 +110,32 @@ static int x509_openssl_parse_encoded_oid (const uint8_t *encoded_oid, size_t le
return 0;
}
/**
* Set the value of an ASN.1 BIT STRING, ensuring that the unused bits field is always 0.
*
* @param data The data to encode as a BIT STRING.
* @param length Length of the data.
* @param bits The BIT STRING object that will be updated.
*
* @return 0 if the bit string was updated successfully or an error code.
*/
int x509_openssl_set_bit_string (const uint8_t *data, size_t length, ASN1_BIT_STRING *bits)
{
int status;
status = ASN1_BIT_STRING_set (bits, (uint8_t*) data, length);
if (status == 0) {
status = -ERR_get_error ();
return status;
}
/* Make sure unused bits is always 0. */
bits->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
bits->flags |= ASN1_STRING_FLAG_BITS_LEFT;
return 0;
}
/**
* Create an custom formatted X.509 extension.
*

Просмотреть файл

@ -19,5 +19,9 @@ struct x509_engine_openssl {
int x509_openssl_init (struct x509_engine_openssl *engine);
void x509_openssl_release (struct x509_engine_openssl *engine);
/* ASN.1 encoding helper functions. */
int x509_openssl_parse_encoded_oid (const uint8_t *encoded_oid, size_t length, ASN1_OBJECT **oid);
int x509_openssl_set_bit_string (const uint8_t *data, size_t length, ASN1_BIT_STRING *bits);
#endif /* X509_OPENSSL_H_ */

Просмотреть файл

@ -0,0 +1,408 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "platform_api.h"
#include "testing.h"
#include "asn1/dme/x509_extension_builder_dme.h"
#include "asn1/dme/x509_extension_builder_openssl_dme.h"
#include "asn1/dme/x509_extension_builder_openssl_dme_static.h"
#include "testing/asn1/dme/dme_structure_testing.h"
#include "testing/asn1/dme/x509_extension_builder_dme_testing.h"
TEST_SUITE_LABEL ("x509_extension_builder_openssl_dme");
/*******************
* Test cases
*******************/
static void x509_extension_builder_openssl_dme_test_init (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
TEST_START;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
CuAssertPtrNotNull (test, builder.base.build);
CuAssertPtrNotNull (test, builder.base.free);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_init_null (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
TEST_START;
status = x509_extension_builder_openssl_dme_init (NULL, &dme);
CuAssertIntEquals (test, DME_EXTENSION_INVALID_ARGUMENT, status);
status = x509_extension_builder_openssl_dme_init (&builder, NULL);
CuAssertIntEquals (test, DME_EXTENSION_INVALID_ARGUMENT, status);
}
static void x509_extension_builder_openssl_dme_test_static_init (CuTest *test)
{
struct dme_structure dme;
struct x509_extension_builder_openssl_dme builder =
x509_extension_builder_openssl_dme_static_init (&dme);
TEST_START;
CuAssertPtrNotNull (test, builder.base.build);
CuAssertPtrNotNull (test, builder.base.free);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, 0, status);
CuAssertIntEquals (test, false, extension.critical);
CuAssertPtrNotNull (test, extension.oid);
CuAssertPtrNotNull (test, extension.data);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_OID_LEN, extension.oid_length);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC384_SHA384_LEN,
extension.data_length);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_OID, extension.oid,
extension.oid_length);
CuAssertIntEquals (test, 0, status);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC384_SHA384,
extension.data, extension.data_length);
CuAssertIntEquals (test, 0, status);
builder.base.free (&builder.base, &extension);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_ecc256_sha256 (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc256_sha256 (&dme);
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, 0, status);
CuAssertIntEquals (test, false, extension.critical);
CuAssertPtrNotNull (test, extension.oid);
CuAssertPtrNotNull (test, extension.data);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_OID_LEN, extension.oid_length);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC256_SHA256_LEN,
extension.data_length);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_OID, extension.oid,
extension.oid_length);
CuAssertIntEquals (test, 0, status);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC256_SHA256,
extension.data, extension.data_length);
CuAssertIntEquals (test, 0, status);
builder.base.free (&builder.base, &extension);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_device_oid (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_no_device_oid (&dme);
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, 0, status);
CuAssertIntEquals (test, false, extension.critical);
CuAssertPtrNotNull (test, extension.oid);
CuAssertPtrNotNull (test, extension.data);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_OID_LEN, extension.oid_length);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_DEVICE_OID_LEN,
extension.data_length);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_OID, extension.oid,
extension.oid_length);
CuAssertIntEquals (test, 0, status);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_DEVICE_OID,
extension.data, extension.data_length);
CuAssertIntEquals (test, 0, status);
builder.base.free (&builder.base, &extension);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_renewal_counter (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_no_renewal (&dme);
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, 0, status);
CuAssertIntEquals (test, false, extension.critical);
CuAssertPtrNotNull (test, extension.oid);
CuAssertPtrNotNull (test, extension.data);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_OID_LEN, extension.oid_length);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_RENEWAL_LEN,
extension.data_length);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_OID, extension.oid,
extension.oid_length);
CuAssertIntEquals (test, 0, status);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_DATA_NO_RENEWAL,
extension.data, extension.data_length);
CuAssertIntEquals (test, 0, status);
builder.base.free (&builder.base, &extension);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_static_init (CuTest *test)
{
struct dme_structure dme;
struct x509_extension_builder_openssl_dme builder =
x509_extension_builder_openssl_dme_static_init (&dme);
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, 0, status);
CuAssertIntEquals (test, false, extension.critical);
CuAssertPtrNotNull (test, extension.oid);
CuAssertPtrNotNull (test, extension.data);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_OID_LEN, extension.oid_length);
CuAssertIntEquals (test, X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC384_SHA384_LEN,
extension.data_length);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_OID, extension.oid,
extension.oid_length);
CuAssertIntEquals (test, 0, status);
status = testing_validate_array (X509_EXTENSION_BUILDER_DME_TESTING_DATA_ECC384_SHA384,
extension.data, extension.data_length);
CuAssertIntEquals (test, 0, status);
builder.base.free (&builder.base, &extension);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_null (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (NULL, &extension);
CuAssertIntEquals (test, DME_EXTENSION_INVALID_ARGUMENT, status);
status = builder.base.build (&builder.base, NULL);
CuAssertIntEquals (test, DME_EXTENSION_INVALID_ARGUMENT, status);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_static_init_null_dme_structure (
CuTest *test)
{
struct x509_extension_builder_openssl_dme builder =
x509_extension_builder_openssl_dme_static_init (NULL);
int status;
struct x509_extension extension;
TEST_START;
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, DME_EXTENSION_INVALID_ARGUMENT, status);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_structure_type_oid (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
dme.data_oid = NULL;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, DME_EXTENSION_NO_TYPE_OID, status);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_structure_data (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
dme.data = NULL;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, DME_EXTENSION_NO_DATA, status);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_signature_type_oid (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
dme.sig_oid = NULL;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, DME_EXTENSION_NO_SIG_TYPE_OID, status);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_signature (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
dme.signature = NULL;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, DME_EXTENSION_NO_SIGNATURE, status);
x509_extension_builder_openssl_dme_release (&builder);
}
static void x509_extension_builder_openssl_dme_test_build_no_dme_key (CuTest *test)
{
struct x509_extension_builder_openssl_dme builder;
struct dme_structure dme;
int status;
struct x509_extension extension;
TEST_START;
dme_structure_testing_structure_ecc384_sha384 (&dme);
dme.dme_pub_key = NULL;
status = x509_extension_builder_openssl_dme_init (&builder, &dme);
CuAssertIntEquals (test, 0, status);
status = builder.base.build (&builder.base, &extension);
CuAssertIntEquals (test, DME_EXTENSION_NO_DME_KEY, status);
x509_extension_builder_openssl_dme_release (&builder);
}
TEST_SUITE_START (x509_extension_builder_openssl_dme);
TEST (x509_extension_builder_openssl_dme_test_init);
TEST (x509_extension_builder_openssl_dme_test_init_null);
TEST (x509_extension_builder_openssl_dme_test_static_init);
TEST (x509_extension_builder_openssl_dme_test_build);
TEST (x509_extension_builder_openssl_dme_test_build_ecc256_sha256);
TEST (x509_extension_builder_openssl_dme_test_build_no_device_oid);
TEST (x509_extension_builder_openssl_dme_test_build_no_renewal_counter);
TEST (x509_extension_builder_openssl_dme_test_build_static_init);
TEST (x509_extension_builder_openssl_dme_test_build_null);
TEST (x509_extension_builder_openssl_dme_test_build_static_init_null_dme_structure);
TEST (x509_extension_builder_openssl_dme_test_build_no_structure_type_oid);
TEST (x509_extension_builder_openssl_dme_test_build_no_structure_data);
TEST (x509_extension_builder_openssl_dme_test_build_no_signature_type_oid);
TEST (x509_extension_builder_openssl_dme_test_build_no_signature);
TEST (x509_extension_builder_openssl_dme_test_build_no_dme_key);
TEST_SUITE_END;

Просмотреть файл

@ -27,6 +27,12 @@ static void add_all_linux_asn1_tests (CuSuite *suite)
!defined TESTING_SKIP_BASE64_OPENSSL_SUITE
TESTING_RUN_SUITE (base64_openssl);
#endif
#if (defined TESTING_RUN_X509_EXTENSION_BUILDER_OPENSSL_DME_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_LINUX_TESTS || \
(!defined TESTING_SKIP_ALL_TESTS && !defined TESTING_SKIP_ALL_LINUX_TESTS)) && \
!defined TESTING_SKIP_X509_EXTENSION_BUILDER_OPENSSL_DME_SUITE
TESTING_RUN_SUITE (x509_extension_builder_openssl_dme);
#endif
#if (defined TESTING_RUN_X509_EXTENSION_BUILDER_OPENSSL_DICE_TCBINFO_SUITE || \
defined TESTING_RUN_ALL_TESTS || defined TESTING_RUN_ALL_LINUX_TESTS || \
(!defined TESTING_SKIP_ALL_TESTS && !defined TESTING_SKIP_ALL_LINUX_TESTS)) && \