584 lines
15 KiB
C
584 lines
15 KiB
C
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
/* Authentication module based on PolarSSL */
|
||
|
|
||
|
#include <stddef.h>
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <auth.h>
|
||
|
#include <debug.h>
|
||
|
#include <platform.h>
|
||
|
#include <platform_def.h>
|
||
|
#include <platform_oid.h>
|
||
|
|
||
|
#include <polarssl/memory_buffer_alloc.h>
|
||
|
#include <polarssl/oid.h>
|
||
|
#include <polarssl/platform.h>
|
||
|
#include <polarssl/sha256.h>
|
||
|
#include <polarssl/x509_crt.h>
|
||
|
|
||
|
/*
|
||
|
* At each authentication stage, the module is responsible for extracting and
|
||
|
* storing those elements (keys, hashes, etc.) that will be needed later on
|
||
|
* during the Trusted Boot process.
|
||
|
*/
|
||
|
|
||
|
/* SHA256 algorithm */
|
||
|
#define SHA_BYTES 32
|
||
|
|
||
|
/*
|
||
|
* An 8 KB stack has been proven to be enough for the current Trusted Boot
|
||
|
* process
|
||
|
*/
|
||
|
#define POLARSSL_HEAP_SIZE (8*1024)
|
||
|
static unsigned char heap[POLARSSL_HEAP_SIZE];
|
||
|
|
||
|
/*
|
||
|
* RSA public keys:
|
||
|
* SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
|
||
|
* algorithm AlgorithmIdentifier, 1 + 1 (sequence)
|
||
|
* + 1 + 1 + 9 (rsa oid)
|
||
|
* + 1 + 1 (params null)
|
||
|
* subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
|
||
|
* RSAPublicKey ::= SEQUENCE { 1 + 3
|
||
|
* modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
|
||
|
* publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
|
||
|
* }
|
||
|
*
|
||
|
* POLARSSL_MPI_MAX_SIZE is set to 256 bytes (RSA-2048 bit keys) in the
|
||
|
* configuration file
|
||
|
*/
|
||
|
#define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE
|
||
|
|
||
|
/*
|
||
|
* Buffer for storing public keys extracted from certificates while they are
|
||
|
* verified
|
||
|
*/
|
||
|
static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES];
|
||
|
|
||
|
/* We use this variable to parse and authenticate the certificates */
|
||
|
static x509_crt cert;
|
||
|
|
||
|
/* BL specific variables */
|
||
|
#if IMAGE_BL1
|
||
|
static unsigned char sha_bl2[SHA_BYTES];
|
||
|
#elif IMAGE_BL2
|
||
|
/* Buffers to store the hash of BL3-x images */
|
||
|
static unsigned char sha_bl30[SHA_BYTES];
|
||
|
static unsigned char sha_bl31[SHA_BYTES];
|
||
|
static unsigned char sha_bl32[SHA_BYTES];
|
||
|
static unsigned char sha_bl33[SHA_BYTES];
|
||
|
/* Buffers to store the Trusted and Non-Trusted world public keys */
|
||
|
static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES];
|
||
|
static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES];
|
||
|
static size_t tz_world_pk_len, ntz_world_pk_len;
|
||
|
/* Buffer to store the BL3-x public keys */
|
||
|
static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES];
|
||
|
static size_t content_pk_len;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
static int x509_get_crt_ext_data(const unsigned char **ext_data,
|
||
|
size_t *ext_len,
|
||
|
x509_crt *crt,
|
||
|
const char *oid)
|
||
|
{
|
||
|
int ret;
|
||
|
size_t len;
|
||
|
unsigned char *end_ext_data, *end_ext_octet;
|
||
|
unsigned char *p;
|
||
|
const unsigned char *end;
|
||
|
char oid_str[64];
|
||
|
|
||
|
p = crt->v3_ext.p;
|
||
|
end = crt->v3_ext.p + crt->v3_ext.len;
|
||
|
|
||
|
ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
|
||
|
if (ret != 0)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
|
||
|
|
||
|
if (end != p + len)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
|
||
|
POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
|
||
|
|
||
|
while (p < end) {
|
||
|
/*
|
||
|
* Extension ::= SEQUENCE {
|
||
|
* extnID OBJECT IDENTIFIER,
|
||
|
* critical BOOLEAN DEFAULT FALSE,
|
||
|
* extnValue OCTET STRING }
|
||
|
*/
|
||
|
x509_buf extn_oid = {0, 0, NULL};
|
||
|
int is_critical = 0; /* DEFAULT FALSE */
|
||
|
|
||
|
ret = asn1_get_tag(&p, end, &len,
|
||
|
ASN1_CONSTRUCTED | ASN1_SEQUENCE);
|
||
|
if (ret != 0)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
|
||
|
|
||
|
end_ext_data = p + len;
|
||
|
|
||
|
/* Get extension ID */
|
||
|
extn_oid.tag = *p;
|
||
|
|
||
|
ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID);
|
||
|
if (ret != 0)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
|
||
|
|
||
|
extn_oid.p = p;
|
||
|
p += extn_oid.len;
|
||
|
|
||
|
if ((end - p) < 1)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
|
||
|
POLARSSL_ERR_ASN1_OUT_OF_DATA;
|
||
|
|
||
|
/* Get optional critical */
|
||
|
ret = asn1_get_bool(&p, end_ext_data, &is_critical);
|
||
|
if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG))
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
|
||
|
|
||
|
/* Data should be octet string type */
|
||
|
ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING);
|
||
|
if (ret != 0)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
|
||
|
|
||
|
end_ext_octet = p + len;
|
||
|
|
||
|
if (end_ext_octet != end_ext_data)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
|
||
|
POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
|
||
|
|
||
|
/* Detect requested extension */
|
||
|
oid_get_numeric_string(oid_str, 64, &extn_oid);
|
||
|
if (memcmp(oid, oid_str, sizeof(oid)) == 0) {
|
||
|
*ext_data = p;
|
||
|
*ext_len = len;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Next */
|
||
|
p = end_ext_octet;
|
||
|
}
|
||
|
|
||
|
if (p != end)
|
||
|
return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
|
||
|
POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
|
||
|
|
||
|
return POLARSSL_ERR_X509_UNKNOWN_OID;
|
||
|
}
|
||
|
|
||
|
#if IMAGE_BL1
|
||
|
/*
|
||
|
* Parse and verify the BL2 certificate
|
||
|
*
|
||
|
* This function verifies the integrity of the BL2 certificate, checks that it
|
||
|
* has been signed with the ROT key and extracts the BL2 hash stored in the
|
||
|
* certificate so it can be matched later against the calculated hash.
|
||
|
*
|
||
|
* Return: 0 = success, Otherwise = error
|
||
|
*/
|
||
|
static int check_bl2_cert(unsigned char *buf, size_t len)
|
||
|
{
|
||
|
const unsigned char *p;
|
||
|
size_t sz;
|
||
|
int err, flags;
|
||
|
|
||
|
x509_crt_init(&cert);
|
||
|
|
||
|
/* Parse the BL2 certificate */
|
||
|
err = x509_crt_parse(&cert, buf, len);
|
||
|
if (err) {
|
||
|
ERROR("BL2 certificate parse error %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Check that it has been signed with the ROT key */
|
||
|
err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
|
||
|
if (err < 0) {
|
||
|
ERROR("Error loading ROT key in DER format %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
sz = (size_t)err;
|
||
|
p = pk_buf + sizeof(pk_buf) - sz;
|
||
|
|
||
|
err = plat_match_rotpk(p, sz);
|
||
|
if (err) {
|
||
|
ERROR("ROT and BL2 certificate key mismatch\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Verify certificate */
|
||
|
err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
|
||
|
if (err) {
|
||
|
ERROR("BL2 certificate verification error %d. Flags: 0x%x.\n",
|
||
|
err, flags);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Extract BL2 image hash from certificate */
|
||
|
err = x509_get_crt_ext_data(&p, &sz, &cert, BL2_HASH_OID);
|
||
|
if (err) {
|
||
|
ERROR("Cannot read BL2 hash from certificate\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
assert(sz == SHA_BYTES + 2);
|
||
|
|
||
|
/* Skip the tag and length bytes and copy the hash */
|
||
|
p += 2;
|
||
|
memcpy(sha_bl2, p, SHA_BYTES);
|
||
|
|
||
|
error:
|
||
|
x509_crt_free(&cert);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
#endif /* IMAGE_BL1 */
|
||
|
|
||
|
#if IMAGE_BL2
|
||
|
static int check_trusted_key_cert(unsigned char *buf, size_t len)
|
||
|
{
|
||
|
const unsigned char *p;
|
||
|
size_t sz;
|
||
|
int err, flags;
|
||
|
|
||
|
x509_crt_init(&cert);
|
||
|
|
||
|
/* Parse the Trusted Key certificate */
|
||
|
err = x509_crt_parse(&cert, buf, len);
|
||
|
if (err) {
|
||
|
ERROR("Trusted Key certificate parse error %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Verify Trusted Key certificate */
|
||
|
err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
|
||
|
if (err) {
|
||
|
ERROR("Trusted Key certificate verification error %d. Flags: "
|
||
|
"0x%x.\n", err, flags);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Check that it has been signed with the ROT key */
|
||
|
err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
|
||
|
if (err < 0) {
|
||
|
ERROR("Error loading ROT key in DER format %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
sz = (size_t)err;
|
||
|
p = pk_buf + sizeof(pk_buf) - sz;
|
||
|
|
||
|
if (plat_match_rotpk(p, sz)) {
|
||
|
ERROR("ROT and Trusted Key certificate key mismatch\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Extract Trusted World key from extensions */
|
||
|
err = x509_get_crt_ext_data(&p, &tz_world_pk_len,
|
||
|
&cert, TZ_WORLD_PK_OID);
|
||
|
if (err) {
|
||
|
ERROR("Cannot read Trusted World key\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
|
||
|
memcpy(tz_world_pk, p, tz_world_pk_len);
|
||
|
|
||
|
/* Extract Non-Trusted World key from extensions */
|
||
|
err = x509_get_crt_ext_data(&p, &ntz_world_pk_len,
|
||
|
&cert, NTZ_WORLD_PK_OID);
|
||
|
if (err) {
|
||
|
ERROR("Cannot read Non-Trusted World key\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
|
||
|
memcpy(ntz_world_pk, p, ntz_world_pk_len);
|
||
|
|
||
|
error:
|
||
|
x509_crt_free(&cert);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
static int check_bl3x_key_cert(const unsigned char *buf, size_t len,
|
||
|
const unsigned char *i_key, size_t i_key_len,
|
||
|
unsigned char *s_key, size_t *s_key_len,
|
||
|
const char *key_oid)
|
||
|
{
|
||
|
const unsigned char *p;
|
||
|
size_t sz;
|
||
|
int err, flags;
|
||
|
|
||
|
x509_crt_init(&cert);
|
||
|
|
||
|
/* Parse key certificate */
|
||
|
err = x509_crt_parse(&cert, buf, len);
|
||
|
if (err) {
|
||
|
ERROR("Key certificate parse error %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Verify certificate */
|
||
|
err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
|
||
|
if (err) {
|
||
|
ERROR("Key certificate verification error %d. Flags: "
|
||
|
"0x%x.\n", err, flags);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Check that the certificate has been signed by the issuer */
|
||
|
err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
|
||
|
if (err < 0) {
|
||
|
ERROR("Error loading key in DER format %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
sz = (size_t)err;
|
||
|
p = pk_buf + sizeof(pk_buf) - sz;
|
||
|
if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
|
||
|
ERROR("Key certificate not signed with issuer key\n");
|
||
|
err = 1;
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Get the content certificate key */
|
||
|
err = x509_get_crt_ext_data(&p, &sz, &cert, key_oid);
|
||
|
if (err) {
|
||
|
ERROR("Extension %s not found in Key certificate\n", key_oid);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
assert(sz <= RSA_PUB_DER_MAX_BYTES);
|
||
|
memcpy(s_key, p, sz);
|
||
|
*s_key_len = sz;
|
||
|
|
||
|
error:
|
||
|
x509_crt_free(&cert);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
static int check_bl3x_cert(unsigned char *buf, size_t len,
|
||
|
const unsigned char *i_key, size_t i_key_len,
|
||
|
const char *hash_oid, unsigned char *sha)
|
||
|
{
|
||
|
const unsigned char *p;
|
||
|
size_t sz;
|
||
|
int err, flags;
|
||
|
|
||
|
x509_crt_init(&cert);
|
||
|
|
||
|
/* Parse BL31 content certificate */
|
||
|
err = x509_crt_parse(&cert, buf, len);
|
||
|
if (err) {
|
||
|
ERROR("Content certificate parse error %d.\n", err);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Verify certificate */
|
||
|
err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
|
||
|
if (err) {
|
||
|
ERROR("Content certificate verification error %d. Flags: "
|
||
|
"0x%x.\n", err, flags);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Check that content certificate has been signed with the content
|
||
|
* certificate key corresponding to this image */
|
||
|
sz = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
|
||
|
p = pk_buf + sizeof(pk_buf) - sz;
|
||
|
|
||
|
if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
|
||
|
ERROR("Content certificate not signed with content "
|
||
|
"certificate key\n");
|
||
|
err = 1;
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
/* Extract image hash from certificate */
|
||
|
err = x509_get_crt_ext_data(&p, &sz, &cert, hash_oid);
|
||
|
if (err) {
|
||
|
ERROR("Cannot read hash from certificate\n");
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
assert(sz == SHA_BYTES + 2);
|
||
|
|
||
|
/* Skip the tag and length bytes and copy the hash */
|
||
|
p += 2;
|
||
|
memcpy(sha, p, SHA_BYTES);
|
||
|
|
||
|
error:
|
||
|
x509_crt_free(&cert);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
#endif /* IMAGE_BL2 */
|
||
|
|
||
|
/*
|
||
|
* Calculate the hash of the image and check it against the hash extracted
|
||
|
* previously from the certificate
|
||
|
*
|
||
|
* Parameters:
|
||
|
* buf: buffer where image is loaded
|
||
|
* len: size of the image
|
||
|
* sha: matching hash (extracted from the image certificate)
|
||
|
*
|
||
|
* Return: 0 = match, Otherwise = mismatch
|
||
|
*/
|
||
|
static int check_bl_img(unsigned char *buf, size_t len,
|
||
|
const unsigned char *sha)
|
||
|
{
|
||
|
unsigned char img_sha[SHA_BYTES];
|
||
|
|
||
|
/* Calculate the hash of the image */
|
||
|
sha256(buf, len, img_sha, 0);
|
||
|
|
||
|
/* Match the hash with the one extracted from the certificate */
|
||
|
if (memcmp(img_sha, sha, SHA_BYTES)) {
|
||
|
ERROR("Image hash mismatch\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Object verification function
|
||
|
*
|
||
|
* The id parameter will indicate the expected format of the object
|
||
|
* (certificate, image, etc).
|
||
|
*
|
||
|
* Return: 0 = success, Otherwise = error
|
||
|
*/
|
||
|
static int polarssl_mod_verify(unsigned int id, uintptr_t obj, size_t len)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
switch (id) {
|
||
|
#if IMAGE_BL1
|
||
|
case AUTH_BL2_IMG_CERT:
|
||
|
ret = check_bl2_cert((unsigned char *)obj, len);
|
||
|
break;
|
||
|
case AUTH_BL2_IMG:
|
||
|
ret = check_bl_img((unsigned char *)obj, len, sha_bl2);
|
||
|
break;
|
||
|
#endif /* IMAGE_BL1 */
|
||
|
|
||
|
#if IMAGE_BL2
|
||
|
case AUTH_TRUSTED_KEY_CERT:
|
||
|
ret = check_trusted_key_cert((unsigned char *)obj, len);
|
||
|
break;
|
||
|
case AUTH_BL30_KEY_CERT:
|
||
|
ret = check_bl3x_key_cert((unsigned char *)obj, len,
|
||
|
tz_world_pk, tz_world_pk_len,
|
||
|
content_pk, &content_pk_len,
|
||
|
BL30_CONTENT_CERT_PK_OID);
|
||
|
break;
|
||
|
case AUTH_BL31_KEY_CERT:
|
||
|
ret = check_bl3x_key_cert((unsigned char *)obj, len,
|
||
|
tz_world_pk, tz_world_pk_len,
|
||
|
content_pk, &content_pk_len,
|
||
|
BL31_CONTENT_CERT_PK_OID);
|
||
|
break;
|
||
|
case AUTH_BL32_KEY_CERT:
|
||
|
ret = check_bl3x_key_cert((unsigned char *)obj, len,
|
||
|
tz_world_pk, tz_world_pk_len,
|
||
|
content_pk, &content_pk_len,
|
||
|
BL32_CONTENT_CERT_PK_OID);
|
||
|
break;
|
||
|
case AUTH_BL33_KEY_CERT:
|
||
|
ret = check_bl3x_key_cert((unsigned char *)obj, len,
|
||
|
ntz_world_pk, ntz_world_pk_len,
|
||
|
content_pk, &content_pk_len,
|
||
|
BL33_CONTENT_CERT_PK_OID);
|
||
|
break;
|
||
|
case AUTH_BL30_IMG_CERT:
|
||
|
ret = check_bl3x_cert((unsigned char *)obj, len,
|
||
|
content_pk, content_pk_len,
|
||
|
BL30_HASH_OID, sha_bl30);
|
||
|
break;
|
||
|
case AUTH_BL31_IMG_CERT:
|
||
|
ret = check_bl3x_cert((unsigned char *)obj, len,
|
||
|
content_pk, content_pk_len,
|
||
|
BL31_HASH_OID, sha_bl31);
|
||
|
break;
|
||
|
case AUTH_BL32_IMG_CERT:
|
||
|
ret = check_bl3x_cert((unsigned char *)obj, len,
|
||
|
content_pk, content_pk_len,
|
||
|
BL32_HASH_OID, sha_bl32);
|
||
|
break;
|
||
|
case AUTH_BL33_IMG_CERT:
|
||
|
ret = check_bl3x_cert((unsigned char *)obj, len,
|
||
|
content_pk, content_pk_len,
|
||
|
BL33_HASH_OID, sha_bl33);
|
||
|
break;
|
||
|
case AUTH_BL30_IMG:
|
||
|
ret = check_bl_img((unsigned char *)obj, len, sha_bl30);
|
||
|
break;
|
||
|
case AUTH_BL31_IMG:
|
||
|
ret = check_bl_img((unsigned char *)obj, len, sha_bl31);
|
||
|
break;
|
||
|
case AUTH_BL32_IMG:
|
||
|
ret = check_bl_img((unsigned char *)obj, len, sha_bl32);
|
||
|
break;
|
||
|
case AUTH_BL33_IMG:
|
||
|
ret = check_bl_img((unsigned char *)obj, len, sha_bl33);
|
||
|
break;
|
||
|
#endif /* IMAGE_BL2 */
|
||
|
default:
|
||
|
ret = -1;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Module initialization function
|
||
|
*
|
||
|
* Return: 0 = success, Otherwise = error
|
||
|
*/
|
||
|
static int polarssl_mod_init(void)
|
||
|
{
|
||
|
/* Initialize the PolarSSL heap */
|
||
|
return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE);
|
||
|
}
|
||
|
|
||
|
const auth_mod_t auth_mod = {
|
||
|
.name = "PolarSSL",
|
||
|
.init = polarssl_mod_init,
|
||
|
.verify = polarssl_mod_verify
|
||
|
};
|