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 
x509_get_crt_ext_data(const unsigned char ** ext_data,size_t * ext_len,x509_crt * crt,const char * oid)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  */
check_bl2_cert(unsigned char * buf,size_t len)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
check_trusted_key_cert(unsigned char * buf,size_t len)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 
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)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 
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)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  */
check_bl_img(unsigned char * buf,size_t len,const unsigned char * sha)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  */
polarssl_mod_verify(unsigned int id,uintptr_t obj,size_t len)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  */
polarssl_mod_init(void)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