blob: 7d22eb9e5bcbf95aea73004c99fcac75acf5ca79 [file] [log] [blame]
Shashank Mittal64d04852014-08-28 15:02:46 -07001/*
vijay kumara89b9252015-12-10 16:10:03 +05302 * Copyright (c) 2014-2016, 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>
Channagoud Kadabi86b0c112016-03-16 19:23:16 -070047#include "bootimg.h"
Shashank Mittal64d04852014-08-28 15:02:46 -070048
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -070049#define ASN1_ENCODED_SHA256_SIZE 0x33
50#define ASN1_ENCODED_SHA256_OFFSET 0x13
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -070051#define ASN1_SIGNATURE_BUFFER_SZ mmc_page_size()
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -070052
Shashank Mittal64d04852014-08-28 15:02:46 -070053static KEYSTORE *oem_keystore;
54static KEYSTORE *user_keystore;
55static uint32_t dev_boot_state = RED;
Shashank Mittal64d04852014-08-28 15:02:46 -070056char KEYSTORE_PTN_NAME[] = "keystore";
Sridhar Parasuram8b792422015-07-05 11:38:13 -070057RSA *rsa_from_cert = NULL;
lijuangf214e222015-07-16 20:06:22 +080058unsigned char fp[EVP_MAX_MD_SIZE];
59uint32_t fp_size;
Channagoud Kadabi86b0c112016-03-16 19:23:16 -070060#if OSVERSION_IN_BOOTIMAGE
61km_boot_state_t boot_state_info;
62#endif
Shashank Mittal64d04852014-08-28 15:02:46 -070063
64ASN1_SEQUENCE(AUTH_ATTR) ={
65 ASN1_SIMPLE(AUTH_ATTR, target, ASN1_PRINTABLESTRING),
66 ASN1_SIMPLE(AUTH_ATTR, len, ASN1_INTEGER)
67} ASN1_SEQUENCE_END(AUTH_ATTR)
68IMPLEMENT_ASN1_FUNCTIONS(AUTH_ATTR)
69
70 ASN1_SEQUENCE(VERIFIED_BOOT_SIG) = {
71 ASN1_SIMPLE(VERIFIED_BOOT_SIG, version, ASN1_INTEGER),
Unnati Gandhi93334992015-02-25 19:38:38 +053072 ASN1_SIMPLE(VERIFIED_BOOT_SIG, certificate, X509),
Shashank Mittal64d04852014-08-28 15:02:46 -070073 ASN1_SIMPLE(VERIFIED_BOOT_SIG, algor, X509_ALGOR),
74 ASN1_SIMPLE(VERIFIED_BOOT_SIG, auth_attr, AUTH_ATTR),
75 ASN1_SIMPLE(VERIFIED_BOOT_SIG, sig, ASN1_OCTET_STRING)
76 } ASN1_SEQUENCE_END(VERIFIED_BOOT_SIG)
77IMPLEMENT_ASN1_FUNCTIONS(VERIFIED_BOOT_SIG)
78
79 ASN1_SEQUENCE(KEY) = {
80 ASN1_SIMPLE(KEY, algorithm_id, X509_ALGOR),
81 ASN1_SIMPLE(KEY, key_material, RSAPublicKey)
82 }ASN1_SEQUENCE_END(KEY)
83IMPLEMENT_ASN1_FUNCTIONS(KEY);
84
85ASN1_SEQUENCE(KEYBAG) = {
86 ASN1_SIMPLE(KEYBAG, mykey, KEY)
87}ASN1_SEQUENCE_END(KEYBAG)
88IMPLEMENT_ASN1_FUNCTIONS(KEYBAG)
89
90 ASN1_SEQUENCE(KEYSTORE_INNER) = {
91 ASN1_SIMPLE(KEYSTORE_INNER, version, ASN1_INTEGER),
92 ASN1_SIMPLE(KEYSTORE_INNER, mykeybag, KEYBAG)
93 } ASN1_SEQUENCE_END(KEYSTORE_INNER)
94IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE_INNER)
95
96 ASN1_SEQUENCE(KEYSTORE) = {
97 ASN1_SIMPLE(KEYSTORE, version, ASN1_INTEGER),
98 ASN1_SIMPLE(KEYSTORE, mykeybag, KEYBAG),
99 ASN1_SIMPLE(KEYSTORE, sig, VERIFIED_BOOT_SIG)
100 } ASN1_SEQUENCE_END(KEYSTORE)
101IMPLEMENT_ASN1_FUNCTIONS(KEYSTORE)
102
P.V. Phani Kumarbbe8c8e2016-03-09 19:43:24 +0530103uint32_t read_der_message_length(unsigned char* input, unsigned sz)
Shashank Mittal64d04852014-08-28 15:02:46 -0700104{
105 uint32_t len = 0;
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530106 uint32_t pos = 0;
Shashank Mittal64d04852014-08-28 15:02:46 -0700107 uint8_t len_bytes = 1;
108
109 /* Check if input starts with Sequence id (0X30) */
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530110 if(sz < 3 || input[pos] != 0x30)
Shashank Mittal64d04852014-08-28 15:02:46 -0700111 return len;
112 pos++;
113
114 /* A length of 0xAABBCCDD in DER encoded messages would be sequence of
115 following octets 0xAA, 0xBB, 0XCC, 0XDD.
116
117 To read length - read each octet and shift left by 1 octect before
118 reading next octet.
119 */
120 /* check if short or long length form */
121 if(input[pos] & 0x80)
122 {
123 len_bytes = (input[pos] & ~(0x80));
124 pos++;
125 }
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700126
Shashank Mittal64d04852014-08-28 15:02:46 -0700127 while(len_bytes)
128 {
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700129 /* Shift len by 1 octet, make sure to check unsigned int overflow */
130 if (len <= (UINT_MAX >> 8))
131 len <<= 8;
132 else
133 {
134 dprintf(CRITICAL, "Error: Length exceeding max size of uintmax\n");
135 return 0;
136 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700137
138 /* Read next octet */
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530139 if (pos < (uint32_t) ASN1_SIGNATURE_BUFFER_SZ && pos < sz)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700140 len = len | input[pos];
141 else
142 {
143 dprintf(CRITICAL, "Error: Pos index exceeding the input buffer size\n");
144 return 0;
145 }
146
Shashank Mittal64d04852014-08-28 15:02:46 -0700147 pos++; len_bytes--;
148 }
149
150 /* Add number of octets representing sequence id and length */
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700151 if ((UINT_MAX - pos) > len)
152 len += pos;
153 else
154 {
155 dprintf(CRITICAL, "Error: Len overflows UINT_MAX value\n");
156 return 0;
157 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700158
159 return len;
160}
161
Shashank Mittal64d04852014-08-28 15:02:46 -0700162static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
163{
164 return i2d_AUTH_ATTR(input, &ptr);
165}
166
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700167bool boot_verify_compare_sha256(unsigned char *image_ptr,
Shashank Mittal64d04852014-08-28 15:02:46 -0700168 unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
169{
170 int ret = -1;
171 bool auth = false;
172 unsigned char *plain_text = NULL;
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700173
174 /* The magic numbers here are drawn from the PKCS#1 standard and are the ASN.1
175 *encoding of the SHA256 object identifier that is required for a PKCS#1
176 * signature.*/
177 uint8_t digest[ASN1_ENCODED_SHA256_SIZE] = {0x30, 0x31, 0x30, 0x0d, 0x06,
178 0x09, 0x60, 0x86, 0x48, 0x01,
179 0x65, 0x03, 0x04, 0x02, 0x01,
180 0x05, 0x00, 0x04, 0x20};
Shashank Mittal64d04852014-08-28 15:02:46 -0700181
182 plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
183 if (plain_text == NULL) {
184 dprintf(CRITICAL, "boot_verifier: Calloc failed during verification\n");
185 goto cleanup;
186 }
187
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700188 /* Calculate SHA256 of image and place it into the ASN.1 structure*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700189 image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700190 digest + ASN1_ENCODED_SHA256_OFFSET);
Shashank Mittal64d04852014-08-28 15:02:46 -0700191
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700192 /* Find digest from the image. This performs the PKCS#1 padding checks up to
193 * but not including the ASN.1 OID and hash function check. The return value
194 * is not positive for a failure or the length of the part after the padding */
Shashank Mittal64d04852014-08-28 15:02:46 -0700195 ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
196
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700197 /* Make sure the length returned from rsa decrypt is same as x509 signature format
198 * otherwise the signature is invalid and we fail
199 */
200 if (ret != ASN1_ENCODED_SHA256_SIZE)
201 {
202 dprintf(CRITICAL, "boot_verifier: Signature decrypt failed! Signature invalid = %d\n",
Shashank Mittal64d04852014-08-28 15:02:46 -0700203 ret);
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700204 goto cleanup;
205 }
206 /* So plain_text contains the ASN.1 encoded hash from the signature and
207 * digest contains the value that this should be for the image that we're
208 * verifying, so compare them.*/
Shashank Mittal64d04852014-08-28 15:02:46 -0700209
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700210 ret = memcmp(plain_text, digest, ASN1_ENCODED_SHA256_SIZE);
Shashank Mittal64d04852014-08-28 15:02:46 -0700211 if(ret == 0)
212 {
213 auth = true;
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700214#ifdef TZ_SAVE_KERNEL_HASH
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700215 save_kernel_hash((unsigned char *) digest + ASN1_ENCODED_SHA256_OFFSET, CRYPTO_AUTH_ALG_SHA256);
Sridhar Parasuramb27e47c2015-05-27 14:33:54 -0700216#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700217 }
218
219cleanup:
220 if (plain_text != NULL)
221 free(plain_text);
222 EVP_cleanup();
223 CRYPTO_cleanup_all_ex_data();
224 ERR_remove_thread_state(NULL);
225 return auth;
226
227}
228
229static bool verify_image_with_sig(unsigned char* img_addr, uint32_t img_size,
230 char *pname, VERIFIED_BOOT_SIG *sig, KEYSTORE *ks)
231{
232 bool ret = false;
233 uint32_t len;
234 int shift_bytes;
235 RSA *rsa = NULL;
236 bool keystore_verification = false;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700237 EVP_PKEY* key = NULL;
vijay kumar9fe95642015-12-14 14:14:20 +0530238 int attr = 0;
Shashank Mittal64d04852014-08-28 15:02:46 -0700239
240 if(!strcmp(pname, "keystore"))
241 keystore_verification = true;
242
243 /* Verify target name */
244 if(strncmp((char*)(sig->auth_attr->target->data), pname,
245 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800246 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700247 {
248 dprintf(CRITICAL,
249 "boot_verifier: verification failure due to target name mismatch\n");
250 goto verify_image_with_sig_error;
251 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700252 /* Read image size from signature */
253 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
254 len->data as 0X00CCBBAA and len->length as 3(octets).
255
256 To read len we need to left shift data to number of missing octets and
257 then change it to host long
258 */
259 len = *((uint32_t*)sig->auth_attr->len->data);
260 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
261 if(shift_bytes > 0) {
262 len = len << (shift_bytes*8);
263 }
264 len = ntohl(len);
265
266 /* Verify image size*/
267 if(len != img_size)
268 {
269 dprintf(CRITICAL,
270 "boot_verifier: image length is different. (%d vs %d)\n",
271 len, img_size);
272 goto verify_image_with_sig_error;
273 }
274
275 /* append attribute to image */
276 if(!keystore_verification)
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700277 {
278 // verifying a non keystore partition
vijay kumar9fe95642015-12-14 14:14:20 +0530279 attr = add_attribute_to_img((unsigned char*)(img_addr + img_size),
Shashank Mittal64d04852014-08-28 15:02:46 -0700280 sig->auth_attr);
vijay kumar9fe95642015-12-14 14:14:20 +0530281 if (img_size > (UINT_MAX - attr))
282 {
283 dprintf(CRITICAL,"Interger overflow detected\n");
284 ASSERT(0);
285 }
286 else img_size += attr;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700287 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700288
289 /* compare SHA256SUM of image with value in signature */
290 if(ks != NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700291 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700292 // use rsa from keystore
293 rsa = ks->mykeybag->mykey->key_material;
294 }
295 else
296 {
297 dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
298 ASSERT(0);
299 }
300
301 // verify boot.img with rsa from oem keystore
302 if((ret = boot_verify_compare_sha256(img_addr, img_size,
303 (unsigned char*)sig->sig->data, rsa)))
304
305 {
306 dprintf(SPEW, "Verified boot.img with oem keystore\n");
307 boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
308 goto verify_image_with_sig_done;
309 }
310 else
311 {
312 dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
313 // get the public key from certificate in boot.img
314 if ((key = X509_get_pubkey(sig->certificate)))
315 {
316 // convert to rsa key format
317 dprintf(INFO, "RSA KEY found from the embedded certificate\n");
318 rsa = EVP_PKEY_get1_RSA(key);
319 rsa_from_cert = rsa;
320 }
321 else
322 {
323 dprintf(CRITICAL, "Unable to extract public key from certificate\n");
324 ASSERT(0);
325 }
326 }
327
328 // verify boot.img with rsa from embedded certificate
329 if ((ret = boot_verify_compare_sha256(img_addr, img_size,
330 (unsigned char*)sig->sig->data, rsa)))
331 {
332 dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
333 boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
334 goto verify_image_with_sig_done;
335 }
336 else
337 {
338 dprintf(INFO, "verified for red state\n");
339 boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
340 goto verify_image_with_sig_done;
Shashank Mittal64d04852014-08-28 15:02:46 -0700341 }
342
343verify_image_with_sig_error:
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700344verify_image_with_sig_done:
Shashank Mittal64d04852014-08-28 15:02:46 -0700345 return ret;
346}
347
348static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
349{
350 int ret = 0;
351 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
352 if (ks_inner == NULL)
353 return ret;
354 ASN1_INTEGER *tmp_version = ks_inner->version;
355 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
356
357 ks_inner->version = ks->version;
358 ks_inner->mykeybag = ks->mykeybag;
359 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
360
361 ks_inner->version = tmp_version;
362 ks_inner->mykeybag = tmp_mykeybag;
363
364 if(ks_inner != NULL)
365 KEYSTORE_INNER_free(ks_inner);
366 return ret;
367}
368
369static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
370{
371 bool ret = false;
372 unsigned char * ptr = ks_addr;
373 uint32_t inner_len = encode_inner_keystore(ptr, ks);
374 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
375 oem_keystore);
376 return ret;
377}
378
379static void read_oem_keystore()
380{
Shashank Mittale6797222014-09-19 18:58:43 -0700381 KEYSTORE *ks = NULL;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700382 uint32_t len = sizeof(OEM_KEYSTORE);
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800383 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700384
Shashank Mittal64d04852014-08-28 15:02:46 -0700385 if(oem_keystore != NULL)
386 return;
387
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800388 ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700389 if(ks != NULL)
390 {
391 oem_keystore = ks;
392 user_keystore = ks;
393 }
394}
395
Shashank Mittal64d04852014-08-28 15:02:46 -0700396uint32_t boot_verify_keystore_init()
397{
398 /* Read OEM Keystore */
399 read_oem_keystore();
400
Shashank Mittal64d04852014-08-28 15:02:46 -0700401 return dev_boot_state;
402}
403
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700404#if OSVERSION_IN_BOOTIMAGE
405static void boot_verify_send_boot_state(km_boot_state_t *boot_state)
406{
407 km_get_version_req_t version_req;
408 km_get_version_rsp_t version_rsp;
409 int ret;
410 int app_handle = get_secapp_handle();
411 km_set_boot_state_req_t *bs_req = NULL;
412 km_set_boot_state_rsp_t boot_state_rsp;
413 uint8_t *boot_state_ptr;
414
415 version_req.cmd_id = KEYMASTER_GET_VERSION;
416 ret = qseecom_send_command(app_handle, (void*) &version_req, sizeof(version_req), (void*) &version_rsp, sizeof(version_rsp));
417 if (ret < 0 || version_rsp.status < 0)
418 {
419 dprintf(CRITICAL, "QSEEcom command for getting keymaster version returned error: %d\n", version_rsp.status);
420 ASSERT(0);
421 }
422
423 if (version_rsp.major_version >= 0x2)
424 {
425 bs_req = malloc(sizeof(km_set_boot_state_req_t) + sizeof(km_boot_state_t));
426 ASSERT(bs_req);
427
428 boot_state_ptr = (uint8_t *) bs_req + sizeof(km_set_boot_state_req_t);
429 /* copy the boot state data */
430 memscpy(boot_state_ptr, sizeof(km_boot_state_t), &boot_state_info, sizeof(boot_state_info));
431
432 bs_req->cmd_id = KEYMASTER_SET_BOOT_STATE;
433 bs_req->version = 0x0;
434 bs_req->boot_state_offset = sizeof(km_set_boot_state_req_t);
435 bs_req->boot_state_size = sizeof(km_boot_state_t);
436
437 ret = qseecom_send_command(app_handle, (void *)bs_req, sizeof(*bs_req) + sizeof(km_boot_state_t), (void *) &boot_state_rsp, sizeof(boot_state_rsp));
438 if (ret < 0 || boot_state_rsp.status < 0)
439 {
440 dprintf(CRITICAL, "QSEEcom command for Sending boot state returned error: %d\n", boot_state_rsp.status);
441 free(bs_req);
442 ASSERT(0);
443 }
444 }
445
446 if (bs_req)
447 free(bs_req);
448}
449#endif
450
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700451bool send_rot_command(uint32_t is_unlocked)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700452{
453 int ret = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700454 unsigned char *input = NULL;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700455 char *rot_input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700456 unsigned int digest[9] = {0}, final_digest[8] = {0};
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700457 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
458 uint32_t boot_device_state = boot_verify_get_state();
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700459 int app_handle = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700460 uint32_t len_oem_rsa = 0, len_from_cert = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700461 km_set_rot_req_t *read_req;
462 km_set_rot_rsp_t read_rsp;
463 app_handle = get_secapp_handle();
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700464 int n = 0, e = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700465 switch (boot_device_state)
466 {
467 case GREEN:
468 // Locked device and boot.img verified against OEM keystore.
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700469 // Send hash of key from OEM KEYSTORE + Boot device state
470 n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
471 e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
vijay kumara89b9252015-12-10 16:10:03 +0530472 /*this assumes a valid acceptable range for RSA, including 4096 bits of modulo n. */
473 if (n<0 || n>1024)
474 {
475 dprintf(CRITICAL, "Invalid n value from key_material\n");
476 ASSERT(0);
477 }
478 /* e can assumes 3,5,17,257,65537 as valid values, which should be 1 byte long only, we accept 2 bytes or 16 bits long */
479 if( e < 0 || e >16)
480 {
481 dprintf(CRITICAL, "Invalid e value from key_material\n");
482 ASSERT(0);
483 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700484 len_oem_rsa = n + e;
485 if(!(input = malloc(len_oem_rsa)))
486 {
487 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
488 ASSERT(0);
489 }
490 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
491 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
492 hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700493 digest[8] = is_unlocked;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700494 break;
495 case YELLOW:
496 case RED:
497 // 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 -0700498 if (!rsa_from_cert)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700499 {
500 dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
501 ASSERT(0);
502 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700503 // Send hash of key from certificate in boot image + boot device state
504 n = BN_num_bytes(rsa_from_cert->n);
505 e = BN_num_bytes(rsa_from_cert->e);
vijay kumara89b9252015-12-10 16:10:03 +0530506 /*this assumes a valid acceptable range for RSA, including 4096 bits of modulo n. */
507 if (n<0 || n>1024)
508 {
509 dprintf(CRITICAL, "Invalid n value from rsa_from_cert\n");
510 ASSERT(0);
511 }
512 /* e can assumes 3,5,17,257,65537 as valid values, which should be 1 byte long only, we accept 2 bytes or 16 bits long */
513 if( e < 0 || e >16)
514 {
515 dprintf(CRITICAL, "Invalid e value from rsa_from_cert\n");
516 ASSERT(0);
517 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700518 len_from_cert = n + e;
519 if(!(input = malloc(len_from_cert)))
520 {
521 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
522 ASSERT(0);
523 }
524 BN_bn2bin(rsa_from_cert->n, input);
525 BN_bn2bin(rsa_from_cert->e, input+n);
526 hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700527 digest[8] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700528 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700529 case ORANGE:
530 // Unlocked device and no verification done.
531 // Send the hash of boot device state
532 input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700533 digest[0] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700534 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700535 }
536
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700537 hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700538 dprintf(SPEW, "Digest: ");
539 for(uint8_t i = 0; i < 8; i++)
540 dprintf(SPEW, "0x%x ", final_digest[i]);
541 dprintf(SPEW, "\n");
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700542 if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700543 {
544 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
545 ASSERT(0);
546 }
547
548 void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
549 // set ROT stucture
550 read_req->cmd_id = KEYMASTER_SET_ROT;
551 read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700552 read_req->rot_size = sizeof(final_digest);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700553 // copy the digest
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700554 memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700555 dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
556
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700557 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 -0700558 if (ret < 0 || read_rsp.status < 0)
559 {
560 dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700561 if(input)
562 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700563 free(read_req);
564 free(rot_input);
565 return false;
566 }
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700567
568#if OSVERSION_IN_BOOTIMAGE
569 boot_state_info.is_unlocked = is_unlocked;
570 boot_state_info.color = boot_verify_get_state();
571 memscpy(boot_state_info.public_key, sizeof(boot_state_info.public_key), digest, 32);
572 boot_verify_send_boot_state(&boot_state_info);
573#endif
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700574 dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700575 if(input)
576 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700577 free(read_req);
578 free(rot_input);
579 return true;
580}
581
lijuangf214e222015-07-16 20:06:22 +0800582unsigned char* get_boot_fingerprint(unsigned int* buf_size)
583{
584 *buf_size = fp_size;
585
586 return fp;
587}
588
Shashank Mittal64d04852014-08-28 15:02:46 -0700589bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
590{
591 bool ret = false;
lijuangf214e222015-07-16 20:06:22 +0800592 X509 *cert = NULL;
593 const EVP_MD *fp_type = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700594 VERIFIED_BOOT_SIG *sig = NULL;
595 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700596 uint32_t sig_len = 0;
597 unsigned char *signature = NULL;
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700598#if OSVERSION_IN_BOOTIMAGE
599 struct boot_img_hdr *img_hdr = NULL;
600#endif
Shashank Mittal64d04852014-08-28 15:02:46 -0700601
602 if(dev_boot_state == ORANGE)
603 {
604 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
605 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
606 return false;
607 }
608
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700609 signature = malloc(ASN1_SIGNATURE_BUFFER_SZ);
610 ASSERT(signature);
611
612 /* Copy the signature from scratch memory to buffer */
613 memcpy(signature, sig_addr, ASN1_SIGNATURE_BUFFER_SZ);
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530614 sig_len = read_der_message_length(signature, ASN1_SIGNATURE_BUFFER_SZ);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700615
Shashank Mittal64d04852014-08-28 15:02:46 -0700616 if(!sig_len)
617 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700618 dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700619 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700620 }
621
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700622 if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
623 {
624 dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
625 goto verify_image_error;
626 }
627
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700628 if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
629 {
630 dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
631 goto verify_image_error;
632 }
633
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800634 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700635 {
636 dprintf(CRITICAL,
637 "boot_verifier: verification failure due to target name mismatch\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700638 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700639 }
640
lijuangf214e222015-07-16 20:06:22 +0800641 cert = sig->certificate;
642 fp_type = EVP_sha1();
643 if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
644 dprintf(INFO,"Fail to create certificate fingerprint.\n");
645 }
646
Shashank Mittal64d04852014-08-28 15:02:46 -0700647 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
648
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700649#if OSVERSION_IN_BOOTIMAGE
650 /* Extract the os version and patch level */
651 img_hdr = (struct boot_img_hdr *)img_addr;
652 boot_state_info.system_version = (img_hdr->os_version & 0xFFFFF8) >> 11;
653 boot_state_info.system_security_level = (img_hdr->os_version & 0x7FF);
654#endif
655
Shashank Mittal64d04852014-08-28 15:02:46 -0700656 if(sig != NULL)
657 VERIFIED_BOOT_SIG_free(sig);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700658verify_image_error:
659 free(signature);
Shashank Mittal64d04852014-08-28 15:02:46 -0700660 return ret;
661}
662
663void boot_verify_send_event(uint32_t event)
664{
665 switch(event)
666 {
667 case BOOT_INIT:
668 dev_boot_state = GREEN;
669 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700670 case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
671 dev_boot_state = GREEN;
672 break;
673 case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
Shashank Mittal64d04852014-08-28 15:02:46 -0700674 if(dev_boot_state == GREEN)
675 dev_boot_state = YELLOW;
676 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700677 case BOOTIMG_VERIFICATION_FAIL:
Shashank Mittal64d04852014-08-28 15:02:46 -0700678 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
679 dev_boot_state = RED;
680 break;
681 case DEV_UNLOCK:
682 dev_boot_state = ORANGE;
683 break;
684 case USER_DENIES:
685 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
686 dev_boot_state = RED;
687 break;
688 }
689}
690
691uint32_t boot_verify_get_state()
692{
693 return dev_boot_state;
694}
695
696void boot_verify_print_state()
697{
698 switch(dev_boot_state)
699 {
700 case GREEN:
701 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
702 break;
703 case ORANGE:
704 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
705 break;
706 case YELLOW:
707 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
708 break;
709 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530710 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");
711
Shashank Mittal64d04852014-08-28 15:02:46 -0700712 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
713 break;
714 }
715}
716
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530717bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz)
Shashank Mittal64d04852014-08-28 15:02:46 -0700718{
719 bool ret = false;
720 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700721 KEYSTORE *ks = NULL;
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530722 uint32_t len = read_der_message_length(input, sz);
Shashank Mittale6797222014-09-19 18:58:43 -0700723 if(!len)
724 {
725 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
726 return ret;
727 }
728
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800729 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700730 if(ks != NULL)
731 {
732 ret = true;
733 }
734 return ret;
735}
736
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800737static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700738{
Shashank Mittal64d04852014-08-28 15:02:46 -0700739 if(list == NULL || entry == NULL)
740 return false;
741
742 while(*list != NULL)
743 {
744 if(!strcmp(entry, *list))
745 return true;
746
747 list++;
748 }
749
750 return false;
751}
752
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700753KEYSTORE *boot_gerity_get_oem_keystore()
754{
755 read_oem_keystore();
756 return oem_keystore;
757}