blob: 6a5f5f39ff57bb19325d64c263005a07c2a29d9d [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
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -070050#define ASN1_SIGNATURE_BUFFER_SZ mmc_page_size()
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -070051
Shashank Mittal64d04852014-08-28 15:02:46 -070052static KEYSTORE *oem_keystore;
53static KEYSTORE *user_keystore;
54static uint32_t dev_boot_state = RED;
Shashank Mittal64d04852014-08-28 15:02:46 -070055char KEYSTORE_PTN_NAME[] = "keystore";
Sridhar Parasuram8b792422015-07-05 11:38:13 -070056RSA *rsa_from_cert = NULL;
lijuangf214e222015-07-16 20:06:22 +080057unsigned char fp[EVP_MAX_MD_SIZE];
58uint32_t fp_size;
Shashank Mittal64d04852014-08-28 15:02:46 -070059
60ASN1_SEQUENCE(AUTH_ATTR) ={
61 ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
62 ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
63} ASN1_SEQUENCE_END(AUTH_ATTR)
64IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
65
66 ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
67 ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
Unnati Gandhi93334992015-02-25 19:38:38 +053068 ASN1_SIMPLE(VERIFIED_BOOT_SIG, certificate, X509),
Shashank Mittal64d04852014-08-28 15:02:46 -070069 ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
70 ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
71 ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
72 } ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
73IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
74
75 ASN1_SEQUENCE(KEY) = {
76 ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
77 ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
78 }ASN1_SEQUENCE_END(KEY)
79IMPLEMENT_ASN1_FUNCTIONS(KEY);
80
81ASN1_SEQUENCE(KEYBAG) = {
82 ASN1_SIMPLE(KEYBAG, mykey, KEY)
83}ASN1_SEQUENCE_END(KEYBAG)
84IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
85
86 ASN1_SEQUENCE(KEYSTORE_INNER) = {
87 ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
88 ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
89 } ASN1_SEQUENCE_END(KEYSTORE_INNER)
90IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
91
92 ASN1_SEQUENCE(KEYSTORE) = {
93 ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
94 ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
95 ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
96 } ASN1_SEQUENCE_END(KEYSTORE)
97IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
98
99static uint32_t read_der_message_length(unsigned char* input)
100{
101 uint32_t len = 0;
102 int pos = 0;
103 uint8_t len_bytes = 1;
104
105 /* Check if input starts with Sequence id (0X30) */
106 if(input[pos] != 0x30)
107 return len;
108 pos++;
109
110 /* A length of 0xAABBCCDD in DER encoded messages would be sequence of
111 following octets 0xAA, 0xBB, 0XCC, 0XDD.
112
113 To read length - read each octet and shift left by 1 octect before
114 reading next octet.
115 */
116 /* check if short or long length form */
117 if(input[pos] & 0x80)
118 {
119 len_bytes = (input[pos] & ~(0x80));
120 pos++;
121 }
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700122
Shashank Mittal64d04852014-08-28 15:02:46 -0700123 while(len_bytes)
124 {
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700125 /* Shift len by 1 octet, make sure to check unsigned int overflow */
126 if (len <= (UINT_MAX >> 8))
127 len <<= 8;
128 else
129 {
130 dprintf(CRITICAL, "Error: Length exceeding max size of uintmax\n");
131 return 0;
132 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700133
134 /* Read next octet */
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700135 if (pos < (int) ASN1_SIGNATURE_BUFFER_SZ)
136 len = len | input[pos];
137 else
138 {
139 dprintf(CRITICAL, "Error: Pos index exceeding the input buffer size\n");
140 return 0;
141 }
142
Shashank Mittal64d04852014-08-28 15:02:46 -0700143 pos++; len_bytes--;
144 }
145
146 /* Add number of octets representing sequence id and length */
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700147 if ((UINT_MAX - pos) > len)
148 len += pos;
149 else
150 {
151 dprintf(CRITICAL, "Error: Len overflows UINT_MAX value\n");
152 return 0;
153 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700154
155 return len;
156}
157
Shashank Mittal64d04852014-08-28 15:02:46 -0700158static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
159{
160 return i2d_AUTH_ATTR(input, &ptr);
161}
162
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700163bool boot_verify_compare_sha256(unsigned char *image_ptr,
Shashank Mittal64d04852014-08-28 15:02:46 -0700164 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
165{
166 int ret = -1;
167 bool auth = false;
168 unsigned char *plain_text = NULL;
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700169
170 /* The magic numbers here are drawn from the PKCS#1 standard and are the ASN.1
171 *encoding of the SHA256 object identifier that is required for a PKCS#1
172 * signature.*/
173 uint8_t digest[ASN1_ENCODED_SHA256_SIZE] = {0x30, 0x31, 0x30, 0x0d, 0x06,
174 0x09, 0x60, 0x86, 0x48, 0x01,
175 0x65, 0x03, 0x04, 0x02, 0x01,
176 0x05, 0x00, 0x04, 0x20};
Shashank Mittal64d04852014-08-28 15:02:46 -0700177
178 plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
179 if (plain_text == NULL) {
180 dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
181 goto cleanup;
182 }
183
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700184 /* Calculate SHA256 of image and place it into the ASN.1 structure*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700185 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700186 digest + ASN1_ENCODED_SHA256_OFFSET);
Shashank Mittal64d04852014-08-28 15:02:46 -0700187
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700188 /* Find digest from the image. This performs the PKCS#1 padding checks up to
189 * but not including the ASN.1 OID and hash function check. The return value
190 * is not positive for a failure or the length of the part after the padding */
Shashank Mittal64d04852014-08-28 15:02:46 -0700191 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
192
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700193 /* Make sure the length returned from rsa decrypt is same as x509 signature format
194 * otherwise the signature is invalid and we fail
195 */
196 if (ret != ASN1_ENCODED_SHA256_SIZE)
197 {
198 dprintf(CRITICAL, "boot_verifier: Signature decrypt failed! Signature invalid = %d\n",
Shashank Mittal64d04852014-08-28 15:02:46 -0700199 ret);
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700200 goto cleanup;
201 }
202 /* So plain_text contains the ASN.1 encoded hash from the signature and
203 * digest contains the value that this should be for the image that we're
204 * verifying, so compare them.*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700205
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700206 ret = memcmp(plain_text, digest, ASN1_ENCODED_SHA256_SIZE);
Shashank Mittal64d04852014-08-28 15:02:46 -0700207 if(ret == 0)
208 {
209 auth = true;
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700210#ifdef TZ_SAVE_KERNEL_HASH
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700211 save_kernel_hash((unsigned char *) digest + ASN1_ENCODED_SHA256_OFFSET, CRYPTO_AUTH_ALG_SHA256);
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700212#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700213 }
214
215cleanup:
216 if (plain_text != NULL)
217 free(plain_text);
218 EVP_cleanup();
219 CRYPTO_cleanup_all_ex_data();
220 ERR_remove_thread_state(NULL);
221 return auth;
222
223}
224
225static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
226 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
227{
228 bool ret = false;
229 uint32_t len;
230 int shift_bytes;
231 RSA *rsa = NULL;
232 bool keystore_verification = false;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700233 EVP_PKEY* key = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700234
235 if(!strcmp(pname, "keystore"))
236 keystore_verification = true;
237
238 /* Verify target name */
239 if(strncmp((char*)(sig->auth_attr->target->data), pname,
240 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800241 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700242 {
243 dprintf(CRITICAL,
244 "boot_verifier: verification failure due to target name mismatch\n");
245 goto verify_image_with_sig_error;
246 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700247 /* Read image size from signature */
248 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
249 len->data as 0X00CCBBAA and len->length as 3(octets).
250
251 To read len we need to left shift data to number of missing octets and
252 then change it to host long
253 */
254 len = *((uint32_t*)sig->auth_attr->len->data);
255 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
256 if(shift_bytes > 0) {
257 len = len << (shift_bytes*8);
258 }
259 len = ntohl(len);
260
261 /* Verify image size*/
262 if(len != img_size)
263 {
264 dprintf(CRITICAL,
265 "boot_verifier: image length is different. (%d vs %d)\n",
266 len, img_size);
267 goto verify_image_with_sig_error;
268 }
269
270 /* append attribute to image */
271 if(!keystore_verification)
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700272 {
273 // verifying a non keystore partition
Shashank Mittal64d04852014-08-28 15:02:46 -0700274 img_size += add_attribute_to_img((unsigned char*)(img_addr + img_size),
275 sig->auth_attr);
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700276 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700277
278 /* compare SHA256SUM of image with value in signature */
279 if(ks != NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700280 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700281 // use rsa from keystore
282 rsa = ks->mykeybag->mykey->key_material;
283 }
284 else
285 {
286 dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
287 ASSERT(0);
288 }
289
290 // verify boot.img with rsa from oem keystore
291 if((ret = boot_verify_compare_sha256(img_addr, img_size,
292 (unsigned char*)sig->sig->data, rsa)))
293
294 {
295 dprintf(SPEW, "Verified boot.img with oem keystore\n");
296 boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
297 goto verify_image_with_sig_done;
298 }
299 else
300 {
301 dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
302 // get the public key from certificate in boot.img
303 if ((key = X509_get_pubkey(sig->certificate)))
304 {
305 // convert to rsa key format
306 dprintf(INFO, "RSA KEY found from the embedded certificate\n");
307 rsa = EVP_PKEY_get1_RSA(key);
308 rsa_from_cert = rsa;
309 }
310 else
311 {
312 dprintf(CRITICAL, "Unable to extract public key from certificate\n");
313 ASSERT(0);
314 }
315 }
316
317 // verify boot.img with rsa from embedded certificate
318 if ((ret = boot_verify_compare_sha256(img_addr, img_size,
319 (unsigned char*)sig->sig->data, rsa)))
320 {
321 dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
322 boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
323 goto verify_image_with_sig_done;
324 }
325 else
326 {
327 dprintf(INFO, "verified for red state\n");
328 boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
329 goto verify_image_with_sig_done;
Shashank Mittal64d04852014-08-28 15:02:46 -0700330 }
331
332verify_image_with_sig_error:
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700333verify_image_with_sig_done:
Shashank Mittal64d04852014-08-28 15:02:46 -0700334 return ret;
335}
336
337static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
338{
339 int ret = 0;
340 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
341 if (ks_inner == NULL)
342 return ret;
343 ASN1_INTEGER *tmp_version = ks_inner->version;
344 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
345
346 ks_inner->version = ks->version;
347 ks_inner->mykeybag = ks->mykeybag;
348 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
349
350 ks_inner->version = tmp_version;
351 ks_inner->mykeybag = tmp_mykeybag;
352
353 if(ks_inner != NULL)
354 KEYSTORE_INNER_free(ks_inner);
355 return ret;
356}
357
358static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
359{
360 bool ret = false;
361 unsigned char * ptr = ks_addr;
362 uint32_t inner_len = encode_inner_keystore(ptr, ks);
363 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
364 oem_keystore);
365 return ret;
366}
367
368static void read_oem_keystore()
369{
Shashank Mittale6797222014-09-19 18:58:43 -0700370 KEYSTORE *ks = NULL;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700371 uint32_t len = sizeof(OEM_KEYSTORE);
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800372 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700373
Shashank Mittal64d04852014-08-28 15:02:46 -0700374 if(oem_keystore != NULL)
375 return;
376
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800377 ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700378 if(ks != NULL)
379 {
380 oem_keystore = ks;
381 user_keystore = ks;
382 }
383}
384
Shashank Mittal64d04852014-08-28 15:02:46 -0700385uint32_t boot_verify_keystore_init()
386{
387 /* Read OEM Keystore */
388 read_oem_keystore();
389
Shashank Mittal64d04852014-08-28 15:02:46 -0700390 return dev_boot_state;
391}
392
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700393bool send_rot_command(uint32_t is_unlocked)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700394{
395 int ret = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700396 unsigned char *input = NULL;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700397 char *rot_input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700398 unsigned int digest[9] = {0}, final_digest[8] = {0};
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700399 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
400 uint32_t boot_device_state = boot_verify_get_state();
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700401 int app_handle = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700402 uint32_t len_oem_rsa = 0, len_from_cert = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700403 km_set_rot_req_t *read_req;
404 km_set_rot_rsp_t read_rsp;
405 app_handle = get_secapp_handle();
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700406 int n = 0, e = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700407 switch (boot_device_state)
408 {
409 case GREEN:
410 // Locked device and boot.img verified against OEM keystore.
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700411 // Send hash of key from OEM KEYSTORE + Boot device state
412 n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
413 e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
414 len_oem_rsa = n + e;
415 if(!(input = malloc(len_oem_rsa)))
416 {
417 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
418 ASSERT(0);
419 }
420 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
421 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
422 hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700423 digest[8] = is_unlocked;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700424 break;
425 case YELLOW:
426 case RED:
427 // 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 -0700428 if (!rsa_from_cert)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700429 {
430 dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
431 ASSERT(0);
432 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700433 // Send hash of key from certificate in boot image + boot device state
434 n = BN_num_bytes(rsa_from_cert->n);
435 e = BN_num_bytes(rsa_from_cert->e);
436 len_from_cert = n + e;
437 if(!(input = malloc(len_from_cert)))
438 {
439 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
440 ASSERT(0);
441 }
442 BN_bn2bin(rsa_from_cert->n, input);
443 BN_bn2bin(rsa_from_cert->e, input+n);
444 hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700445 digest[8] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700446 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700447 case ORANGE:
448 // Unlocked device and no verification done.
449 // Send the hash of boot device state
450 input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700451 digest[0] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700452 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700453 }
454
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700455 hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700456 dprintf(SPEW, "Digest: ");
457 for(uint8_t i = 0; i < 8; i++)
458 dprintf(SPEW, "0x%x ", final_digest[i]);
459 dprintf(SPEW, "\n");
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700460 if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700461 {
462 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
463 ASSERT(0);
464 }
465
466 void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
467 // set ROT stucture
468 read_req->cmd_id = KEYMASTER_SET_ROT;
469 read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700470 read_req->rot_size = sizeof(final_digest);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700471 // copy the digest
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700472 memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700473 dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
474
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700475 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 -0700476 if (ret < 0 || read_rsp.status < 0)
477 {
478 dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700479 if(input)
480 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700481 free(read_req);
482 free(rot_input);
483 return false;
484 }
485 dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700486 if(input)
487 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700488 free(read_req);
489 free(rot_input);
490 return true;
491}
492
lijuangf214e222015-07-16 20:06:22 +0800493unsigned char* get_boot_fingerprint(unsigned int* buf_size)
494{
495 *buf_size = fp_size;
496
497 return fp;
498}
499
Shashank Mittal64d04852014-08-28 15:02:46 -0700500bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
501{
502 bool ret = false;
lijuangf214e222015-07-16 20:06:22 +0800503 X509 *cert = NULL;
504 const EVP_MD *fp_type = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700505 VERIFIED_BOOT_SIG *sig = NULL;
506 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700507 uint32_t sig_len = 0;
508 unsigned char *signature = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700509
510 if(dev_boot_state == ORANGE)
511 {
512 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
513 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
514 return false;
515 }
516
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700517 signature = malloc(ASN1_SIGNATURE_BUFFER_SZ);
518 ASSERT(signature);
519
520 /* Copy the signature from scratch memory to buffer */
521 memcpy(signature, sig_addr, ASN1_SIGNATURE_BUFFER_SZ);
522 sig_len = read_der_message_length(signature);
523
Shashank Mittal64d04852014-08-28 15:02:46 -0700524 if(!sig_len)
525 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700526 dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700527 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700528 }
529
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700530 if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
531 {
532 dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
533 goto verify_image_error;
534 }
535
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800536 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700537 {
538 dprintf(CRITICAL,
539 "boot_verifier: verification failure due to target name mismatch\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700540 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700541 }
542
lijuangf214e222015-07-16 20:06:22 +0800543 cert = sig->certificate;
544 fp_type = EVP_sha1();
545 if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
546 dprintf(INFO,"Fail to create certificate fingerprint.\n");
547 }
548
Shashank Mittal64d04852014-08-28 15:02:46 -0700549 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
550
Shashank Mittal64d04852014-08-28 15:02:46 -0700551 if(sig != NULL)
552 VERIFIED_BOOT_SIG_free(sig);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700553verify_image_error:
554 free(signature);
Shashank Mittal64d04852014-08-28 15:02:46 -0700555 return ret;
556}
557
558void boot_verify_send_event(uint32_t event)
559{
560 switch(event)
561 {
562 case BOOT_INIT:
563 dev_boot_state = GREEN;
564 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700565 case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
566 dev_boot_state = GREEN;
567 break;
568 case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
Shashank Mittal64d04852014-08-28 15:02:46 -0700569 if(dev_boot_state == GREEN)
570 dev_boot_state = YELLOW;
571 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700572 case BOOTIMG_VERIFICATION_FAIL:
Shashank Mittal64d04852014-08-28 15:02:46 -0700573 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
574 dev_boot_state = RED;
575 break;
576 case DEV_UNLOCK:
577 dev_boot_state = ORANGE;
578 break;
579 case USER_DENIES:
580 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
581 dev_boot_state = RED;
582 break;
583 }
584}
585
586uint32_t boot_verify_get_state()
587{
588 return dev_boot_state;
589}
590
591void boot_verify_print_state()
592{
593 switch(dev_boot_state)
594 {
595 case GREEN:
596 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
597 break;
598 case ORANGE:
599 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
600 break;
601 case YELLOW:
602 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
603 break;
604 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530605 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");
606
Shashank Mittal64d04852014-08-28 15:02:46 -0700607 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
608 break;
609 }
610}
611
612bool boot_verify_validate_keystore(unsigned char * user_addr)
613{
614 bool ret = false;
615 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700616 KEYSTORE *ks = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700617 uint32_t len = read_der_message_length(input);
Shashank Mittale6797222014-09-19 18:58:43 -0700618 if(!len)
619 {
620 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
621 return ret;
622 }
623
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800624 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700625 if(ks != NULL)
626 {
627 ret = true;
628 }
629 return ret;
630}
631
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800632static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700633{
Shashank Mittal64d04852014-08-28 15:02:46 -0700634 if(list == NULL || entry == NULL)
635 return false;
636
637 while(*list != NULL)
638 {
639 if(!strcmp(entry, *list))
640 return true;
641
642 list++;
643 }
644
645 return false;
646}
647
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700648KEYSTORE *boot_gerity_get_oem_keystore()
649{
650 read_oem_keystore();
651 return oem_keystore;
652}