blob: 02b21220efd58f2506beaf694c01bd2d9d84e912 [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;
lijuangf214e222015-07-16 20:06:22 +080053unsigned char fp[EVP_MAX_MD_SIZE];
54uint32_t fp_size;
Shashank Mittal64d04852014-08-28 15:02:46 -070055
56ASN1_SEQUENCE(AUTH_ATTR) ={
57 ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
58 ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
59} ASN1_SEQUENCE_END(AUTH_ATTR)
60IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
61
62 ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
63 ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
Unnati Gandhi93334992015-02-25 19:38:38 +053064 ASN1_SIMPLE(VERIFIED_BOOT_SIG, certificate, X509),
Shashank Mittal64d04852014-08-28 15:02:46 -070065 ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
66 ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
67 ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
68 } ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
69IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
70
71 ASN1_SEQUENCE(KEY) = {
72 ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
73 ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
74 }ASN1_SEQUENCE_END(KEY)
75IMPLEMENT_ASN1_FUNCTIONS(KEY);
76
77ASN1_SEQUENCE(KEYBAG) = {
78 ASN1_SIMPLE(KEYBAG, mykey, KEY)
79}ASN1_SEQUENCE_END(KEYBAG)
80IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
81
82 ASN1_SEQUENCE(KEYSTORE_INNER) = {
83 ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
84 ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
85 } ASN1_SEQUENCE_END(KEYSTORE_INNER)
86IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
87
88 ASN1_SEQUENCE(KEYSTORE) = {
89 ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
90 ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
91 ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
92 } ASN1_SEQUENCE_END(KEYSTORE)
93IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
94
95static uint32_t read_der_message_length(unsigned char* input)
96{
97 uint32_t len = 0;
98 int pos = 0;
99 uint8_t len_bytes = 1;
100
101 /* Check if input starts with Sequence id (0X30) */
102 if(input[pos] != 0x30)
103 return len;
104 pos++;
105
106 /* A length of 0xAABBCCDD in DER encoded messages would be sequence of
107 following octets 0xAA, 0xBB, 0XCC, 0XDD.
108
109 To read length - read each octet and shift left by 1 octect before
110 reading next octet.
111 */
112 /* check if short or long length form */
113 if(input[pos] & 0x80)
114 {
115 len_bytes = (input[pos] & ~(0x80));
116 pos++;
117 }
118 while(len_bytes)
119 {
120 /* Shift len by 1 octet */
121 len = len << 8;
122
123 /* Read next octet */
124 len = len | input[pos];
125 pos++; len_bytes--;
126 }
127
128 /* Add number of octets representing sequence id and length */
129 len += pos;
130
131 return len;
132}
133
134static int verify_digest(unsigned char* input, unsigned char *digest, int hash_size)
135{
136 int ret = -1;
Shashank Mittale6797222014-09-19 18:58:43 -0700137 X509_SIG *sig = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700138 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700139 if(!len)
140 {
141 dprintf(CRITICAL, "boot_verifier: Signature length is invalid.\n");
142 return ret;
143 }
144
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800145 sig = d2i_X509_SIG(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700146 if(sig == NULL)
147 {
148 dprintf(CRITICAL, "boot_verifier: Reading digest failed\n");
149 return ret;
150 }
151
152 if(sig->digest->length != SHA256_SIZE)
153 {
154 dprintf(CRITICAL, "boot_verifier: Digest length error.\n");
155 goto verify_digest_error;
156 }
157
158 if(memcmp(sig->digest->data, digest, hash_size) == 0)
159 ret = 0;
160
161verify_digest_error:
162 if(sig != NULL)
163 X509_SIG_free(sig);
164
165 return ret;
166}
167
168static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
169{
170 return i2d_AUTH_ATTR(input, &ptr);
171}
172
173static bool boot_verify_compare_sha256(unsigned char *image_ptr,
174 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
175{
176 int ret = -1;
177 bool auth = false;
178 unsigned char *plain_text = NULL;
179 unsigned int digest[8];
180
181 plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
182 if (plain_text == NULL) {
183 dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
184 goto cleanup;
185 }
186
187 /* Calculate SHA256sum */
188 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
189 (unsigned char *)&digest);
190
191 /* Find digest from the image */
192 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
193
194 dprintf(SPEW, "boot_verifier: Return of RSA_public_decrypt = %d\n",
195 ret);
196
197 ret = verify_digest(plain_text, (unsigned char*)digest, SHA256_SIZE);
198 if(ret == 0)
199 {
200 auth = true;
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700201#ifdef TZ_SAVE_KERNEL_HASH
202 save_kernel_hash((unsigned char *) &digest, CRYPTO_AUTH_ALG_SHA256);
203#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700204 }
205
206cleanup:
207 if (plain_text != NULL)
208 free(plain_text);
209 EVP_cleanup();
210 CRYPTO_cleanup_all_ex_data();
211 ERR_remove_thread_state(NULL);
212 return auth;
213
214}
215
216static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
217 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
218{
219 bool ret = false;
220 uint32_t len;
221 int shift_bytes;
222 RSA *rsa = NULL;
223 bool keystore_verification = false;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700224 EVP_PKEY* key = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700225
226 if(!strcmp(pname, "keystore"))
227 keystore_verification = true;
228
229 /* Verify target name */
230 if(strncmp((char*)(sig->auth_attr->target->data), pname,
231 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800232 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700233 {
234 dprintf(CRITICAL,
235 "boot_verifier: verification failure due to target name mismatch\n");
236 goto verify_image_with_sig_error;
237 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700238 /* Read image size from signature */
239 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
240 len->data as 0X00CCBBAA and len->length as 3(octets).
241
242 To read len we need to left shift data to number of missing octets and
243 then change it to host long
244 */
245 len = *((uint32_t*)sig->auth_attr->len->data);
246 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
247 if(shift_bytes > 0) {
248 len = len << (shift_bytes*8);
249 }
250 len = ntohl(len);
251
252 /* Verify image size*/
253 if(len != img_size)
254 {
255 dprintf(CRITICAL,
256 "boot_verifier: image length is different. (%d vs %d)\n",
257 len, img_size);
258 goto verify_image_with_sig_error;
259 }
260
261 /* append attribute to image */
262 if(!keystore_verification)
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700263 {
264 // verifying a non keystore partition
Shashank Mittal64d04852014-08-28 15:02:46 -0700265 img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
266 sig->auth_attr);
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700267 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700268
269 /* compare SHA256SUM of image with value in signature */
270 if(ks != NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700271 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700272 // use rsa from keystore
273 rsa = ks->mykeybag->mykey->key_material;
274 }
275 else
276 {
277 dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
278 ASSERT(0);
279 }
280
281 // verify boot.img with rsa from oem keystore
282 if((ret = boot_verify_compare_sha256(img_addr, img_size,
283 (unsigned char*)sig->sig->data, rsa)))
284
285 {
286 dprintf(SPEW, "Verified boot.img with oem keystore\n");
287 boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
288 goto verify_image_with_sig_done;
289 }
290 else
291 {
292 dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
293 // get the public key from certificate in boot.img
294 if ((key = X509_get_pubkey(sig->certificate)))
295 {
296 // convert to rsa key format
297 dprintf(INFO, "RSA KEY found from the embedded certificate\n");
298 rsa = EVP_PKEY_get1_RSA(key);
299 rsa_from_cert = rsa;
300 }
301 else
302 {
303 dprintf(CRITICAL, "Unable to extract public key from certificate\n");
304 ASSERT(0);
305 }
306 }
307
308 // verify boot.img with rsa from embedded certificate
309 if ((ret = boot_verify_compare_sha256(img_addr, img_size,
310 (unsigned char*)sig->sig->data, rsa)))
311 {
312 dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
313 boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
314 goto verify_image_with_sig_done;
315 }
316 else
317 {
318 dprintf(INFO, "verified for red state\n");
319 boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
320 goto verify_image_with_sig_done;
Shashank Mittal64d04852014-08-28 15:02:46 -0700321 }
322
323verify_image_with_sig_error:
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700324verify_image_with_sig_done:
Shashank Mittal64d04852014-08-28 15:02:46 -0700325 return ret;
326}
327
328static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
329{
330 int ret = 0;
331 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
332 if (ks_inner == NULL)
333 return ret;
334 ASN1_INTEGER *tmp_version = ks_inner->version;
335 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
336
337 ks_inner->version = ks->version;
338 ks_inner->mykeybag = ks->mykeybag;
339 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
340
341 ks_inner->version = tmp_version;
342 ks_inner->mykeybag = tmp_mykeybag;
343
344 if(ks_inner != NULL)
345 KEYSTORE_INNER_free(ks_inner);
346 return ret;
347}
348
349static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
350{
351 bool ret = false;
352 unsigned char * ptr = ks_addr;
353 uint32_t inner_len = encode_inner_keystore(ptr, ks);
354 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
355 oem_keystore);
356 return ret;
357}
358
359static void read_oem_keystore()
360{
Shashank Mittale6797222014-09-19 18:58:43 -0700361 KEYSTORE *ks = NULL;
362 uint32_t len = 0;
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800363 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700364
Shashank Mittal64d04852014-08-28 15:02:46 -0700365 if(oem_keystore != NULL)
366 return;
367
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800368 len = read_der_message_length((unsigned char *)input);
Shashank Mittale6797222014-09-19 18:58:43 -0700369 if(!len)
370 {
371 dprintf(CRITICAL, "boot_verifier: oem keystore length is invalid.\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 oem_keystore = ks;
379 user_keystore = ks;
380 }
381}
382
Shashank Mittal64d04852014-08-28 15:02:46 -0700383uint32_t boot_verify_keystore_init()
384{
385 /* Read OEM Keystore */
386 read_oem_keystore();
387
Shashank Mittal64d04852014-08-28 15:02:46 -0700388 return dev_boot_state;
389}
390
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700391bool send_rot_command()
392{
393 int ret = 0;
394 const unsigned char *input;
395 char *rot_input = NULL;
396 unsigned int digest[8];
397 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
398 uint32_t boot_device_state = boot_verify_get_state();
399 uint32_t len = 0;
400 int app_handle = 0;
401 km_set_rot_req_t *read_req;
402 km_set_rot_rsp_t read_rsp;
403 app_handle = get_secapp_handle();
404 switch (boot_device_state)
405 {
406 case GREEN:
407 // Locked device and boot.img verified against OEM keystore.
408 // Send hash of OEM KEYSTORE + Boot device state
409 input = OEM_KEYSTORE;
410 len = read_der_message_length((unsigned char *)input) + sizeof(uint32_t);
411 if(!(rot_input = malloc(len)))
412 {
413 dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
414 ASSERT(0);
415 }
416 snprintf(rot_input, len, "%s%ul", input, boot_device_state);
417 break;
418 case YELLOW:
419 case RED:
420 // Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
421 // Send hash of certificate + boot device state
422 if (rsa_from_cert)
423 len = RSA_size(rsa_from_cert);
424 else
425 {
426 dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
427 ASSERT(0);
428 }
429 hash_find((unsigned char *)rsa_from_cert, len, (unsigned char *) &digest, auth_algo);
430 len = sizeof(digest) + sizeof(unsigned int);
431 if(!(rot_input = malloc(len)))
432 {
433 dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
434 ASSERT(0);
435 }
436 memcpy(rot_input, digest, sizeof(digest));
437 memcpy(rot_input + sizeof(digest), (unsigned char *) boot_device_state, sizeof(unsigned int));
438 break;
439 case ORANGE:
440 // Unlocked device and no verification done.
441 // Send the hash of boot device state
442 input = NULL;
443 len = sizeof(uint32_t);
444 if(!(rot_input = malloc(len)))
445 {
446 dprintf(CRITICAL, "Failed to allocate memory for ROT command data\n");
447 ASSERT(0);
448 }
449 snprintf(rot_input, len, "%ul", boot_device_state);
450 break;
451 }
452
453 hash_find((unsigned char *) rot_input, len, (unsigned char *)&digest, auth_algo);
454 if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(digest))))
455 {
456 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
457 ASSERT(0);
458 }
459
460 void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
461 // set ROT stucture
462 read_req->cmd_id = KEYMASTER_SET_ROT;
463 read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
464 read_req->rot_size = sizeof(digest);
465 // copy the digest
466 memcpy(cpy_ptr, (void *) &digest, sizeof(digest));
467 dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
468
469 ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(digest), (void*) &read_rsp, sizeof(read_rsp));
470 if (ret < 0 || read_rsp.status < 0)
471 {
472 dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
473 free(read_req);
474 free(rot_input);
475 return false;
476 }
477 dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
478 free(read_req);
479 free(rot_input);
480 return true;
481}
482
lijuangf214e222015-07-16 20:06:22 +0800483unsigned char* get_boot_fingerprint(unsigned int* buf_size)
484{
485 *buf_size = fp_size;
486
487 return fp;
488}
489
Shashank Mittal64d04852014-08-28 15:02:46 -0700490bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
491{
492 bool ret = false;
lijuangf214e222015-07-16 20:06:22 +0800493 X509 *cert = NULL;
494 const EVP_MD *fp_type = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700495 VERIFIED_BOOT_SIG *sig = NULL;
496 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
497 uint32_t sig_len = read_der_message_length(sig_addr);
498
499 if(dev_boot_state == ORANGE)
500 {
501 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
502 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
503 return false;
504 }
505
506 if(!sig_len)
507 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700508 dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
Shashank Mittal64d04852014-08-28 15:02:46 -0700509 goto verify_image_error;
510 }
511
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800512 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700513 {
514 dprintf(CRITICAL,
515 "boot_verifier: verification failure due to target name mismatch\n");
516 goto verify_image_error;
517 }
518
lijuangf214e222015-07-16 20:06:22 +0800519 cert = sig->certificate;
520 fp_type = EVP_sha1();
521 if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
522 dprintf(INFO,"Fail to create certificate fingerprint.\n");
523 }
524
Shashank Mittal64d04852014-08-28 15:02:46 -0700525 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
526
527verify_image_error:
528 if(sig != NULL)
529 VERIFIED_BOOT_SIG_free(sig);
Shashank Mittal64d04852014-08-28 15:02:46 -0700530 return ret;
531}
532
533void boot_verify_send_event(uint32_t event)
534{
535 switch(event)
536 {
537 case BOOT_INIT:
538 dev_boot_state = GREEN;
539 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700540 case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
541 dev_boot_state = GREEN;
542 break;
543 case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
Shashank Mittal64d04852014-08-28 15:02:46 -0700544 if(dev_boot_state == GREEN)
545 dev_boot_state = YELLOW;
546 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700547 case BOOTIMG_VERIFICATION_FAIL:
Shashank Mittal64d04852014-08-28 15:02:46 -0700548 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
549 dev_boot_state = RED;
550 break;
551 case DEV_UNLOCK:
552 dev_boot_state = ORANGE;
553 break;
554 case USER_DENIES:
555 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
556 dev_boot_state = RED;
557 break;
558 }
559}
560
561uint32_t boot_verify_get_state()
562{
563 return dev_boot_state;
564}
565
566void boot_verify_print_state()
567{
568 switch(dev_boot_state)
569 {
570 case GREEN:
571 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
572 break;
573 case ORANGE:
574 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
575 break;
576 case YELLOW:
577 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
578 break;
579 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530580 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");
581
Shashank Mittal64d04852014-08-28 15:02:46 -0700582 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
583 break;
584 }
585}
586
587bool boot_verify_validate_keystore(unsigned char * user_addr)
588{
589 bool ret = false;
590 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700591 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700592 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700593 if(!len)
594 {
595 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
596 return ret;
597 }
598
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800599 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700600 if(ks != NULL)
601 {
602 ret = true;
603 }
604 return ret;
605}
606
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800607static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700608{
Shashank Mittal64d04852014-08-28 15:02:46 -0700609 if(list == NULL || entry == NULL)
610 return false;
611
612 while(*list != NULL)
613 {
614 if(!strcmp(entry, *list))
615 return true;
616
617 list++;
618 }
619
620 return false;
621}