blob: e099f50cdf3626a360debde8892016edb8eefd52 [file] [log] [blame]
Juan Castillo9c25a402015-01-13 12:21:04 +00001/*
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)
62static 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 */
85static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES];
86
87/* We use this variable to parse and authenticate the certificates */
88static x509_crt cert;
89
90/* BL specific variables */
91#if IMAGE_BL1
92static unsigned char sha_bl2[SHA_BYTES];
93#elif IMAGE_BL2
94/* Buffers to store the hash of BL3-x images */
95static unsigned char sha_bl30[SHA_BYTES];
96static unsigned char sha_bl31[SHA_BYTES];
97static unsigned char sha_bl32[SHA_BYTES];
98static unsigned char sha_bl33[SHA_BYTES];
99/* Buffers to store the Trusted and Non-Trusted world public keys */
100static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES];
101static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES];
102static size_t tz_world_pk_len, ntz_world_pk_len;
103/* Buffer to store the BL3-x public keys */
104static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES];
105static size_t content_pk_len;
106#endif
107
108
109static 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 */
208static 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
260error:
261 x509_crt_free(&cert);
262
263 return err;
264}
265#endif /* IMAGE_BL1 */
266
267#if IMAGE_BL2
268static 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
328error:
329 x509_crt_free(&cert);
330
331 return err;
332}
333
334static 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
386error:
387 x509_crt_free(&cert);
388
389 return err;
390}
391
392static 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
442error:
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 */
460static 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 */
485static 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 */
573static int polarssl_mod_init(void)
574{
575 /* Initialize the PolarSSL heap */
576 return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE);
577}
578
579const auth_mod_t auth_mod = {
580 .name = "PolarSSL",
581 .init = polarssl_mod_init,
582 .verify = polarssl_mod_verify
583};