blob: 62675db9893afc4db962ff5cf43b978fae22a84a [file] [log] [blame]
Shashank Mittal64d04852014-08-28 15:02:46 -07001/*
Sridhar Parasuram8b792422015-07-05 11:38:13 -07002 * 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
Sridhar Parasuram8b792422015-07-05 11:38:13 -07005 * modification, are permitted provided that the following conditions are
6 * met:
Shashank Mittal64d04852014-08-28 15:02:46 -07007 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
Sridhar Parasuram8b792422015-07-05 11:38:13 -07009 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Shashank Mittal64d04852014-08-28 15:02:46 -070028 */
29
30#include <stdlib.h>
Channagoud Kadabi1420b002015-01-13 14:48:12 -080031#include <stdint.h>
Shashank Mittal64d04852014-08-28 15:02:46 -070032#include <crypto_hash.h>
33#include <boot_verifier.h>
34#include <image_verify.h>
35#include <mmc.h>
36#include <oem_keystore.h>
37#include <openssl/asn1t.h>
38#include <openssl/x509.h>
39#include <partition_parser.h>
40#include <rsa.h>
41#include <string.h>
Channagoud Kadabi1420b002015-01-13 14:48:12 -080042#include <openssl/err.h>
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +053043#include <platform.h>
Sridhar Parasuram8b792422015-07-05 11:38:13 -070044#include <qseecom_lk_api.h>
45#include <secapp_loader.h>
46#include <target.h>
Shashank Mittal64d04852014-08-28 15:02:46 -070047
48static KEYSTORE *oem_keystore;
49static KEYSTORE *user_keystore;
50static uint32_t dev_boot_state = RED;
Shashank Mittal64d04852014-08-28 15:02:46 -070051char KEYSTORE_PTN_NAME[] = "keystore";
Sridhar Parasuram8b792422015-07-05 11:38:13 -070052RSA *rsa_from_cert = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -070053
54ASN1_SEQUENCE(AUTH_ATTR) ={
55 ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
56 ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
57} ASN1_SEQUENCE_END(AUTH_ATTR)
58IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
59
60 ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
61 ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
Unnati Gandhi93334992015-02-25 19:38:38 +053062 ASN1_SIMPLE(VERIFIED_BOOT_SIG, certificate, X509),
Shashank Mittal64d04852014-08-28 15:02:46 -070063 ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
64 ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
65 ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
66 } ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
67IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
68
69 ASN1_SEQUENCE(KEY) = {
70 ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
71 ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
72 }ASN1_SEQUENCE_END(KEY)
73IMPLEMENT_ASN1_FUNCTIONS(KEY);
74
75ASN1_SEQUENCE(KEYBAG) = {
76 ASN1_SIMPLE(KEYBAG, mykey, KEY)
77}ASN1_SEQUENCE_END(KEYBAG)
78IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
79
80 ASN1_SEQUENCE(KEYSTORE_INNER) = {
81 ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
82 ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
83 } ASN1_SEQUENCE_END(KEYSTORE_INNER)
84IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
85
86 ASN1_SEQUENCE(KEYSTORE) = {
87 ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
88 ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
89 ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
90 } ASN1_SEQUENCE_END(KEYSTORE)
91IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
92
93static uint32_t read_der_message_length(unsigned char* input)
94{
95 uint32_t len = 0;
96 int pos = 0;
97 uint8_t len_bytes = 1;
98
99 /* Check if input starts with Sequence id (0X30) */
100 if(input[pos] != 0x30)
101 return len;
102 pos++;
103
104 /* A length of 0xAABBCCDD in DER encoded messages would be sequence of
105 following octets 0xAA, 0xBB, 0XCC, 0XDD.
106
107 To read length - read each octet and shift left by 1 octect before
108 reading next octet.
109 */
110 /* check if short or long length form */
111 if(input[pos] & 0x80)
112 {
113 len_bytes = (input[pos] & ~(0x80));
114 pos++;
115 }
116 while(len_bytes)
117 {
118 /* Shift len by 1 octet */
119 len = len << 8;
120
121 /* Read next octet */
122 len = len | input[pos];
123 pos++; len_bytes--;
124 }
125
126 /* Add number of octets representing sequence id and length */
127 len += pos;
128
129 return len;
130}
131
132static int verify_digest(unsigned char* input, unsigned char *digest, int hash_size)
133{
134 int ret = -1;
Shashank Mittale6797222014-09-19 18:58:43 -0700135 X509_SIG *sig = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700136 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700137 if(!len)
138 {
139 dprintf(CRITICAL, "boot_verifier: Signature length is invalid.\n");
140 return ret;
141 }
142
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800143 sig = d2i_X509_SIG(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700144 if(sig == NULL)
145 {
146 dprintf(CRITICAL, "boot_verifier: Reading digest failed\n");
147 return ret;
148 }
149
150 if(sig->digest->length != SHA256_SIZE)
151 {
152 dprintf(CRITICAL, "boot_verifier: Digest length error.\n");
153 goto verify_digest_error;
154 }
155
156 if(memcmp(sig->digest->data, digest, hash_size) == 0)
157 ret = 0;
158
159verify_digest_error:
160 if(sig != NULL)
161 X509_SIG_free(sig);
162
163 return ret;
164}
165
166static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
167{
168 return i2d_AUTH_ATTR(input, &ptr);
169}
170
171static bool boot_verify_compare_sha256(unsigned char *image_ptr,
172 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
173{
174 int ret = -1;
175 bool auth = false;
176 unsigned char *plain_text = NULL;
177 unsigned int digest[8];
178
179 plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
180 if (plain_text == NULL) {
181 dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
182 goto cleanup;
183 }
184
185 /* Calculate SHA256sum */
186 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
187 (unsigned char *)&digest);
188
189 /* Find digest from the image */
190 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
191
192 dprintf(SPEW, "boot_verifier: Return of RSA_public_decrypt = %d\n",
193 ret);
194
195 ret = verify_digest(plain_text, (unsigned char*)digest, SHA256_SIZE);
196 if(ret == 0)
197 {
198 auth = true;
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700199#ifdef TZ_SAVE_KERNEL_HASH
200 save_kernel_hash((unsigned char *) &digest, CRYPTO_AUTH_ALG_SHA256);
201#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700202 }
203
204cleanup:
205 if (plain_text != NULL)
206 free(plain_text);
207 EVP_cleanup();
208 CRYPTO_cleanup_all_ex_data();
209 ERR_remove_thread_state(NULL);
210 return auth;
211
212}
213
214static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
215 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
216{
217 bool ret = false;
218 uint32_t len;
219 int shift_bytes;
220 RSA *rsa = NULL;
221 bool keystore_verification = false;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700222 EVP_PKEY* key = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700223
224 if(!strcmp(pname, "keystore"))
225 keystore_verification = true;
226
227 /* Verify target name */
228 if(strncmp((char*)(sig->auth_attr->target->data), pname,
229 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800230 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700231 {
232 dprintf(CRITICAL,
233 "boot_verifier: verification failure due to target name mismatch\n");
234 goto verify_image_with_sig_error;
235 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700236 /* Read image size from signature */
237 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
238 len->data as 0X00CCBBAA and len->length as 3(octets).
239
240 To read len we need to left shift data to number of missing octets and
241 then change it to host long
242 */
243 len = *((uint32_t*)sig->auth_attr->len->data);
244 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
245 if(shift_bytes > 0) {
246 len = len << (shift_bytes*8);
247 }
248 len = ntohl(len);
249
250 /* Verify image size*/
251 if(len != img_size)
252 {
253 dprintf(CRITICAL,
254 "boot_verifier: image length is different. (%d vs %d)\n",
255 len, img_size);
256 goto verify_image_with_sig_error;
257 }
258
259 /* append attribute to image */
260 if(!keystore_verification)
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700261 {
262 // verifying a non keystore partition
Shashank Mittal64d04852014-08-28 15:02:46 -0700263 img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
264 sig->auth_attr);
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700265 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700266
267 /* compare SHA256SUM of image with value in signature */
268 if(ks != NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700269 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700270 // use rsa from keystore
271 rsa = ks->mykeybag->mykey->key_material;
272 }
273 else
274 {
275 dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
276 ASSERT(0);
277 }
278
279 // verify boot.img with rsa from oem keystore
280 if((ret = boot_verify_compare_sha256(img_addr, img_size,
281 (unsigned char*)sig->sig->data, rsa)))
282
283 {
284 dprintf(SPEW, "Verified boot.img with oem keystore\n");
285 boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
286 goto verify_image_with_sig_done;
287 }
288 else
289 {
290 dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
291 // get the public key from certificate in boot.img
292 if ((key = X509_get_pubkey(sig->certificate)))
293 {
294 // convert to rsa key format
295 dprintf(INFO, "RSA KEY found from the embedded certificate\n");
296 rsa = EVP_PKEY_get1_RSA(key);
297 rsa_from_cert = rsa;
298 }
299 else
300 {
301 dprintf(CRITICAL, "Unable to extract public key from certificate\n");
302 ASSERT(0);
303 }
304 }
305
306 // verify boot.img with rsa from embedded certificate
307 if ((ret = boot_verify_compare_sha256(img_addr, img_size,
308 (unsigned char*)sig->sig->data, rsa)))
309 {
310 dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
311 boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
312 goto verify_image_with_sig_done;
313 }
314 else
315 {
316 dprintf(INFO, "verified for red state\n");
317 boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
318 goto verify_image_with_sig_done;
Shashank Mittal64d04852014-08-28 15:02:46 -0700319 }
320
321verify_image_with_sig_error:
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700322verify_image_with_sig_done:
Shashank Mittal64d04852014-08-28 15:02:46 -0700323 return ret;
324}
325
326static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
327{
328 int ret = 0;
329 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
330 if (ks_inner == NULL)
331 return ret;
332 ASN1_INTEGER *tmp_version = ks_inner->version;
333 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
334
335 ks_inner->version = ks->version;
336 ks_inner->mykeybag = ks->mykeybag;
337 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
338
339 ks_inner->version = tmp_version;
340 ks_inner->mykeybag = tmp_mykeybag;
341
342 if(ks_inner != NULL)
343 KEYSTORE_INNER_free(ks_inner);
344 return ret;
345}
346
347static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
348{
349 bool ret = false;
350 unsigned char * ptr = ks_addr;
351 uint32_t inner_len = encode_inner_keystore(ptr, ks);
352 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
353 oem_keystore);
354 return ret;
355}
356
357static void read_oem_keystore()
358{
Shashank Mittale6797222014-09-19 18:58:43 -0700359 KEYSTORE *ks = NULL;
360 uint32_t len = 0;
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800361 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700362
Shashank Mittal64d04852014-08-28 15:02:46 -0700363 if(oem_keystore != NULL)
364 return;
365
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800366 len = read_der_message_length((unsigned char *)input);
Shashank Mittale6797222014-09-19 18:58:43 -0700367 if(!len)
368 {
369 dprintf(CRITICAL, "boot_verifier: oem keystore length is invalid.\n");
370 return;
371 }
372
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800373 ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700374 if(ks != NULL)
375 {
376 oem_keystore = ks;
377 user_keystore = ks;
378 }
379}
380
Shashank Mittal64d04852014-08-28 15:02:46 -0700381uint32_t boot_verify_keystore_init()
382{
383 /* Read OEM Keystore */
384 read_oem_keystore();
385
Shashank Mittal64d04852014-08-28 15:02:46 -0700386 return dev_boot_state;
387}
388
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700389bool send_rot_command()
390{
391 int ret = 0;
392 const unsigned char *input;
393 char *rot_input = NULL;
394 unsigned int digest[8];
395 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
396 uint32_t boot_device_state = boot_verify_get_state();
397 uint32_t len = 0;
398 int app_handle = 0;
399 km_set_rot_req_t *read_req;
400 km_set_rot_rsp_t read_rsp;
401 app_handle = get_secapp_handle();
402 switch (boot_device_state)
403 {
404 case GREEN:
405 // Locked device and boot.img verified against OEM keystore.
406 // Send hash of OEM KEYSTORE + Boot device state
407 input = OEM_KEYSTORE;
408 len = read_der_message_length((unsigned char *)input) + sizeof(uint32_t);
409 if(!(rot_input = malloc(len)))
410 {
411 dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
412 ASSERT(0);
413 }
414 snprintf(rot_input, len, "%s%ul", input, boot_device_state);
415 break;
416 case YELLOW:
417 case RED:
418 // Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
419 // Send hash of certificate + boot device state
420 if (rsa_from_cert)
421 len = RSA_size(rsa_from_cert);
422 else
423 {
424 dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
425 ASSERT(0);
426 }
427 hash_find((unsigned char *)rsa_from_cert, len, (unsigned char *) &digest, auth_algo);
428 len = sizeof(digest) + sizeof(unsigned int);
429 if(!(rot_input = malloc(len)))
430 {
431 dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
432 ASSERT(0);
433 }
434 memcpy(rot_input, digest, sizeof(digest));
435 memcpy(rot_input + sizeof(digest), (unsigned char *) boot_device_state, sizeof(unsigned int));
436 break;
437 case ORANGE:
438 // Unlocked device and no verification done.
439 // Send the hash of boot device state
440 input = NULL;
441 len = sizeof(uint32_t);
442 if(!(rot_input = malloc(len)))
443 {
444 dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
445 ASSERT(0);
446 }
447 snprintf(rot_input, len, "%ul", boot_device_state);
448 break;
449 }
450
451 hash_find((unsigned char *) rot_input, len, (unsigned char *)&digest, auth_algo);
452 if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(digest))))
453 {
454 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
455 ASSERT(0);
456 }
457
458 void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
459 // set ROT stucture
460 read_req->cmd_id = KEYMASTER_SET_ROT;
461 read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
462 read_req->rot_size = sizeof(digest);
463 // copy the digest
464 memcpy(cpy_ptr, (void *) &digest, sizeof(digest));
465 dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
466
467 ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(digest), (void*) &read_rsp, sizeof(read_rsp));
468 if (ret < 0 || read_rsp.status < 0)
469 {
470 dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
471 free(read_req);
472 free(rot_input);
473 return false;
474 }
475 dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
476 free(read_req);
477 free(rot_input);
478 return true;
479}
480
Shashank Mittal64d04852014-08-28 15:02:46 -0700481bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
482{
483 bool ret = false;
484 VERIFIED_BOOT_SIG *sig = NULL;
485 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
486 uint32_t sig_len = read_der_message_length(sig_addr);
487
488 if(dev_boot_state == ORANGE)
489 {
490 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
491 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
492 return false;
493 }
494
495 if(!sig_len)
496 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700497 dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
Shashank Mittal64d04852014-08-28 15:02:46 -0700498 goto verify_image_error;
499 }
500
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800501 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700502 {
503 dprintf(CRITICAL,
504 "boot_verifier: verification failure due to target name mismatch\n");
505 goto verify_image_error;
506 }
507
508 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
509
510verify_image_error:
511 if(sig != NULL)
512 VERIFIED_BOOT_SIG_free(sig);
Shashank Mittal64d04852014-08-28 15:02:46 -0700513 return ret;
514}
515
516void boot_verify_send_event(uint32_t event)
517{
518 switch(event)
519 {
520 case BOOT_INIT:
521 dev_boot_state = GREEN;
522 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700523 case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
524 dev_boot_state = GREEN;
525 break;
526 case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
Shashank Mittal64d04852014-08-28 15:02:46 -0700527 if(dev_boot_state == GREEN)
528 dev_boot_state = YELLOW;
529 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700530 case BOOTIMG_VERIFICATION_FAIL:
Shashank Mittal64d04852014-08-28 15:02:46 -0700531 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
532 dev_boot_state = RED;
533 break;
534 case DEV_UNLOCK:
535 dev_boot_state = ORANGE;
536 break;
537 case USER_DENIES:
538 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
539 dev_boot_state = RED;
540 break;
541 }
542}
543
544uint32_t boot_verify_get_state()
545{
546 return dev_boot_state;
547}
548
549void boot_verify_print_state()
550{
551 switch(dev_boot_state)
552 {
553 case GREEN:
554 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
555 break;
556 case ORANGE:
557 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
558 break;
559 case YELLOW:
560 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
561 break;
562 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530563 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");
564
Shashank Mittal64d04852014-08-28 15:02:46 -0700565 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
566 break;
567 }
568}
569
570bool boot_verify_validate_keystore(unsigned char * user_addr)
571{
572 bool ret = false;
573 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700574 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700575 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700576 if(!len)
577 {
578 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
579 return ret;
580 }
581
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800582 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700583 if(ks != NULL)
584 {
585 ret = true;
586 }
587 return ret;
588}
589
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800590static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700591{
Shashank Mittal64d04852014-08-28 15:02:46 -0700592 if(list == NULL || entry == NULL)
593 return false;
594
595 while(*list != NULL)
596 {
597 if(!strcmp(entry, *list))
598 return true;
599
600 list++;
601 }
602
603 return false;
604}