aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJuan Castillo <juan.castillo@arm.com>2015-01-13 12:21:04 +0000
committerDan Handley <dan.handley@arm.com>2015-01-28 18:27:54 +0000
commitdb6071c99b100e7393a769277d5b5dfdf43aaf9b (patch)
treebfdaaf14df0453d2c363beaae90639d37e4e4d92 /common
parente509d05728ac0a625e67d62197ad8bef73db6d88 (diff)
downloadtrusted-firmware-a-db6071c99b100e7393a769277d5b5dfdf43aaf9b.tar.gz
TBB: add PolarSSL based authentication module
This patch implements an authentication module based on the PolarSSL library (v1.3.9) to verify the Chain of Trust when Trusted Boot is enabled. PolarSSL sources must be fetched separately. The POLARSSL_DIR build option may be used to indicate the path to the PolarSSL main directory (this directory must contain the 'include' and 'library' subdirectories). To be able to build PolarSSL sources as a part of the Trusted Firmware build process, the DISABLE_PEDANTIC flag in polarssl.mk will tell the build system to remove the -pedantic option from the CFLAGS. Inclusion of PolarSSL increases the memory requirements of the BL1 and BL2 images. The following are the changes made to the FVP and Juno platforms to cater for this when TRUSTED_BOARD_BOOT is defined: Changes on FVP: - BL1 and BL2 stacks have been increased to 4 KB - BL1(rw) section has been increased to 32 KB. - BL2 memory region has been increased to 112 KB Changes on Juno: - BL1 and BL2 stacks have been increased to 4 KB - BL1(rw) section has been increased to 32 KB. - Trusted ROM region in Flash has been increased to 128 KB. - BL2 memory region has been increased to 116 KB Change-Id: Ie87d80d43408eb6239c4acd0ec5ab2120e4e9e80
Diffstat (limited to 'common')
-rw-r--r--common/auth/polarssl/polarssl.c583
-rw-r--r--common/auth/polarssl/polarssl.mk69
-rw-r--r--common/auth/polarssl/polarssl_config.h85
3 files changed, 737 insertions, 0 deletions
diff --git a/common/auth/polarssl/polarssl.c b/common/auth/polarssl/polarssl.c
new file mode 100644
index 0000000000..e099f50cdf
--- /dev/null
+++ b/common/auth/polarssl/polarssl.c
@@ -0,0 +1,583 @@
+/*
+ * 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
+};
diff --git a/common/auth/polarssl/polarssl.mk b/common/auth/polarssl/polarssl.mk
new file mode 100644
index 0000000000..f7d92ea8d2
--- /dev/null
+++ b/common/auth/polarssl/polarssl.mk
@@ -0,0 +1,69 @@
+#
+# 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.
+#
+
+# POLARSSL_DIR must be set to the PolarSSL main directory (it must contain
+# the 'include' and 'library' subdirectories).
+ifeq (${POLARSSL_DIR},)
+ $(error Error: POLARSSL_DIR not set)
+endif
+
+INCLUDES += -I${POLARSSL_DIR}/include \
+ -Icommon/auth/polarssl
+
+POLARSSL_CONFIG_FILE := "<polarssl_config.h>"
+$(eval $(call add_define,POLARSSL_CONFIG_FILE))
+
+POLARSSL_SOURCES := $(addprefix ${POLARSSL_DIR}/library/, \
+ asn1parse.c \
+ asn1write.c \
+ bignum.c \
+ md.c \
+ md_wrap.c \
+ memory_buffer_alloc.c \
+ oid.c \
+ pk.c \
+ pk_wrap.c \
+ pkparse.c \
+ pkwrite.c \
+ platform.c \
+ rsa.c \
+ sha1.c \
+ sha256.c \
+ x509.c \
+ x509_crt.c \
+ )
+
+BL1_SOURCES += ${POLARSSL_SOURCES} \
+ common/auth/polarssl/polarssl.c
+
+BL2_SOURCES += ${POLARSSL_SOURCES} \
+ common/auth/polarssl/polarssl.c
+
+DISABLE_PEDANTIC := 1
diff --git a/common/auth/polarssl/polarssl_config.h b/common/auth/polarssl/polarssl_config.h
new file mode 100644
index 0000000000..531e084531
--- /dev/null
+++ b/common/auth/polarssl/polarssl_config.h
@@ -0,0 +1,85 @@
+/*
+ * 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 __POLARSSL_CONFIG_H__
+#define __POLARSSL_CONFIG_H__
+
+
+/*
+ * 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
+
+#define POLARSSL_RSA_C
+#define POLARSSL_SHA1_C
+#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"
+
+#endif /* __POLARSSL_CONFIG_H__ */