blob: 79accbfc79e5e6e0e98561249425ac13cc9e628b [file] [log] [blame]
Shashank Mittal64d04852014-08-28 15:02:46 -07001/*
2 * Copyright (c) 2014 The Linux Foundation. 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
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in
11 * the documentation and/or other materials provided with the
12 * distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
21 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <stdlib.h>
29#include <crypto_hash.h>
30#include <boot_verifier.h>
31#include <image_verify.h>
32#include <mmc.h>
33#include <oem_keystore.h>
34#include <openssl/asn1t.h>
35#include <openssl/x509.h>
36#include <partition_parser.h>
37#include <rsa.h>
38#include <string.h>
39
40static KEYSTORE *oem_keystore;
41static KEYSTORE *user_keystore;
42static uint32_t dev_boot_state = RED;
43BUF_DMA_ALIGN(keystore_buf, 4096);
44char KEYSTORE_PTN_NAME[] = "keystore";
45
46static char *VERIFIED_FLASH_ALLOWED_PTN[] = {
47 "aboot",
48 "boot",
49 "recovery",
50 "system",
51 NULL };
52
53ASN1_SEQUENCE(AUTH_ATTR) ={
54 ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
55 ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
56} ASN1_SEQUENCE_END(AUTH_ATTR)
57IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
58
59 ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
60 ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
61 ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
62 ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
63 ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
64 } ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
65IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
66
67 ASN1_SEQUENCE(KEY) = {
68 ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
69 ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
70 }ASN1_SEQUENCE_END(KEY)
71IMPLEMENT_ASN1_FUNCTIONS(KEY);
72
73ASN1_SEQUENCE(KEYBAG) = {
74 ASN1_SIMPLE(KEYBAG, mykey, KEY)
75}ASN1_SEQUENCE_END(KEYBAG)
76IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
77
78 ASN1_SEQUENCE(KEYSTORE_INNER) = {
79 ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
80 ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
81 } ASN1_SEQUENCE_END(KEYSTORE_INNER)
82IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
83
84 ASN1_SEQUENCE(KEYSTORE) = {
85 ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
86 ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
87 ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
88 } ASN1_SEQUENCE_END(KEYSTORE)
89IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
90
91static uint32_t read_der_message_length(unsigned char* input)
92{
93 uint32_t len = 0;
94 int pos = 0;
95 uint8_t len_bytes = 1;
96
97 /* Check if input starts with Sequence id (0X30) */
98 if(input[pos] != 0x30)
99 return len;
100 pos++;
101
102 /* A length of 0xAABBCCDD in DER encoded messages would be sequence of
103 following octets 0xAA, 0xBB, 0XCC, 0XDD.
104
105 To read length - read each octet and shift left by 1 octect before
106 reading next octet.
107 */
108 /* check if short or long length form */
109 if(input[pos] & 0x80)
110 {
111 len_bytes = (input[pos] & ~(0x80));
112 pos++;
113 }
114 while(len_bytes)
115 {
116 /* Shift len by 1 octet */
117 len = len << 8;
118
119 /* Read next octet */
120 len = len | input[pos];
121 pos++; len_bytes--;
122 }
123
124 /* Add number of octets representing sequence id and length */
125 len += pos;
126
127 return len;
128}
129
130static int verify_digest(unsigned char* input, unsigned char *digest, int hash_size)
131{
132 int ret = -1;
Shashank Mittale6797222014-09-19 18:58:43 -0700133 X509_SIG *sig = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700134 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700135 if(!len)
136 {
137 dprintf(CRITICAL, "boot_verifier: Signature length is invalid.\n");
138 return ret;
139 }
140
141 sig = d2i_X509_SIG(NULL, &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700142 if(sig == NULL)
143 {
144 dprintf(CRITICAL, "boot_verifier: Reading digest failed\n");
145 return ret;
146 }
147
148 if(sig->digest->length != SHA256_SIZE)
149 {
150 dprintf(CRITICAL, "boot_verifier: Digest length error.\n");
151 goto verify_digest_error;
152 }
153
154 if(memcmp(sig->digest->data, digest, hash_size) == 0)
155 ret = 0;
156
157verify_digest_error:
158 if(sig != NULL)
159 X509_SIG_free(sig);
160
161 return ret;
162}
163
164static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
165{
166 return i2d_AUTH_ATTR(input, &ptr);
167}
168
169static bool boot_verify_compare_sha256(unsigned char *image_ptr,
170 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
171{
172 int ret = -1;
173 bool auth = false;
174 unsigned char *plain_text = NULL;
175 unsigned int digest[8];
176
177 plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
178 if (plain_text == NULL) {
179 dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
180 goto cleanup;
181 }
182
183 /* Calculate SHA256sum */
184 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
185 (unsigned char *)&digest);
186
187 /* Find digest from the image */
188 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
189
190 dprintf(SPEW, "boot_verifier: Return of RSA_public_decrypt = %d\n",
191 ret);
192
193 ret = verify_digest(plain_text, (unsigned char*)digest, SHA256_SIZE);
194 if(ret == 0)
195 {
196 auth = true;
197 }
198
199cleanup:
200 if (plain_text != NULL)
201 free(plain_text);
202 EVP_cleanup();
203 CRYPTO_cleanup_all_ex_data();
204 ERR_remove_thread_state(NULL);
205 return auth;
206
207}
208
209static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
210 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
211{
212 bool ret = false;
213 uint32_t len;
214 int shift_bytes;
215 RSA *rsa = NULL;
216 bool keystore_verification = false;
217
218 if(!strcmp(pname, "keystore"))
219 keystore_verification = true;
220
221 /* Verify target name */
222 if(strncmp((char*)(sig->auth_attr->target->data), pname,
223 sig->auth_attr->target->length) ||
224 (strlen(pname) != sig->auth_attr->target->length))
225 {
226 dprintf(CRITICAL,
227 "boot_verifier: verification failure due to target name mismatch\n");
228 goto verify_image_with_sig_error;
229 }
230
231 /* Read image size from signature */
232 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
233 len->data as 0X00CCBBAA and len->length as 3(octets).
234
235 To read len we need to left shift data to number of missing octets and
236 then change it to host long
237 */
238 len = *((uint32_t*)sig->auth_attr->len->data);
239 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
240 if(shift_bytes > 0) {
241 len = len << (shift_bytes*8);
242 }
243 len = ntohl(len);
244
245 /* Verify image size*/
246 if(len != img_size)
247 {
248 dprintf(CRITICAL,
249 "boot_verifier: image length is different. (%d vs %d)\n",
250 len, img_size);
251 goto verify_image_with_sig_error;
252 }
253
254 /* append attribute to image */
255 if(!keystore_verification)
256 img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
257 sig->auth_attr);
258
259 /* compare SHA256SUM of image with value in signature */
260 if(ks != NULL)
261 rsa = ks->mykeybag->mykey->key_material;
262
263 ret = boot_verify_compare_sha256(img_addr, img_size,
264 (unsigned char*)sig->sig->data, rsa);
265
266 if(!ret)
267 {
268 dprintf(CRITICAL,
269 "boot_verifier: Image verification failed.\n");
270 }
271
272verify_image_with_sig_error:
273 return ret;
274}
275
276static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
277{
278 int ret = 0;
279 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
280 if (ks_inner == NULL)
281 return ret;
282 ASN1_INTEGER *tmp_version = ks_inner->version;
283 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
284
285 ks_inner->version = ks->version;
286 ks_inner->mykeybag = ks->mykeybag;
287 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
288
289 ks_inner->version = tmp_version;
290 ks_inner->mykeybag = tmp_mykeybag;
291
292 if(ks_inner != NULL)
293 KEYSTORE_INNER_free(ks_inner);
294 return ret;
295}
296
297static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
298{
299 bool ret = false;
300 unsigned char * ptr = ks_addr;
301 uint32_t inner_len = encode_inner_keystore(ptr, ks);
302 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
303 oem_keystore);
304 return ret;
305}
306
307static void read_oem_keystore()
308{
Shashank Mittale6797222014-09-19 18:58:43 -0700309 KEYSTORE *ks = NULL;
310 uint32_t len = 0;
311 unsigned char *input = OEM_KEYSTORE;
312
Shashank Mittal64d04852014-08-28 15:02:46 -0700313 if(oem_keystore != NULL)
314 return;
315
Shashank Mittale6797222014-09-19 18:58:43 -0700316 len = read_der_message_length(input);
317 if(!len)
318 {
319 dprintf(CRITICAL, "boot_verifier: oem keystore length is invalid.\n");
320 return;
321 }
322
323 ks = d2i_KEYSTORE(NULL, &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700324 if(ks != NULL)
325 {
326 oem_keystore = ks;
327 user_keystore = ks;
328 }
329}
330
331static int read_user_keystore_ptn()
332{
333 int index = INVALID_PTN;
334 unsigned long long ptn = 0;
335
336 index = partition_get_index(KEYSTORE_PTN_NAME);
337 ptn = partition_get_offset(index);
338 if(ptn == 0) {
339 dprintf(CRITICAL, "boot_verifier: No keystore partition found\n");
340 return -1;
341 }
342
343 if (mmc_read(ptn, (unsigned int *) keystore_buf, mmc_page_size())) {
344 dprintf(CRITICAL, "boot_verifier: Cannot read user keystore\n");
345 return -1;
346 }
347 return 0;
348}
349
350static void read_user_keystore(unsigned char *user_addr)
351{
352 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700353 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700354 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700355 if(!len)
356 {
357 dprintf(CRITICAL, "boot_verifier: user keystore length is invalid.\n");
358 return;
359 }
360
361 ks = d2i_KEYSTORE(NULL, &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700362 if(ks != NULL)
363 {
364 if(verify_keystore(user_addr, ks) == false)
365 {
366 dprintf(CRITICAL, "boot_verifier: Keystore verification failed!\n");
367 boot_verify_send_event(KEYSTORE_VERIFICATION_FAIL);
368 }
369 else
370 dprintf(CRITICAL, "boot_verifier: Keystore verification success!\n");
371 user_keystore = ks;
372 }
373 else
374 {
375 user_keystore = oem_keystore;
376 }
377}
378
379uint32_t boot_verify_keystore_init()
380{
381 /* Read OEM Keystore */
382 read_oem_keystore();
383
384 /* Read User Keystore */
385 if(!read_user_keystore_ptn())
386 read_user_keystore((unsigned char *)keystore_buf);
387 return dev_boot_state;
388}
389
390bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
391{
392 bool ret = false;
393 VERIFIED_BOOT_SIG *sig = NULL;
394 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
395 uint32_t sig_len = read_der_message_length(sig_addr);
396
397 if(dev_boot_state == ORANGE)
398 {
399 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
400 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
401 return false;
402 }
403
404 if(!sig_len)
405 {
406 dprintf(CRITICAL, "boot_verifier: Error while reading singature length.\n");
407 goto verify_image_error;
408 }
409
410 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, &sig_addr, sig_len)) == NULL)
411 {
412 dprintf(CRITICAL,
413 "boot_verifier: verification failure due to target name mismatch\n");
414 goto verify_image_error;
415 }
416
417 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
418
419verify_image_error:
420 if(sig != NULL)
421 VERIFIED_BOOT_SIG_free(sig);
422 if(!ret)
423 boot_verify_send_event(BOOT_VERIFICATION_FAIL);
424 return ret;
425}
426
427void boot_verify_send_event(uint32_t event)
428{
429 switch(event)
430 {
431 case BOOT_INIT:
432 dev_boot_state = GREEN;
433 break;
434 case KEYSTORE_VERIFICATION_FAIL:
435 if(dev_boot_state == GREEN)
436 dev_boot_state = YELLOW;
437 break;
438 case BOOT_VERIFICATION_FAIL:
439 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
440 dev_boot_state = RED;
441 break;
442 case DEV_UNLOCK:
443 dev_boot_state = ORANGE;
444 break;
445 case USER_DENIES:
446 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
447 dev_boot_state = RED;
448 break;
449 }
450}
451
452uint32_t boot_verify_get_state()
453{
454 return dev_boot_state;
455}
456
457void boot_verify_print_state()
458{
459 switch(dev_boot_state)
460 {
461 case GREEN:
462 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
463 break;
464 case ORANGE:
465 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
466 break;
467 case YELLOW:
468 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
469 break;
470 case RED:
471 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
472 break;
473 }
474}
475
476bool boot_verify_validate_keystore(unsigned char * user_addr)
477{
478 bool ret = false;
479 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700480 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700481 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700482 if(!len)
483 {
484 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
485 return ret;
486 }
487
488 ks = d2i_KEYSTORE(NULL, &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700489 if(ks != NULL)
490 {
491 ret = true;
492 }
493 return ret;
494}
495
496static bool check_list(char**list, char* entry)
497{
498 int i = 0;
499 if(list == NULL || entry == NULL)
500 return false;
501
502 while(*list != NULL)
503 {
504 if(!strcmp(entry, *list))
505 return true;
506
507 list++;
508 }
509
510 return false;
511}
512
513bool boot_verify_flash_allowed(char * entry)
514{
515 return check_list(VERIFIED_FLASH_ALLOWED_PTN, entry);
516}