Commit 7d37aa17 authored by Juan Castillo's avatar Juan Castillo
Browse files

TBB: add mbedTLS authentication related libraries

This patch adds the following mbedTLS based libraries:

* Cryptographic library

It is used by the crypto module to verify a digital signature
and a hash. This library relies on mbedTLS to perform the
cryptographic operations. mbedTLS sources must be obtained
separately.

Two key algorithms are currently supported:

    * RSA-2048
    * ECDSA-SECP256R1

The platform is responsible for picking up the required
algorithm by defining the 'MBEDTLS_KEY_ALG' variable in the
platform makefile. Available options are:

    * 'rsa' (for RSA-2048) (default option)
    * 'ecdsa' (for ECDSA-SECP256R1)

Hash algorithm currently supported is SHA-256.

* Image parser library

Used by the image parser module to extract the authentication
parameters stored in X509v3 certificates.

Change-Id: I597c4be3d29287f2f18b82846973afc142ee0bf0
parent 05799ae0
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
/* mbedTLS headers */
#include <polarssl/memory_buffer_alloc.h>
/*
* mbedTLS heap
*/
#if (MBEDTLS_KEY_ALG_ID == MBEDTLS_ECDSA)
#define MBEDTLS_HEAP_SIZE (14*1024)
#elif (MBEDTLS_KEY_ALG_ID == MBEDTLS_RSA)
#define MBEDTLS_HEAP_SIZE (8*1024)
#endif
static unsigned char heap[MBEDTLS_HEAP_SIZE];
/*
* mbedTLS initialization function
*
* Return: 0 = success, Otherwise = error
*/
void mbedtls_init(void)
{
static int ready;
int rc;
if (!ready) {
/* Initialize the mbedTLS heap */
rc = memory_buffer_alloc_init(heap, MBEDTLS_HEAP_SIZE);
if (rc == 0) {
ready = 1;
} else {
assert(0);
}
}
}
#
# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of ARM nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
ifneq (${MBEDTLS_COMMON_MK},1)
MBEDTLS_COMMON_MK := 1
# MBEDTLS_DIR must be set to the mbedTLS main directory (it must contain
# the 'include' and 'library' subdirectories).
ifeq (${MBEDTLS_DIR},)
$(error Error: MBEDTLS_DIR not set)
endif
INCLUDES += -I${MBEDTLS_DIR}/include \
-Iinclude/drivers/auth/mbedtls
# Specify mbedTLS configuration file
POLARSSL_CONFIG_FILE := "<mbedtls_config.h>"
$(eval $(call add_define,POLARSSL_CONFIG_FILE))
MBEDTLS_COMMON_SOURCES := drivers/auth/mbedtls/mbedtls_common.c \
$(addprefix ${MBEDTLS_DIR}/library/, \
asn1parse.c \
asn1write.c \
memory_buffer_alloc.c \
oid.c \
platform.c \
)
BL1_SOURCES += ${MBEDTLS_COMMON_SOURCES}
BL2_SOURCES += ${MBEDTLS_COMMON_SOURCES}
DISABLE_PEDANTIC := 1
endif
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <crypto_mod.h>
#include <debug.h>
#include <mbedtls_common.h>
#include <stddef.h>
#include <string.h>
/* mbedTLS headers */
#include <polarssl/md_wrap.h>
#include <polarssl/memory_buffer_alloc.h>
#include <polarssl/oid.h>
#include <polarssl/platform.h>
#define LIB_NAME "mbedTLS"
/*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING
* }
*
* DigestInfo ::= SEQUENCE {
* digestAlgorithm AlgorithmIdentifier,
* digest OCTET STRING
* }
*/
/*
* Initialize the library and export the descriptor
*/
static void init(void)
{
/* Initialize mbedTLS */
mbedtls_init();
}
/*
* Verify a signature.
*
* Parameters are passed using the DER encoding format following the ASN.1
* structures detailed above.
*/
static int verify_signature(void *data_ptr, unsigned int data_len,
void *sig_ptr, unsigned int sig_len,
void *sig_alg, unsigned int sig_alg_len,
void *pk_ptr, unsigned int pk_len)
{
asn1_buf sig_oid, sig_params;
asn1_buf signature;
md_type_t md_alg;
pk_type_t pk_alg;
pk_context pk;
int rc;
void *sig_opts = NULL;
const md_info_t *md_info;
unsigned char *p, *end;
unsigned char hash[POLARSSL_MD_MAX_SIZE];
/* Get pointers to signature OID and parameters */
p = (unsigned char *)sig_alg;
end = (unsigned char *)(p + sig_alg_len);
rc = asn1_get_alg(&p, end, &sig_oid, &sig_params);
if (rc != 0) {
return CRYPTO_ERR_SIGNATURE;
}
/* Get the actual signature algorithm (MD + PK) */
rc = oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
if (rc != 0) {
return CRYPTO_ERR_SIGNATURE;
}
/* Parse the public key */
pk_init(&pk);
p = (unsigned char *)pk_ptr;
end = (unsigned char *)(p + pk_len);
rc = pk_parse_subpubkey(&p, end, &pk);
if (rc != 0) {
return CRYPTO_ERR_SIGNATURE;
}
/* Get the signature (bitstring) */
p = (unsigned char *)sig_ptr;
end = (unsigned char *)(p + sig_len);
signature.tag = *p;
rc = asn1_get_bitstring_null(&p, end, &signature.len);
if (rc != 0) {
rc = CRYPTO_ERR_SIGNATURE;
goto end;
}
signature.p = p;
/* Calculate the hash of the data */
md_info = md_info_from_type(md_alg);
if (md_info == NULL) {
rc = CRYPTO_ERR_SIGNATURE;
goto end;
}
p = (unsigned char *)data_ptr;
rc = md(md_info, p, data_len, hash);
if (rc != 0) {
rc = CRYPTO_ERR_SIGNATURE;
goto end;
}
/* Verify the signature */
rc = pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash,
md_info->size, signature.p, signature.len);
if (rc != 0) {
rc = CRYPTO_ERR_SIGNATURE;
goto end;
}
/* Signature verification success */
rc = CRYPTO_SUCCESS;
end:
pk_free(&pk);
return rc;
}
/*
* Match a hash
*
* Digest info is passed in DER format following the ASN.1 structure detailed
* above.
*/
static int verify_hash(void *data_ptr, unsigned int data_len,
void *digest_info_ptr, unsigned int digest_info_len)
{
asn1_buf hash_oid, params;
md_type_t md_alg;
const md_info_t *md_info;
unsigned char *p, *end, *hash;
unsigned char data_hash[POLARSSL_MD_MAX_SIZE];
size_t len;
int rc;
/* Digest info should be an ASN1_SEQUENCE */
p = (unsigned char *)digest_info_ptr;
end = (unsigned char *)(digest_info_ptr + digest_info_len);
rc = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (rc != 0) {
return CRYPTO_ERR_HASH;
}
/* Get the hash algorithm */
rc = asn1_get_alg(&p, end, &hash_oid, &params);
if (rc != 0) {
return CRYPTO_ERR_HASH;
}
rc = oid_get_md_alg(&hash_oid, &md_alg);
if (rc != 0) {
return CRYPTO_ERR_HASH;
}
md_info = md_info_from_type(md_alg);
if (md_info == NULL) {
return CRYPTO_ERR_HASH;
}
/* Hash should be octet string type */
rc = asn1_get_tag(&p, end, &len, ASN1_OCTET_STRING);
if (rc != 0) {
return CRYPTO_ERR_HASH;
}
/* Length of hash must match the algorithm's size */
if (len != md_info->size) {
return CRYPTO_ERR_HASH;
}
hash = p;
/* Calculate the hash of the data */
p = (unsigned char *)data_ptr;
rc = md(md_info, p, data_len, data_hash);
if (rc != 0) {
return CRYPTO_ERR_HASH;
}
/* Compare values */
rc = memcmp(data_hash, hash, md_info->size);
if (rc != 0) {
return CRYPTO_ERR_HASH;
}
return CRYPTO_SUCCESS;
}
/*
* Register crypto library descriptor
*/
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash);
#
# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of ARM nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
include drivers/auth/mbedtls/mbedtls_common.mk
# The platform may define the variable 'MBEDTLS_KEY_ALG' to select the key
# algorithm to use. Default algorithm is ECDSA.
ifeq (${MBEDTLS_KEY_ALG},)
MBEDTLS_KEY_ALG := rsa
endif
MBEDTLS_CRYPTO_SOURCES := drivers/auth/mbedtls/mbedtls_crypto.c \
$(addprefix ${MBEDTLS_DIR}/library/, \
bignum.c \
md.c \
md_wrap.c \
pk.c \
pk_wrap.c \
pkparse.c \
pkwrite.c \
sha256.c \
)
# Key algorithm specific files
ifeq (${MBEDTLS_KEY_ALG},ecdsa)
MBEDTLS_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \
ecdsa.c \
ecp_curves.c \
ecp.c \
)
MBEDTLS_KEY_ALG_ID := MBEDTLS_ECDSA
else ifeq (${MBEDTLS_KEY_ALG},rsa)
MBEDTLS_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \
rsa.c \
)
MBEDTLS_KEY_ALG_ID := MBEDTLS_RSA
else
$(error "MBEDTLS_KEY_ALG=${MBEDTLS_KEY_ALG} not supported on mbedTLS")
endif
# mbedTLS libraries rely on this define to build correctly
$(eval $(call add_define,MBEDTLS_KEY_ALG_ID))
BL1_SOURCES += ${MBEDTLS_CRYPTO_SOURCES}
BL2_SOURCES += ${MBEDTLS_CRYPTO_SOURCES}
#
# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of ARM nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
include drivers/auth/mbedtls/mbedtls_common.mk
MBEDTLS_X509_SOURCES := drivers/auth/mbedtls/mbedtls_x509_parser.c \
$(addprefix ${MBEDTLS_DIR}/library/, \
x509.c \
x509_crt.c \
)
BL1_SOURCES += ${MBEDTLS_X509_SOURCES}
BL2_SOURCES += ${MBEDTLS_X509_SOURCES}
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* X509 parser based on PolarSSL
*
* This module implements functions to check the integrity of a X509v3
* certificate ASN.1 structure and extract authentication parameters from the
* extensions field, such as an image hash or a public key.
*/
#include <assert.h>
#include <img_parser_mod.h>
#include <mbedtls_common.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
/* mbedTLS headers */
#include <polarssl/asn1.h>
#include <polarssl/oid.h>
#include <polarssl/platform.h>
/* Maximum OID string length ("a.b.c.d.e.f ...") */
#define MAX_OID_STR_LEN 64
#define LIB_NAME "mbedTLS X509v3"
/* Temporary variables to speed up the authentication parameters search. These
* variables are assigned once during the integrity check and used any time an
* authentication parameter is requested, so we do not have to parse the image
* again */
static asn1_buf tbs;
static asn1_buf v3_ext;
static asn1_buf pk;
static asn1_buf sig_alg;
static asn1_buf signature;
/*
* Get X509v3 extension
*
* Global variable 'v3_ext' must point to the extensions region
* in the certificate. No need to check for errors since the image has passed
* the integrity check.
*/
static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
{
int oid_len;
size_t len;
unsigned char *end_ext_data, *end_ext_octet;
unsigned char *p;
const unsigned char *end;
char oid_str[MAX_OID_STR_LEN];
asn1_buf extn_oid;
int is_critical;
assert(oid != NULL);
p = v3_ext.p;
end = v3_ext.p + v3_ext.len;
asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
while (p < end) {
memset(&extn_oid, 0x0, sizeof(extn_oid));
is_critical = 0; /* DEFAULT FALSE */
asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
end_ext_data = p + len;
/* Get extension ID */
extn_oid.tag = *p;
asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID);
extn_oid.p = p;
p += extn_oid.len;
/* Get optional critical */
asn1_get_bool(&p, end_ext_data, &is_critical);
/* Extension data */
asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING);
end_ext_octet = p + len;
/* Detect requested extension */
oid_len = oid_get_numeric_string(oid_str,
MAX_OID_STR_LEN, &extn_oid);
if (oid_len == POLARSSL_ERR_OID_BUF_TOO_SMALL) {
return IMG_PARSER_ERR;
}
if ((oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
*ext = (void *)p;
*ext_len = (unsigned int)len;
return IMG_PARSER_OK;
}
/* Next */
p = end_ext_octet;
}
return IMG_PARSER_ERR_NOT_FOUND;
}
/*
* Check the integrity of the certificate ASN.1 structure.
* Extract the relevant data that will be used later during authentication.
*/
static int cert_parse(void *img, unsigned int img_len)
{
int ret, is_critical;
size_t len;
unsigned char *p, *end, *crt_end;
asn1_buf sig_alg1, sig_alg2;
p = (unsigned char *)img;
len = img_len;
end = p + len;
/*
* Certificate ::= SEQUENCE {
* tbsCertificate TBSCertificate,
* signatureAlgorithm AlgorithmIdentifier,
* signatureValue BIT STRING }
*/
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
if (len > (size_t)(end - p)) {
return IMG_PARSER_ERR_FORMAT;
}
crt_end = p + len;
/*
* TBSCertificate ::= SEQUENCE {
*/
tbs.p = p;
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
end = p + len;
tbs.len = end - tbs.p;
/*
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
*/
ret = asn1_get_tag(&p, end, &len,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
/*
* CertificateSerialNumber ::= INTEGER
*/
ret = asn1_get_tag(&p, end, &len, ASN1_INTEGER);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
/*
* signature AlgorithmIdentifier
*/
sig_alg1.p = p;
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
if ((end - p) < 1) {
return IMG_PARSER_ERR_FORMAT;
}
sig_alg1.len = (p + len) - sig_alg1.p;
p += len;
/*
* issuer Name
*/
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
/*
* Validity ::= SEQUENCE {
* notBefore Time,
* notAfter Time }
*
*/
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
/*
* subject Name
*/
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
/*
* SubjectPublicKeyInfo
*/
pk.p = p;
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
pk.len = (p + len) - pk.p;
p += len;
/*
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
*/
ret = asn1_get_tag(&p, end, &len,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1);
if (ret != 0) {
if (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG) {
return IMG_PARSER_ERR_FORMAT;
}
} else {
p += len;
}
/*
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
*/
ret = asn1_get_tag(&p, end, &len,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2);
if (ret != 0) {
if (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG) {
return IMG_PARSER_ERR_FORMAT;
}
} else {
p += len;
}
/*
* extensions [3] EXPLICIT Extensions OPTIONAL
*/
ret = asn1_get_tag(&p, end, &len,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
/*
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
*/
v3_ext.p = p;
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
v3_ext.len = (p + len) - v3_ext.p;
/*
* Check extensions integrity
*/
while (p < end) {
ret = asn1_get_tag(&p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
/* Get extension ID */
ret = asn1_get_tag(&p, end, &len, ASN1_OID);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
/* Get optional critical */
ret = asn1_get_bool(&p, end, &is_critical);
if ((ret != 0) && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG)) {
return IMG_PARSER_ERR_FORMAT;
}
/* Data should be octet string type */
ret = asn1_get_tag(&p, end, &len, ASN1_OCTET_STRING);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
p += len;
}
if (p != end) {
return IMG_PARSER_ERR_FORMAT;
}
end = crt_end;
/*
* }
* -- end of TBSCertificate
*
* signatureAlgorithm AlgorithmIdentifier
*/
sig_alg2.p = p;
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
if ((end - p) < 1) {
return IMG_PARSER_ERR_FORMAT;
}
sig_alg2.len = (p + len) - sig_alg2.p;
p += len;
/* Compare both signature algorithms */
if (sig_alg1.len != sig_alg2.len) {
return IMG_PARSER_ERR_FORMAT;
}
if (0 != memcmp(sig_alg1.p, sig_alg2.p, sig_alg1.len)) {
return IMG_PARSER_ERR_FORMAT;
}
memcpy(&sig_alg, &sig_alg1, sizeof(sig_alg));
/*
* signatureValue BIT STRING
*/
signature.p = p;
ret = asn1_get_tag(&p, end, &len, ASN1_BIT_STRING);
if (ret != 0) {
return IMG_PARSER_ERR_FORMAT;
}
signature.len = (p + len) - signature.p;
p += len;
/* Check certificate length */
if (p != end) {
return IMG_PARSER_ERR_FORMAT;
}
return IMG_PARSER_OK;
}
/* Exported functions */
static void init(void)
{
mbedtls_init();
}
static int check_integrity(void *img, unsigned int img_len)
{
return cert_parse(img, img_len);
}
/*
* Extract an authentication parameter from an X509v3 certificate
*/
static int get_auth_param(const auth_param_type_desc_t *type_desc,
void *img, unsigned int img_len,
void **param, unsigned int *param_len)
{
int rc = IMG_PARSER_OK;
/* We do not use img because the check_integrity function has already
* extracted the relevant data (v3_ext, pk, sig_alg, etc) */
switch (type_desc->type) {
case AUTH_PARAM_RAW_DATA:
/* Data to be signed */
*param = (void *)tbs.p;
*param_len = (unsigned int)tbs.len;
break;
case AUTH_PARAM_HASH:
/* All these parameters are included as X509v3 extensions */
rc = get_ext(type_desc->cookie, param, param_len);
break;
case AUTH_PARAM_PUB_KEY:
if (type_desc->cookie != 0) {
/* Get public key from extension */
rc = get_ext(type_desc->cookie, param, param_len);
} else {
/* Get the subject public key */
*param = (void *)pk.p;
*param_len = (unsigned int)pk.len;
}
break;
case AUTH_PARAM_SIG_ALG:
/* Get the certificate signature algorithm */
*param = (void *)sig_alg.p;
*param_len = (unsigned int)sig_alg.len;
break;
case AUTH_PARAM_SIG:
/* Get the certificate signature */
*param = (void *)signature.p;
*param_len = (unsigned int)signature.len;
break;
default:
rc = IMG_PARSER_ERR_NOT_FOUND;
break;
}
return rc;
}
REGISTER_IMG_PARSER_LIB(IMG_CERT, LIB_NAME, init, \
check_integrity, get_auth_param);
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MBEDTLS_COMMON_H__
#define __MBEDTLS_COMMON_H__
void mbedtls_init(void);
#endif /* __MBEDTLS_COMMON_H__ */
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MBEDTLS_CONFIG_H__
#define __MBEDTLS_CONFIG_H__
/*
* Key algorithms currently supported on mbedTLS libraries
*/
#define MBEDTLS_RSA 1
#define MBEDTLS_ECDSA 2
/*
* Configuration file to build PolarSSL with the required features for
* Trusted Boot
*/
#define POLARSSL_PLATFORM_MEMORY
#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS
#define POLARSSL_PKCS1_V15
#define POLARSSL_PKCS1_V21
#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
#define POLARSSL_X509_CHECK_KEY_USAGE
#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE
#define POLARSSL_ASN1_PARSE_C
#define POLARSSL_ASN1_WRITE_C
#define POLARSSL_BASE64_C
#define POLARSSL_BIGNUM_C
#define POLARSSL_ERROR_C
#define POLARSSL_MD_C
#define POLARSSL_MEMORY_BUFFER_ALLOC_C
#define POLARSSL_OID_C
#define POLARSSL_PK_C
#define POLARSSL_PK_PARSE_C
#define POLARSSL_PK_WRITE_C
#define POLARSSL_PLATFORM_C
#if (MBEDTLS_KEY_ALG_ID == MBEDTLS_ECDSA)
#define POLARSSL_ECDSA_C
#define POLARSSL_ECP_C
#define POLARSSL_ECP_DP_SECP256R1_ENABLED
#elif (MBEDTLS_KEY_ALG_ID == MBEDTLS_RSA)
#define POLARSSL_RSA_C
#endif
#define POLARSSL_SHA256_C
#define POLARSSL_VERSION_C
#define POLARSSL_X509_USE_C
#define POLARSSL_X509_CRT_PARSE_C
/* MPI / BIGNUM options */
#define POLARSSL_MPI_WINDOW_SIZE 2
#define POLARSSL_MPI_MAX_SIZE 256
/* Memory buffer allocator options */
#define POLARSSL_MEMORY_ALIGN_MULTIPLE 8
#include "polarssl/check_config.h"
/* System headers required to build mbedTLS with the current configuration */
#include <stdlib.h>
#endif /* __MBEDTLS_CONFIG_H__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment