blob: b167d70a0b3588624fa79bc35ee60768f5ec3d96 [file] [log] [blame]
Shashank Mittal64d04852014-08-28 15:02:46 -07001/*
Channagoud Kadabi1420b002015-01-13 14:48:12 -08002 * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
Shashank Mittal64d04852014-08-28 15:02:46 -07003 *
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>
Channagoud Kadabi1420b002015-01-13 14:48:12 -080029#include <stdint.h>
Shashank Mittal64d04852014-08-28 15:02:46 -070030#include <crypto_hash.h>
31#include <boot_verifier.h>
32#include <image_verify.h>
33#include <mmc.h>
34#include <oem_keystore.h>
35#include <openssl/asn1t.h>
36#include <openssl/x509.h>
37#include <partition_parser.h>
38#include <rsa.h>
39#include <string.h>
Channagoud Kadabi1420b002015-01-13 14:48:12 -080040#include <openssl/err.h>
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +053041#include <platform.h>
Shashank Mittal64d04852014-08-28 15:02:46 -070042
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -070043#define ASN1_ENCODED_SHA256_SIZE 0x33
44#define ASN1_ENCODED_SHA256_OFFSET 0x13
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -070045#define ASN1_SIGNATURE_BUFFER_SZ mmc_page_size()
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -070046
Shashank Mittal64d04852014-08-28 15:02:46 -070047static KEYSTORE *oem_keystore;
48static KEYSTORE *user_keystore;
49static uint32_t dev_boot_state = RED;
Shashank Mittal64d04852014-08-28 15:02:46 -070050char KEYSTORE_PTN_NAME[] = "keystore";
51
Channagoud Kadabi1420b002015-01-13 14:48:12 -080052static const char *VERIFIED_FLASH_ALLOWED_PTN[] = {
Shashank Mittal64d04852014-08-28 15:02:46 -070053 "aboot",
54 "boot",
55 "recovery",
56 "system",
57 NULL };
58
59ASN1_SEQUENCE(AUTH_ATTR) ={
60 ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
61 ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
62} ASN1_SEQUENCE_END(AUTH_ATTR)
63IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
64
65 ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
66 ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
Unnati Gandhi93334992015-02-25 19:38:38 +053067 ASN1_SIMPLE(VERIFIED_BOOT_SIG, certificate, X509),
Shashank Mittal64d04852014-08-28 15:02:46 -070068 ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
69 ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
70 ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
71 } ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
72IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
73
74 ASN1_SEQUENCE(KEY) = {
75 ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
76 ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
77 }ASN1_SEQUENCE_END(KEY)
78IMPLEMENT_ASN1_FUNCTIONS(KEY);
79
80ASN1_SEQUENCE(KEYBAG) = {
81 ASN1_SIMPLE(KEYBAG, mykey, KEY)
82}ASN1_SEQUENCE_END(KEYBAG)
83IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
84
85 ASN1_SEQUENCE(KEYSTORE_INNER) = {
86 ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
87 ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
88 } ASN1_SEQUENCE_END(KEYSTORE_INNER)
89IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
90
91 ASN1_SEQUENCE(KEYSTORE) = {
92 ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
93 ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
94 ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
95 } ASN1_SEQUENCE_END(KEYSTORE)
96IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
97
98static uint32_t read_der_message_length(unsigned char* input)
99{
100 uint32_t len = 0;
101 int pos = 0;
102 uint8_t len_bytes = 1;
103
104 /* Check if input starts with Sequence id (0X30) */
105 if(input[pos] != 0x30)
106 return len;
107 pos++;
108
109 /* A length of 0xAABBCCDD in DER encoded messages would be sequence of
110 following octets 0xAA, 0xBB, 0XCC, 0XDD.
111
112 To read length - read each octet and shift left by 1 octect before
113 reading next octet.
114 */
115 /* check if short or long length form */
116 if(input[pos] & 0x80)
117 {
118 len_bytes = (input[pos] & ~(0x80));
119 pos++;
120 }
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700121
Shashank Mittal64d04852014-08-28 15:02:46 -0700122 while(len_bytes)
123 {
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700124 /* Shift len by 1 octet, make sure to check unsigned int overflow */
125 if (len <= (UINT_MAX >> 8))
126 len <<= 8;
127 else
128 {
129 dprintf(CRITICAL, "Error: Length exceeding max size of uintmax\n");
130 return 0;
131 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700132
133 /* Read next octet */
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700134 if (pos < (int) ASN1_SIGNATURE_BUFFER_SZ)
135 len = len | input[pos];
136 else
137 {
138 dprintf(CRITICAL, "Error: Pos index exceeding the input buffer size\n");
139 return 0;
140 }
141
Shashank Mittal64d04852014-08-28 15:02:46 -0700142 pos++; len_bytes--;
143 }
144
145 /* Add number of octets representing sequence id and length */
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700146 if ((UINT_MAX - pos) > len)
147 len += pos;
148 else
149 {
150 dprintf(CRITICAL, "Error: Len overflows UINT_MAX value\n");
151 return 0;
152 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700153
154 return len;
155}
156
Shashank Mittal64d04852014-08-28 15:02:46 -0700157static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
158{
159 return i2d_AUTH_ATTR(input, &ptr);
160}
161
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700162bool boot_verify_compare_sha256(unsigned char *image_ptr,
Shashank Mittal64d04852014-08-28 15:02:46 -0700163 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
164{
165 int ret = -1;
166 bool auth = false;
167 unsigned char *plain_text = NULL;
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700168
169 /* The magic numbers here are drawn from the PKCS#1 standard and are the ASN.1
170 *encoding of the SHA256 object identifier that is required for a PKCS#1
171 * signature.*/
172 uint8_t digest[ASN1_ENCODED_SHA256_SIZE] = {0x30, 0x31, 0x30, 0x0d, 0x06,
173 0x09, 0x60, 0x86, 0x48, 0x01,
174 0x65, 0x03, 0x04, 0x02, 0x01,
175 0x05, 0x00, 0x04, 0x20};
Shashank Mittal64d04852014-08-28 15:02:46 -0700176
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
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700183 /* Calculate SHA256 of image and place it into the ASN.1 structure*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700184 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700185 digest + ASN1_ENCODED_SHA256_OFFSET);
Shashank Mittal64d04852014-08-28 15:02:46 -0700186
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700187 /* Find digest from the image. This performs the PKCS#1 padding checks up to
188 * but not including the ASN.1 OID and hash function check. The return value
189 * is not positive for a failure or the length of the part after the padding */
Shashank Mittal64d04852014-08-28 15:02:46 -0700190 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
191
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700192 /* Make sure the length returned from rsa decrypt is same as x509 signature format
193 * otherwise the signature is invalid and we fail
194 */
195 if (ret != ASN1_ENCODED_SHA256_SIZE)
196 {
197 dprintf(CRITICAL, "boot_verifier: Signature decrypt failed! Signature invalid = %d\n",
Shashank Mittal64d04852014-08-28 15:02:46 -0700198 ret);
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700199 goto cleanup;
200 }
201 /* So plain_text contains the ASN.1 encoded hash from the signature and
202 * digest contains the value that this should be for the image that we're
203 * verifying, so compare them.*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700204
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700205 ret = memcmp(plain_text, digest, ASN1_ENCODED_SHA256_SIZE);
Shashank Mittal64d04852014-08-28 15:02:46 -0700206 if(ret == 0)
207 {
208 auth = true;
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700209#ifdef TZ_SAVE_KERNEL_HASH
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700210 save_kernel_hash((unsigned char *) digest + ASN1_ENCODED_SHA256_OFFSET, CRYPTO_AUTH_ALG_SHA256);
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700211#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700212 }
213
214cleanup:
215 if (plain_text != NULL)
216 free(plain_text);
217 EVP_cleanup();
218 CRYPTO_cleanup_all_ex_data();
219 ERR_remove_thread_state(NULL);
220 return auth;
221
222}
223
224static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
225 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
226{
227 bool ret = false;
228 uint32_t len;
229 int shift_bytes;
230 RSA *rsa = NULL;
231 bool keystore_verification = false;
232
233 if(!strcmp(pname, "keystore"))
234 keystore_verification = true;
235
236 /* Verify target name */
237 if(strncmp((char*)(sig->auth_attr->target->data), pname,
238 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800239 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700240 {
241 dprintf(CRITICAL,
242 "boot_verifier: verification failure due to target name mismatch\n");
243 goto verify_image_with_sig_error;
244 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700245 /* Read image size from signature */
246 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
247 len->data as 0X00CCBBAA and len->length as 3(octets).
248
249 To read len we need to left shift data to number of missing octets and
250 then change it to host long
251 */
252 len = *((uint32_t*)sig->auth_attr->len->data);
253 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
254 if(shift_bytes > 0) {
255 len = len << (shift_bytes*8);
256 }
257 len = ntohl(len);
258
259 /* Verify image size*/
260 if(len != img_size)
261 {
262 dprintf(CRITICAL,
263 "boot_verifier: image length is different. (%d vs %d)\n",
264 len, img_size);
265 goto verify_image_with_sig_error;
266 }
267
268 /* append attribute to image */
269 if(!keystore_verification)
270 img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
271 sig->auth_attr);
272
273 /* compare SHA256SUM of image with value in signature */
274 if(ks != NULL)
275 rsa = ks->mykeybag->mykey->key_material;
276
277 ret = boot_verify_compare_sha256(img_addr, img_size,
278 (unsigned char*)sig->sig->data, rsa);
279
280 if(!ret)
281 {
282 dprintf(CRITICAL,
283 "boot_verifier: Image verification failed.\n");
284 }
285
286verify_image_with_sig_error:
287 return ret;
288}
289
290static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
291{
292 int ret = 0;
293 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
294 if (ks_inner == NULL)
295 return ret;
296 ASN1_INTEGER *tmp_version = ks_inner->version;
297 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
298
299 ks_inner->version = ks->version;
300 ks_inner->mykeybag = ks->mykeybag;
301 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
302
303 ks_inner->version = tmp_version;
304 ks_inner->mykeybag = tmp_mykeybag;
305
306 if(ks_inner != NULL)
307 KEYSTORE_INNER_free(ks_inner);
308 return ret;
309}
310
311static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
312{
313 bool ret = false;
314 unsigned char * ptr = ks_addr;
315 uint32_t inner_len = encode_inner_keystore(ptr, ks);
316 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
317 oem_keystore);
318 return ret;
319}
320
321static void read_oem_keystore()
322{
Shashank Mittale6797222014-09-19 18:58:43 -0700323 KEYSTORE *ks = NULL;
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700324 uint32_t len = sizeof(OEM_KEYSTORE);
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800325 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700326
Shashank Mittal64d04852014-08-28 15:02:46 -0700327 if(oem_keystore != NULL)
328 return;
329
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800330 ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700331 if(ks != NULL)
332 {
333 oem_keystore = ks;
334 user_keystore = ks;
335 }
336}
337
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700338static int read_user_keystore_ptn(uint8_t *keystore_buf)
Shashank Mittal64d04852014-08-28 15:02:46 -0700339{
340 int index = INVALID_PTN;
341 unsigned long long ptn = 0;
342
343 index = partition_get_index(KEYSTORE_PTN_NAME);
344 ptn = partition_get_offset(index);
345 if(ptn == 0) {
346 dprintf(CRITICAL, "boot_verifier: No keystore partition found\n");
347 return -1;
348 }
349
350 if (mmc_read(ptn, (unsigned int *) keystore_buf, mmc_page_size())) {
351 dprintf(CRITICAL, "boot_verifier: Cannot read user keystore\n");
352 return -1;
353 }
354 return 0;
355}
356
357static void read_user_keystore(unsigned char *user_addr)
358{
359 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700360 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700361 uint32_t len = read_der_message_length(input);
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700362
Shashank Mittale6797222014-09-19 18:58:43 -0700363 if(!len)
364 {
365 dprintf(CRITICAL, "boot_verifier: user keystore length is invalid.\n");
366 return;
367 }
368
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700369 if (len > ASN1_SIGNATURE_BUFFER_SZ)
370 {
371 dprintf(CRITICAL, "boot_verifier: user keystore exceeds size signature buffer\n");
372 return;
373 }
374
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800375 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700376 if(ks != NULL)
377 {
378 if(verify_keystore(user_addr, ks) == false)
379 {
380 dprintf(CRITICAL, "boot_verifier: Keystore verification failed!\n");
381 boot_verify_send_event(KEYSTORE_VERIFICATION_FAIL);
382 }
383 else
384 dprintf(CRITICAL, "boot_verifier: Keystore verification success!\n");
385 user_keystore = ks;
386 }
387 else
388 {
389 user_keystore = oem_keystore;
390 }
391}
392
393uint32_t boot_verify_keystore_init()
394{
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700395 uint8_t *keystore_buf = NULL;
396
Shashank Mittal64d04852014-08-28 15:02:46 -0700397 /* Read OEM Keystore */
398 read_oem_keystore();
399
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700400 keystore_buf = memalign(ASN1_SIGNATURE_BUFFER_SZ, CACHE_LINE);
401 ASSERT(keystore_buf);
402
Shashank Mittal64d04852014-08-28 15:02:46 -0700403 /* Read User Keystore */
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700404 if(!read_user_keystore_ptn(keystore_buf))
Shashank Mittal64d04852014-08-28 15:02:46 -0700405 read_user_keystore((unsigned char *)keystore_buf);
406 return dev_boot_state;
407}
408
409bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
410{
411 bool ret = false;
412 VERIFIED_BOOT_SIG *sig = NULL;
413 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700414 uint32_t sig_len = 0;
415 unsigned char *signature = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700416
417 if(dev_boot_state == ORANGE)
418 {
419 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
420 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
421 return false;
422 }
423
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700424 signature = malloc(ASN1_SIGNATURE_BUFFER_SZ);
425 ASSERT(signature);
426
427 /* Copy the signature from scratch memory to buffer */
428 memcpy(signature, sig_addr, ASN1_SIGNATURE_BUFFER_SZ);
429 sig_len = read_der_message_length(signature);
430
Shashank Mittal64d04852014-08-28 15:02:46 -0700431 if(!sig_len)
432 {
433 dprintf(CRITICAL, "boot_verifier: Error while reading singature length.\n");
434 goto verify_image_error;
435 }
436
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700437 if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
438 {
439 dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
440 goto verify_image_error;
441 }
442
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800443 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700444 {
445 dprintf(CRITICAL,
446 "boot_verifier: verification failure due to target name mismatch\n");
447 goto verify_image_error;
448 }
449
450 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
451
452verify_image_error:
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700453 free(signature);
Shashank Mittal64d04852014-08-28 15:02:46 -0700454 if(sig != NULL)
455 VERIFIED_BOOT_SIG_free(sig);
456 if(!ret)
457 boot_verify_send_event(BOOT_VERIFICATION_FAIL);
458 return ret;
459}
460
461void boot_verify_send_event(uint32_t event)
462{
463 switch(event)
464 {
465 case BOOT_INIT:
466 dev_boot_state = GREEN;
467 break;
468 case KEYSTORE_VERIFICATION_FAIL:
469 if(dev_boot_state == GREEN)
470 dev_boot_state = YELLOW;
471 break;
472 case BOOT_VERIFICATION_FAIL:
473 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
474 dev_boot_state = RED;
475 break;
476 case DEV_UNLOCK:
477 dev_boot_state = ORANGE;
478 break;
479 case USER_DENIES:
480 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
481 dev_boot_state = RED;
482 break;
483 }
484}
485
486uint32_t boot_verify_get_state()
487{
488 return dev_boot_state;
489}
490
491void boot_verify_print_state()
492{
493 switch(dev_boot_state)
494 {
495 case GREEN:
496 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
497 break;
498 case ORANGE:
499 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
500 break;
501 case YELLOW:
502 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
503 break;
504 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530505 display_fbcon_message("Security Error: This phone has been flashed with unauthorized software & is locked. Call your mobile operator for additional support.Please note that repair/return for this issue may have additional cost.\n");
506
Shashank Mittal64d04852014-08-28 15:02:46 -0700507 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
508 break;
509 }
510}
511
512bool boot_verify_validate_keystore(unsigned char * user_addr)
513{
514 bool ret = false;
515 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700516 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700517 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700518 if(!len)
519 {
520 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
521 return ret;
522 }
523
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800524 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700525 if(ks != NULL)
526 {
527 ret = true;
528 }
529 return ret;
530}
531
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800532static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700533{
Shashank Mittal64d04852014-08-28 15:02:46 -0700534 if(list == NULL || entry == NULL)
535 return false;
536
537 while(*list != NULL)
538 {
539 if(!strcmp(entry, *list))
540 return true;
541
542 list++;
543 }
544
545 return false;
546}
547
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800548bool boot_verify_flash_allowed(const char * entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700549{
550 return check_list(VERIFIED_FLASH_ALLOWED_PTN, entry);
551}
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700552
553KEYSTORE *boot_gerity_get_oem_keystore()
554{
555 read_oem_keystore();
556 return oem_keystore;
557}