blob: 7ecbc0b9c7e4d535789b0619ffb65c78ac0bd509 [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
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -070048#define ASN1_ENCODED_SHA256_SIZE 0x33
49#define ASN1_ENCODED_SHA256_OFFSET 0x13
50
Shashank Mittal64d04852014-08-28 15:02:46 -070051static KEYSTORE *oem_keystore;
52static KEYSTORE *user_keystore;
53static uint32_t dev_boot_state = RED;
Shashank Mittal64d04852014-08-28 15:02:46 -070054char KEYSTORE_PTN_NAME[] = "keystore";
Sridhar Parasuram8b792422015-07-05 11:38:13 -070055RSA *rsa_from_cert = NULL;
lijuangf214e222015-07-16 20:06:22 +080056unsigned char fp[EVP_MAX_MD_SIZE];
57uint32_t fp_size;
Shashank Mittal64d04852014-08-28 15:02:46 -070058
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 }
121 while(len_bytes)
122 {
123 /* Shift len by 1 octet */
124 len = len << 8;
125
126 /* Read next octet */
127 len = len | input[pos];
128 pos++; len_bytes--;
129 }
130
131 /* Add number of octets representing sequence id and length */
132 len += pos;
133
134 return len;
135}
136
Shashank Mittal64d04852014-08-28 15:02:46 -0700137static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
138{
139 return i2d_AUTH_ATTR(input, &ptr);
140}
141
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700142bool boot_verify_compare_sha256(unsigned char *image_ptr,
Shashank Mittal64d04852014-08-28 15:02:46 -0700143 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
144{
145 int ret = -1;
146 bool auth = false;
147 unsigned char *plain_text = NULL;
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700148
149 /* The magic numbers here are drawn from the PKCS#1 standard and are the ASN.1
150 *encoding of the SHA256 object identifier that is required for a PKCS#1
151 * signature.*/
152 uint8_t digest[ASN1_ENCODED_SHA256_SIZE] = {0x30, 0x31, 0x30, 0x0d, 0x06,
153 0x09, 0x60, 0x86, 0x48, 0x01,
154 0x65, 0x03, 0x04, 0x02, 0x01,
155 0x05, 0x00, 0x04, 0x20};
Shashank Mittal64d04852014-08-28 15:02:46 -0700156
157 plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
158 if (plain_text == NULL) {
159 dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
160 goto cleanup;
161 }
162
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700163 /* Calculate SHA256 of image and place it into the ASN.1 structure*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700164 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700165 digest + ASN1_ENCODED_SHA256_OFFSET);
Shashank Mittal64d04852014-08-28 15:02:46 -0700166
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700167 /* Find digest from the image. This performs the PKCS#1 padding checks up to
168 * but not including the ASN.1 OID and hash function check. The return value
169 * is not positive for a failure or the length of the part after the padding */
Shashank Mittal64d04852014-08-28 15:02:46 -0700170 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
171
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700172 /* Make sure the length returned from rsa decrypt is same as x509 signature format
173 * otherwise the signature is invalid and we fail
174 */
175 if (ret != ASN1_ENCODED_SHA256_SIZE)
176 {
177 dprintf(CRITICAL, "boot_verifier: Signature decrypt failed! Signature invalid = %d\n",
Shashank Mittal64d04852014-08-28 15:02:46 -0700178 ret);
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700179 goto cleanup;
180 }
181 /* So plain_text contains the ASN.1 encoded hash from the signature and
182 * digest contains the value that this should be for the image that we're
183 * verifying, so compare them.*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700184
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700185 ret = memcmp(plain_text, digest, ASN1_ENCODED_SHA256_SIZE);
Shashank Mittal64d04852014-08-28 15:02:46 -0700186 if(ret == 0)
187 {
188 auth = true;
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700189#ifdef TZ_SAVE_KERNEL_HASH
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700190 save_kernel_hash((unsigned char *) digest + ASN1_ENCODED_SHA256_OFFSET, CRYPTO_AUTH_ALG_SHA256);
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700191#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700192 }
193
194cleanup:
195 if (plain_text != NULL)
196 free(plain_text);
197 EVP_cleanup();
198 CRYPTO_cleanup_all_ex_data();
199 ERR_remove_thread_state(NULL);
200 return auth;
201
202}
203
204static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
205 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
206{
207 bool ret = false;
208 uint32_t len;
209 int shift_bytes;
210 RSA *rsa = NULL;
211 bool keystore_verification = false;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700212 EVP_PKEY* key = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700213
214 if(!strcmp(pname, "keystore"))
215 keystore_verification = true;
216
217 /* Verify target name */
218 if(strncmp((char*)(sig->auth_attr->target->data), pname,
219 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800220 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700221 {
222 dprintf(CRITICAL,
223 "boot_verifier: verification failure due to target name mismatch\n");
224 goto verify_image_with_sig_error;
225 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700226 /* Read image size from signature */
227 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
228 len->data as 0X00CCBBAA and len->length as 3(octets).
229
230 To read len we need to left shift data to number of missing octets and
231 then change it to host long
232 */
233 len = *((uint32_t*)sig->auth_attr->len->data);
234 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
235 if(shift_bytes > 0) {
236 len = len << (shift_bytes*8);
237 }
238 len = ntohl(len);
239
240 /* Verify image size*/
241 if(len != img_size)
242 {
243 dprintf(CRITICAL,
244 "boot_verifier: image length is different. (%d vs %d)\n",
245 len, img_size);
246 goto verify_image_with_sig_error;
247 }
248
249 /* append attribute to image */
250 if(!keystore_verification)
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700251 {
252 // verifying a non keystore partition
Shashank Mittal64d04852014-08-28 15:02:46 -0700253 img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
254 sig->auth_attr);
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700255 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700256
257 /* compare SHA256SUM of image with value in signature */
258 if(ks != NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700259 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700260 // use rsa from keystore
261 rsa = ks->mykeybag->mykey->key_material;
262 }
263 else
264 {
265 dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
266 ASSERT(0);
267 }
268
269 // verify boot.img with rsa from oem keystore
270 if((ret = boot_verify_compare_sha256(img_addr, img_size,
271 (unsigned char*)sig->sig->data, rsa)))
272
273 {
274 dprintf(SPEW, "Verified boot.img with oem keystore\n");
275 boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
276 goto verify_image_with_sig_done;
277 }
278 else
279 {
280 dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
281 // get the public key from certificate in boot.img
282 if ((key = X509_get_pubkey(sig->certificate)))
283 {
284 // convert to rsa key format
285 dprintf(INFO, "RSA KEY found from the embedded certificate\n");
286 rsa = EVP_PKEY_get1_RSA(key);
287 rsa_from_cert = rsa;
288 }
289 else
290 {
291 dprintf(CRITICAL, "Unable to extract public key from certificate\n");
292 ASSERT(0);
293 }
294 }
295
296 // verify boot.img with rsa from embedded certificate
297 if ((ret = boot_verify_compare_sha256(img_addr, img_size,
298 (unsigned char*)sig->sig->data, rsa)))
299 {
300 dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
301 boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
302 goto verify_image_with_sig_done;
303 }
304 else
305 {
306 dprintf(INFO, "verified for red state\n");
307 boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
308 goto verify_image_with_sig_done;
Shashank Mittal64d04852014-08-28 15:02:46 -0700309 }
310
311verify_image_with_sig_error:
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700312verify_image_with_sig_done:
Shashank Mittal64d04852014-08-28 15:02:46 -0700313 return ret;
314}
315
316static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
317{
318 int ret = 0;
319 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
320 if (ks_inner == NULL)
321 return ret;
322 ASN1_INTEGER *tmp_version = ks_inner->version;
323 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
324
325 ks_inner->version = ks->version;
326 ks_inner->mykeybag = ks->mykeybag;
327 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
328
329 ks_inner->version = tmp_version;
330 ks_inner->mykeybag = tmp_mykeybag;
331
332 if(ks_inner != NULL)
333 KEYSTORE_INNER_free(ks_inner);
334 return ret;
335}
336
337static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
338{
339 bool ret = false;
340 unsigned char * ptr = ks_addr;
341 uint32_t inner_len = encode_inner_keystore(ptr, ks);
342 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
343 oem_keystore);
344 return ret;
345}
346
347static void read_oem_keystore()
348{
Shashank Mittale6797222014-09-19 18:58:43 -0700349 KEYSTORE *ks = NULL;
350 uint32_t len = 0;
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800351 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700352
Shashank Mittal64d04852014-08-28 15:02:46 -0700353 if(oem_keystore != NULL)
354 return;
355
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800356 len = read_der_message_length((unsigned char *)input);
Shashank Mittale6797222014-09-19 18:58:43 -0700357 if(!len)
358 {
359 dprintf(CRITICAL, "boot_verifier: oem keystore length is invalid.\n");
360 return;
361 }
362
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800363 ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700364 if(ks != NULL)
365 {
366 oem_keystore = ks;
367 user_keystore = ks;
368 }
369}
370
Shashank Mittal64d04852014-08-28 15:02:46 -0700371uint32_t boot_verify_keystore_init()
372{
373 /* Read OEM Keystore */
374 read_oem_keystore();
375
Shashank Mittal64d04852014-08-28 15:02:46 -0700376 return dev_boot_state;
377}
378
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700379bool send_rot_command(uint32_t is_unlocked)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700380{
381 int ret = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700382 unsigned char *input = NULL;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700383 char *rot_input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700384 unsigned int digest[9] = {0}, final_digest[8] = {0};
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700385 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
386 uint32_t boot_device_state = boot_verify_get_state();
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700387 int app_handle = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700388 uint32_t len_oem_rsa = 0, len_from_cert = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700389 km_set_rot_req_t *read_req;
390 km_set_rot_rsp_t read_rsp;
391 app_handle = get_secapp_handle();
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700392 int n = 0, e = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700393 switch (boot_device_state)
394 {
395 case GREEN:
396 // Locked device and boot.img verified against OEM keystore.
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700397 // Send hash of key from OEM KEYSTORE + Boot device state
398 n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
399 e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
400 len_oem_rsa = n + e;
401 if(!(input = malloc(len_oem_rsa)))
402 {
403 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
404 ASSERT(0);
405 }
406 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
407 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
408 hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700409 digest[8] = is_unlocked;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700410 break;
411 case YELLOW:
412 case RED:
413 // Locked device and boot.img passed (yellow) or failed (red) verification with the certificate embedded to the boot.img.
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700414 if (!rsa_from_cert)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700415 {
416 dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
417 ASSERT(0);
418 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700419 // Send hash of key from certificate in boot image + boot device state
420 n = BN_num_bytes(rsa_from_cert->n);
421 e = BN_num_bytes(rsa_from_cert->e);
422 len_from_cert = n + e;
423 if(!(input = malloc(len_from_cert)))
424 {
425 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
426 ASSERT(0);
427 }
428 BN_bn2bin(rsa_from_cert->n, input);
429 BN_bn2bin(rsa_from_cert->e, input+n);
430 hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700431 digest[8] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700432 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700433 case ORANGE:
434 // Unlocked device and no verification done.
435 // Send the hash of boot device state
436 input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700437 digest[0] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700438 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700439 }
440
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700441 hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700442 dprintf(SPEW, "Digest: ");
443 for(uint8_t i = 0; i < 8; i++)
444 dprintf(SPEW, "0x%x ", final_digest[i]);
445 dprintf(SPEW, "\n");
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700446 if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700447 {
448 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
449 ASSERT(0);
450 }
451
452 void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
453 // set ROT stucture
454 read_req->cmd_id = KEYMASTER_SET_ROT;
455 read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700456 read_req->rot_size = sizeof(final_digest);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700457 // copy the digest
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700458 memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700459 dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
460
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700461 ret = qseecom_send_command(app_handle, (void*) read_req, sizeof(km_set_rot_req_t) + sizeof(final_digest), (void*) &read_rsp, sizeof(read_rsp));
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700462 if (ret < 0 || read_rsp.status < 0)
463 {
464 dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700465 if(input)
466 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700467 free(read_req);
468 free(rot_input);
469 return false;
470 }
471 dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700472 if(input)
473 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700474 free(read_req);
475 free(rot_input);
476 return true;
477}
478
lijuangf214e222015-07-16 20:06:22 +0800479unsigned char* get_boot_fingerprint(unsigned int* buf_size)
480{
481 *buf_size = fp_size;
482
483 return fp;
484}
485
Shashank Mittal64d04852014-08-28 15:02:46 -0700486bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
487{
488 bool ret = false;
lijuangf214e222015-07-16 20:06:22 +0800489 X509 *cert = NULL;
490 const EVP_MD *fp_type = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700491 VERIFIED_BOOT_SIG *sig = NULL;
492 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
493 uint32_t sig_len = read_der_message_length(sig_addr);
494
495 if(dev_boot_state == ORANGE)
496 {
497 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
498 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
499 return false;
500 }
501
502 if(!sig_len)
503 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700504 dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700505 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700506 }
507
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800508 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700509 {
510 dprintf(CRITICAL,
511 "boot_verifier: verification failure due to target name mismatch\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700512 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700513 }
514
lijuangf214e222015-07-16 20:06:22 +0800515 cert = sig->certificate;
516 fp_type = EVP_sha1();
517 if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
518 dprintf(INFO,"Fail to create certificate fingerprint.\n");
519 }
520
Shashank Mittal64d04852014-08-28 15:02:46 -0700521 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
522
Shashank Mittal64d04852014-08-28 15:02:46 -0700523 if(sig != NULL)
524 VERIFIED_BOOT_SIG_free(sig);
Shashank Mittal64d04852014-08-28 15:02:46 -0700525 return ret;
526}
527
528void boot_verify_send_event(uint32_t event)
529{
530 switch(event)
531 {
532 case BOOT_INIT:
533 dev_boot_state = GREEN;
534 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700535 case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
536 dev_boot_state = GREEN;
537 break;
538 case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
Shashank Mittal64d04852014-08-28 15:02:46 -0700539 if(dev_boot_state == GREEN)
540 dev_boot_state = YELLOW;
541 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700542 case BOOTIMG_VERIFICATION_FAIL:
Shashank Mittal64d04852014-08-28 15:02:46 -0700543 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
544 dev_boot_state = RED;
545 break;
546 case DEV_UNLOCK:
547 dev_boot_state = ORANGE;
548 break;
549 case USER_DENIES:
550 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
551 dev_boot_state = RED;
552 break;
553 }
554}
555
556uint32_t boot_verify_get_state()
557{
558 return dev_boot_state;
559}
560
561void boot_verify_print_state()
562{
563 switch(dev_boot_state)
564 {
565 case GREEN:
566 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
567 break;
568 case ORANGE:
569 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
570 break;
571 case YELLOW:
572 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
573 break;
574 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530575 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");
576
Shashank Mittal64d04852014-08-28 15:02:46 -0700577 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
578 break;
579 }
580}
581
582bool boot_verify_validate_keystore(unsigned char * user_addr)
583{
584 bool ret = false;
585 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700586 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700587 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700588 if(!len)
589 {
590 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
591 return ret;
592 }
593
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800594 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700595 if(ks != NULL)
596 {
597 ret = true;
598 }
599 return ret;
600}
601
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800602static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700603{
Shashank Mittal64d04852014-08-28 15:02:46 -0700604 if(list == NULL || entry == NULL)
605 return false;
606
607 while(*list != NULL)
608 {
609 if(!strcmp(entry, *list))
610 return true;
611
612 list++;
613 }
614
615 return false;
616}
617
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700618KEYSTORE *boot_gerity_get_oem_keystore()
619{
620 read_oem_keystore();
621 return oem_keystore;
622}