Home | History | Annotate | Download | only in polarssl
      1 /*
      2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are met:
      6  *
      7  * Redistributions of source code must retain the above copyright notice, this
      8  * list of conditions and the following disclaimer.
      9  *
     10  * Redistributions in binary form must reproduce the above copyright notice,
     11  * this list of conditions and the following disclaimer in the documentation
     12  * and/or other materials provided with the distribution.
     13  *
     14  * Neither the name of ARM nor the names of its contributors may be used
     15  * to endorse or promote products derived from this software without specific
     16  * prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     28  * POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 /* Authentication module based on PolarSSL */
     32 
     33 #include <stddef.h>
     34 
     35 #include <assert.h>
     36 #include <auth.h>
     37 #include <debug.h>
     38 #include <platform.h>
     39 #include <platform_def.h>
     40 #include <platform_oid.h>
     41 
     42 #include <polarssl/memory_buffer_alloc.h>
     43 #include <polarssl/oid.h>
     44 #include <polarssl/platform.h>
     45 #include <polarssl/sha256.h>
     46 #include <polarssl/x509_crt.h>
     47 
     48 /*
     49  * At each authentication stage, the module is responsible for extracting and
     50  * storing those elements (keys, hashes, etc.) that will be needed later on
     51  * during the Trusted Boot process.
     52  */
     53 
     54 /* SHA256 algorithm */
     55 #define SHA_BYTES			32
     56 
     57 /*
     58  * An 8 KB stack has been proven to be enough for the current Trusted Boot
     59  * process
     60  */
     61 #define POLARSSL_HEAP_SIZE		(8*1024)
     62 static unsigned char heap[POLARSSL_HEAP_SIZE];
     63 
     64 /*
     65  * RSA public keys:
     66  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {          1 + 3
     67  *       algorithm            AlgorithmIdentifier,  1 + 1 (sequence)
     68  *                                                + 1 + 1 + 9 (rsa oid)
     69  *                                                + 1 + 1 (params null)
     70  *       subjectPublicKey     BIT STRING }          1 + 3 + (1 + below)
     71  *  RSAPublicKey ::= SEQUENCE {                     1 + 3
     72  *      modulus           INTEGER,  -- n            1 + 3 + MPI_MAX + 1
     73  *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
     74  *  }
     75  *
     76  * POLARSSL_MPI_MAX_SIZE is set to 256 bytes (RSA-2048 bit keys) in the
     77  * configuration file
     78  */
     79 #define RSA_PUB_DER_MAX_BYTES   38 + 2 * POLARSSL_MPI_MAX_SIZE
     80 
     81 /*
     82  * Buffer for storing public keys extracted from certificates while they are
     83  * verified
     84  */
     85 static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES];
     86 
     87 /* We use this variable to parse and authenticate the certificates */
     88 static x509_crt cert;
     89 
     90 /* BL specific variables */
     91 #if IMAGE_BL1
     92 static unsigned char sha_bl2[SHA_BYTES];
     93 #elif IMAGE_BL2
     94 /* Buffers to store the hash of BL3-x images */
     95 static unsigned char sha_bl30[SHA_BYTES];
     96 static unsigned char sha_bl31[SHA_BYTES];
     97 static unsigned char sha_bl32[SHA_BYTES];
     98 static unsigned char sha_bl33[SHA_BYTES];
     99 /* Buffers to store the Trusted and Non-Trusted world public keys */
    100 static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES];
    101 static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES];
    102 static size_t tz_world_pk_len, ntz_world_pk_len;
    103 /* Buffer to store the BL3-x public keys */
    104 static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES];
    105 static size_t content_pk_len;
    106 #endif
    107 
    108 
    109 static int x509_get_crt_ext_data(const unsigned char **ext_data,
    110 				 size_t *ext_len,
    111 				 x509_crt *crt,
    112 				 const char *oid)
    113 {
    114 	int ret;
    115 	size_t len;
    116 	unsigned char *end_ext_data, *end_ext_octet;
    117 	unsigned char *p;
    118 	const unsigned char *end;
    119 	char oid_str[64];
    120 
    121 	p = crt->v3_ext.p;
    122 	end = crt->v3_ext.p + crt->v3_ext.len;
    123 
    124 	ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE);
    125 	if (ret != 0)
    126 		return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
    127 
    128 	if (end != p + len)
    129 		return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
    130 				POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
    131 
    132 	while (p < end) {
    133 		/*
    134 		 * Extension  ::=  SEQUENCE  {
    135 		 *      extnID      OBJECT IDENTIFIER,
    136 		 *      critical    BOOLEAN DEFAULT FALSE,
    137 		 *      extnValue   OCTET STRING  }
    138 		 */
    139 		x509_buf extn_oid = {0, 0, NULL};
    140 		int is_critical = 0; /* DEFAULT FALSE */
    141 
    142 		ret = asn1_get_tag(&p, end, &len,
    143 				ASN1_CONSTRUCTED | ASN1_SEQUENCE);
    144 		if (ret != 0)
    145 			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
    146 
    147 		end_ext_data = p + len;
    148 
    149 		/* Get extension ID */
    150 		extn_oid.tag = *p;
    151 
    152 		ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID);
    153 		if (ret != 0)
    154 			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
    155 
    156 		extn_oid.p = p;
    157 		p += extn_oid.len;
    158 
    159 		if ((end - p) < 1)
    160 			return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
    161 					POLARSSL_ERR_ASN1_OUT_OF_DATA;
    162 
    163 		/* Get optional critical */
    164 		ret = asn1_get_bool(&p, end_ext_data, &is_critical);
    165 		if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG))
    166 			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
    167 
    168 		/* Data should be octet string type */
    169 		ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING);
    170 		if (ret != 0)
    171 			return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret;
    172 
    173 		end_ext_octet = p + len;
    174 
    175 		if (end_ext_octet != end_ext_data)
    176 			return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
    177 					POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
    178 
    179 		/* Detect requested extension */
    180 		oid_get_numeric_string(oid_str, 64, &extn_oid);
    181 		if (memcmp(oid, oid_str, sizeof(oid)) == 0) {
    182 			*ext_data = p;
    183 			*ext_len = len;
    184 			return 0;
    185 		}
    186 
    187 		/* Next */
    188 		p = end_ext_octet;
    189 	}
    190 
    191 	if (p != end)
    192 		return POLARSSL_ERR_X509_INVALID_EXTENSIONS +
    193 				POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
    194 
    195 	return POLARSSL_ERR_X509_UNKNOWN_OID;
    196 }
    197 
    198 #if IMAGE_BL1
    199 /*
    200  * Parse and verify the BL2 certificate
    201  *
    202  * This function verifies the integrity of the BL2 certificate, checks that it
    203  * has been signed with the ROT key and extracts the BL2 hash stored in the
    204  * certificate so it can be matched later against the calculated hash.
    205  *
    206  * Return: 0 = success, Otherwise = error
    207  */
    208 static int check_bl2_cert(unsigned char *buf, size_t len)
    209 {
    210 	const unsigned char *p;
    211 	size_t sz;
    212 	int err, flags;
    213 
    214 	x509_crt_init(&cert);
    215 
    216 	/* Parse the BL2 certificate */
    217 	err = x509_crt_parse(&cert, buf, len);
    218 	if (err) {
    219 		ERROR("BL2 certificate parse error %d.\n", err);
    220 		goto error;
    221 	}
    222 
    223 	/* Check that it has been signed with the ROT key */
    224 	err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
    225 	if (err < 0) {
    226 		ERROR("Error loading ROT key in DER format %d.\n", err);
    227 		goto error;
    228 	}
    229 
    230 	sz = (size_t)err;
    231 	p = pk_buf + sizeof(pk_buf) - sz;
    232 
    233 	err = plat_match_rotpk(p, sz);
    234 	if (err) {
    235 		ERROR("ROT and BL2 certificate key mismatch\n");
    236 		goto error;
    237 	}
    238 
    239 	/* Verify certificate */
    240 	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
    241 	if (err) {
    242 		ERROR("BL2 certificate verification error %d. Flags: 0x%x.\n",
    243 				err, flags);
    244 		goto error;
    245 	}
    246 
    247 	/* Extract BL2 image hash from certificate */
    248 	err = x509_get_crt_ext_data(&p, &sz, &cert, BL2_HASH_OID);
    249 	if (err) {
    250 		ERROR("Cannot read BL2 hash from certificate\n");
    251 		goto error;
    252 	}
    253 
    254 	assert(sz == SHA_BYTES + 2);
    255 
    256 	/* Skip the tag and length bytes and copy the hash */
    257 	p += 2;
    258 	memcpy(sha_bl2, p, SHA_BYTES);
    259 
    260 error:
    261 	x509_crt_free(&cert);
    262 
    263 	return err;
    264 }
    265 #endif /* IMAGE_BL1 */
    266 
    267 #if IMAGE_BL2
    268 static int check_trusted_key_cert(unsigned char *buf, size_t len)
    269 {
    270 	const unsigned char *p;
    271 	size_t sz;
    272 	int err, flags;
    273 
    274 	x509_crt_init(&cert);
    275 
    276 	/* Parse the Trusted Key certificate */
    277 	err = x509_crt_parse(&cert, buf, len);
    278 	if (err) {
    279 		ERROR("Trusted Key certificate parse error %d.\n", err);
    280 		goto error;
    281 	}
    282 
    283 	/* Verify Trusted Key certificate */
    284 	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
    285 	if (err) {
    286 		ERROR("Trusted Key certificate verification error %d. Flags: "
    287 				"0x%x.\n", err, flags);
    288 		goto error;
    289 	}
    290 
    291 	/* Check that it has been signed with the ROT key */
    292 	err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
    293 	if (err < 0) {
    294 		ERROR("Error loading ROT key in DER format %d.\n", err);
    295 		goto error;
    296 	}
    297 
    298 	sz = (size_t)err;
    299 	p = pk_buf + sizeof(pk_buf) - sz;
    300 
    301 	if (plat_match_rotpk(p, sz)) {
    302 		ERROR("ROT and Trusted Key certificate key mismatch\n");
    303 		goto error;
    304 	}
    305 
    306 	/* Extract Trusted World key from extensions */
    307 	err = x509_get_crt_ext_data(&p, &tz_world_pk_len,
    308 			&cert, TZ_WORLD_PK_OID);
    309 	if (err) {
    310 		ERROR("Cannot read Trusted World key\n");
    311 		goto error;
    312 	}
    313 
    314 	assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
    315 	memcpy(tz_world_pk, p, tz_world_pk_len);
    316 
    317 	/* Extract Non-Trusted World key from extensions */
    318 	err = x509_get_crt_ext_data(&p, &ntz_world_pk_len,
    319 			&cert, NTZ_WORLD_PK_OID);
    320 	if (err) {
    321 		ERROR("Cannot read Non-Trusted World key\n");
    322 		goto error;
    323 	}
    324 
    325 	assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES);
    326 	memcpy(ntz_world_pk, p, ntz_world_pk_len);
    327 
    328 error:
    329 	x509_crt_free(&cert);
    330 
    331 	return err;
    332 }
    333 
    334 static int check_bl3x_key_cert(const unsigned char *buf, size_t len,
    335 			       const unsigned char *i_key, size_t i_key_len,
    336 			       unsigned char *s_key, size_t *s_key_len,
    337 			       const char *key_oid)
    338 {
    339 	const unsigned char *p;
    340 	size_t sz;
    341 	int err, flags;
    342 
    343 	x509_crt_init(&cert);
    344 
    345 	/* Parse key certificate */
    346 	err = x509_crt_parse(&cert, buf, len);
    347 	if (err) {
    348 		ERROR("Key certificate parse error %d.\n", err);
    349 		goto error;
    350 	}
    351 
    352 	/* Verify certificate */
    353 	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
    354 	if (err) {
    355 		ERROR("Key certificate verification error %d. Flags: "
    356 				"0x%x.\n", err, flags);
    357 		goto error;
    358 	}
    359 
    360 	/* Check that the certificate has been signed by the issuer */
    361 	err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
    362 	if (err < 0) {
    363 		ERROR("Error loading key in DER format %d.\n", err);
    364 		goto error;
    365 	}
    366 
    367 	sz = (size_t)err;
    368 	p = pk_buf + sizeof(pk_buf) - sz;
    369 	if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
    370 		ERROR("Key certificate not signed with issuer key\n");
    371 		err = 1;
    372 		goto error;
    373 	}
    374 
    375 	/* Get the content certificate key */
    376 	err = x509_get_crt_ext_data(&p, &sz, &cert, key_oid);
    377 	if (err) {
    378 		ERROR("Extension %s not found in Key certificate\n", key_oid);
    379 		goto error;
    380 	}
    381 
    382 	assert(sz <= RSA_PUB_DER_MAX_BYTES);
    383 	memcpy(s_key, p, sz);
    384 	*s_key_len = sz;
    385 
    386 error:
    387 	x509_crt_free(&cert);
    388 
    389 	return err;
    390 }
    391 
    392 static int check_bl3x_cert(unsigned char *buf, size_t len,
    393 		       const unsigned char *i_key, size_t i_key_len,
    394 		       const char *hash_oid, unsigned char *sha)
    395 {
    396 	const unsigned char *p;
    397 	size_t sz;
    398 	int err, flags;
    399 
    400 	x509_crt_init(&cert);
    401 
    402 	/* Parse BL31 content certificate */
    403 	err = x509_crt_parse(&cert, buf, len);
    404 	if (err) {
    405 		ERROR("Content certificate parse error %d.\n", err);
    406 		goto error;
    407 	}
    408 
    409 	/* Verify certificate */
    410 	err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL);
    411 	if (err) {
    412 		ERROR("Content certificate verification error %d. Flags: "
    413 				"0x%x.\n", err, flags);
    414 		goto error;
    415 	}
    416 
    417 	/* Check that content certificate has been signed with the content
    418 	 * certificate key corresponding to this image */
    419 	sz = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf));
    420 	p = pk_buf + sizeof(pk_buf) - sz;
    421 
    422 	if ((sz != i_key_len) || memcmp(p, i_key, sz)) {
    423 		ERROR("Content certificate not signed with content "
    424 				"certificate key\n");
    425 		err = 1;
    426 		goto error;
    427 	}
    428 
    429 	/* Extract image hash from certificate */
    430 	err = x509_get_crt_ext_data(&p, &sz, &cert, hash_oid);
    431 	if (err) {
    432 		ERROR("Cannot read hash from certificate\n");
    433 		goto error;
    434 	}
    435 
    436 	assert(sz == SHA_BYTES + 2);
    437 
    438 	/* Skip the tag and length bytes and copy the hash */
    439 	p += 2;
    440 	memcpy(sha, p, SHA_BYTES);
    441 
    442 error:
    443 	x509_crt_free(&cert);
    444 
    445 	return err;
    446 }
    447 #endif /* IMAGE_BL2 */
    448 
    449 /*
    450  * Calculate the hash of the image and check it against the hash extracted
    451  * previously from the certificate
    452  *
    453  * Parameters:
    454  *   buf: buffer where image is loaded
    455  *   len: size of the image
    456  *   sha: matching hash (extracted from the image certificate)
    457  *
    458  * Return: 0 = match, Otherwise = mismatch
    459  */
    460 static int check_bl_img(unsigned char *buf, size_t len,
    461 			const unsigned char *sha)
    462 {
    463 	unsigned char img_sha[SHA_BYTES];
    464 
    465 	/* Calculate the hash of the image */
    466 	sha256(buf, len, img_sha, 0);
    467 
    468 	/* Match the hash with the one extracted from the certificate */
    469 	if (memcmp(img_sha, sha, SHA_BYTES)) {
    470 		ERROR("Image hash mismatch\n");
    471 		return 1;
    472 	}
    473 
    474 	return 0;
    475 }
    476 
    477 /*
    478  * Object verification function
    479  *
    480  * The id parameter will indicate the expected format of the object
    481  * (certificate, image, etc).
    482  *
    483  * Return: 0 = success, Otherwise = error
    484  */
    485 static int polarssl_mod_verify(unsigned int id, uintptr_t obj, size_t len)
    486 {
    487 	int ret;
    488 
    489 	switch (id) {
    490 #if IMAGE_BL1
    491 	case AUTH_BL2_IMG_CERT:
    492 		ret = check_bl2_cert((unsigned char *)obj, len);
    493 		break;
    494 	case AUTH_BL2_IMG:
    495 		ret = check_bl_img((unsigned char *)obj, len, sha_bl2);
    496 		break;
    497 #endif /* IMAGE_BL1 */
    498 
    499 #if IMAGE_BL2
    500 	case AUTH_TRUSTED_KEY_CERT:
    501 		ret = check_trusted_key_cert((unsigned char *)obj, len);
    502 		break;
    503 	case AUTH_BL30_KEY_CERT:
    504 		ret = check_bl3x_key_cert((unsigned char *)obj, len,
    505 				tz_world_pk, tz_world_pk_len,
    506 				content_pk, &content_pk_len,
    507 				BL30_CONTENT_CERT_PK_OID);
    508 		break;
    509 	case AUTH_BL31_KEY_CERT:
    510 		ret = check_bl3x_key_cert((unsigned char *)obj, len,
    511 				tz_world_pk, tz_world_pk_len,
    512 				content_pk, &content_pk_len,
    513 				BL31_CONTENT_CERT_PK_OID);
    514 		break;
    515 	case AUTH_BL32_KEY_CERT:
    516 		ret = check_bl3x_key_cert((unsigned char *)obj, len,
    517 				tz_world_pk, tz_world_pk_len,
    518 				content_pk, &content_pk_len,
    519 				BL32_CONTENT_CERT_PK_OID);
    520 		break;
    521 	case AUTH_BL33_KEY_CERT:
    522 		ret = check_bl3x_key_cert((unsigned char *)obj, len,
    523 				ntz_world_pk, ntz_world_pk_len,
    524 				content_pk, &content_pk_len,
    525 				BL33_CONTENT_CERT_PK_OID);
    526 		break;
    527 	case AUTH_BL30_IMG_CERT:
    528 		ret = check_bl3x_cert((unsigned char *)obj, len,
    529 				content_pk, content_pk_len,
    530 				BL30_HASH_OID, sha_bl30);
    531 		break;
    532 	case AUTH_BL31_IMG_CERT:
    533 		ret = check_bl3x_cert((unsigned char *)obj, len,
    534 				content_pk, content_pk_len,
    535 				BL31_HASH_OID, sha_bl31);
    536 		break;
    537 	case AUTH_BL32_IMG_CERT:
    538 		ret = check_bl3x_cert((unsigned char *)obj, len,
    539 				content_pk, content_pk_len,
    540 				BL32_HASH_OID, sha_bl32);
    541 		break;
    542 	case AUTH_BL33_IMG_CERT:
    543 		ret = check_bl3x_cert((unsigned char *)obj, len,
    544 				content_pk, content_pk_len,
    545 				BL33_HASH_OID, sha_bl33);
    546 		break;
    547 	case AUTH_BL30_IMG:
    548 		ret = check_bl_img((unsigned char *)obj, len, sha_bl30);
    549 		break;
    550 	case AUTH_BL31_IMG:
    551 		ret = check_bl_img((unsigned char *)obj, len, sha_bl31);
    552 		break;
    553 	case AUTH_BL32_IMG:
    554 		ret = check_bl_img((unsigned char *)obj, len, sha_bl32);
    555 		break;
    556 	case AUTH_BL33_IMG:
    557 		ret = check_bl_img((unsigned char *)obj, len, sha_bl33);
    558 		break;
    559 #endif /* IMAGE_BL2 */
    560 	default:
    561 		ret = -1;
    562 		break;
    563 	}
    564 
    565 	return ret;
    566 }
    567 
    568 /*
    569  * Module initialization function
    570  *
    571  * Return: 0 = success, Otherwise = error
    572  */
    573 static int polarssl_mod_init(void)
    574 {
    575 	/* Initialize the PolarSSL heap */
    576 	return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE);
    577 }
    578 
    579 const auth_mod_t auth_mod = {
    580 	.name = "PolarSSL",
    581 	.init = polarssl_mod_init,
    582 	.verify = polarssl_mod_verify
    583 };
    584