blob: d3ce07aaf900081dd7a9a4066a46ae1fff1d33be [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>
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
P.V. Phani Kumarbbe8c8e2016-03-09 19:43:24 +053099uint32_t read_der_message_length(unsigned char* input, unsigned sz)
Shashank Mittal64d04852014-08-28 15:02:46 -0700100{
101 uint32_t len = 0;
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530102 uint32_t pos = 0;
Shashank Mittal64d04852014-08-28 15:02:46 -0700103 uint8_t len_bytes = 1;
104
105 /* Check if input starts with Sequence id (0X30) */
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530106 if(sz < 3 || input[pos] != 0x30)
Shashank Mittal64d04852014-08-28 15:02:46 -0700107 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 */
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530135 if (pos < (uint32_t) ASN1_SIGNATURE_BUFFER_SZ && pos < sz)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700136 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;
vijay kumar9fe95642015-12-14 14:14:20 +0530234 int attr = 0;
Shashank Mittal64d04852014-08-28 15:02:46 -0700235
236 if(!strcmp(pname, "keystore"))
237 keystore_verification = true;
238
239 /* Verify target name */
240 if(strncmp((char*)(sig->auth_attr->target->data), pname,
241 sig->auth_attr->target->length) ||
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800242 (strlen(pname) != (unsigned long) sig->auth_attr->target->length))
Shashank Mittal64d04852014-08-28 15:02:46 -0700243 {
244 dprintf(CRITICAL,
245 "boot_verifier: verification failure due to target name mismatch\n");
246 goto verify_image_with_sig_error;
247 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700248 /* Read image size from signature */
249 /* A len = 0xAABBCC (represented by 3 octets) would be stored in
250 len->data as 0X00CCBBAA and len->length as 3(octets).
251
252 To read len we need to left shift data to number of missing octets and
253 then change it to host long
254 */
255 len = *((uint32_t*)sig->auth_attr->len->data);
256 shift_bytes = sizeof(uint32_t) - sig->auth_attr->len->length;
257 if(shift_bytes > 0) {
258 len = len << (shift_bytes*8);
259 }
260 len = ntohl(len);
261
262 /* Verify image size*/
263 if(len != img_size)
264 {
265 dprintf(CRITICAL,
266 "boot_verifier: image length is different. (%d vs %d)\n",
267 len, img_size);
268 goto verify_image_with_sig_error;
269 }
270
271 /* append attribute to image */
272 if(!keystore_verification)
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700273 {
274 // verifying a non keystore partition
vijay kumar9fe95642015-12-14 14:14:20 +0530275 attr = add_attribute_to_img((unsigned char*)(img_addr + img_size),
Shashank Mittal64d04852014-08-28 15:02:46 -0700276 sig->auth_attr);
vijay kumar9fe95642015-12-14 14:14:20 +0530277 if (img_size > (UINT_MAX - attr))
278 {
279 dprintf(CRITICAL,"Interger overflow detected\n");
280 ASSERT(0);
281 }
282 else img_size += attr;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700283 }
Shashank Mittal64d04852014-08-28 15:02:46 -0700284
285 /* compare SHA256SUM of image with value in signature */
286 if(ks != NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700287 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700288 // use rsa from keystore
289 rsa = ks->mykeybag->mykey->key_material;
290 }
291 else
292 {
293 dprintf(CRITICAL, "%s:%d: Keystore is null\n", __func__, __LINE__);
294 ASSERT(0);
295 }
296
297 // verify boot.img with rsa from oem keystore
298 if((ret = boot_verify_compare_sha256(img_addr, img_size,
299 (unsigned char*)sig->sig->data, rsa)))
300
301 {
302 dprintf(SPEW, "Verified boot.img with oem keystore\n");
303 boot_verify_send_event(BOOTIMG_KEYSTORE_VERIFICATION_PASS);
304 goto verify_image_with_sig_done;
305 }
306 else
307 {
308 dprintf(INFO, "Verification with oem keystore failed. Use embedded certificate for verification\n");
309 // get the public key from certificate in boot.img
310 if ((key = X509_get_pubkey(sig->certificate)))
311 {
312 // convert to rsa key format
313 dprintf(INFO, "RSA KEY found from the embedded certificate\n");
314 rsa = EVP_PKEY_get1_RSA(key);
315 rsa_from_cert = rsa;
316 }
317 else
318 {
319 dprintf(CRITICAL, "Unable to extract public key from certificate\n");
320 ASSERT(0);
321 }
322 }
323
324 // verify boot.img with rsa from embedded certificate
325 if ((ret = boot_verify_compare_sha256(img_addr, img_size,
326 (unsigned char*)sig->sig->data, rsa)))
327 {
328 dprintf(SPEW, "Verified boot.img with embedded certificate in boot image\n");
329 boot_verify_send_event(BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS);
330 goto verify_image_with_sig_done;
331 }
332 else
333 {
334 dprintf(INFO, "verified for red state\n");
335 boot_verify_send_event(BOOTIMG_VERIFICATION_FAIL);
336 goto verify_image_with_sig_done;
Shashank Mittal64d04852014-08-28 15:02:46 -0700337 }
338
339verify_image_with_sig_error:
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700340verify_image_with_sig_done:
Shashank Mittal64d04852014-08-28 15:02:46 -0700341 return ret;
342}
343
344static int encode_inner_keystore(unsigned char *ptr, KEYSTORE *ks)
345{
346 int ret = 0;
347 KEYSTORE_INNER *ks_inner = KEYSTORE_INNER_new();
348 if (ks_inner == NULL)
349 return ret;
350 ASN1_INTEGER *tmp_version = ks_inner->version;
351 KEYBAG *tmp_mykeybag = ks_inner->mykeybag;
352
353 ks_inner->version = ks->version;
354 ks_inner->mykeybag = ks->mykeybag;
355 ret = i2d_KEYSTORE_INNER(ks_inner, &ptr);
356
357 ks_inner->version = tmp_version;
358 ks_inner->mykeybag = tmp_mykeybag;
359
360 if(ks_inner != NULL)
361 KEYSTORE_INNER_free(ks_inner);
362 return ret;
363}
364
365static bool verify_keystore(unsigned char * ks_addr, KEYSTORE *ks)
366{
367 bool ret = false;
368 unsigned char * ptr = ks_addr;
369 uint32_t inner_len = encode_inner_keystore(ptr, ks);
370 ret = verify_image_with_sig(ks_addr, inner_len, "keystore", ks->sig,
371 oem_keystore);
372 return ret;
373}
374
375static void read_oem_keystore()
376{
Shashank Mittale6797222014-09-19 18:58:43 -0700377 KEYSTORE *ks = NULL;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700378 uint32_t len = sizeof(OEM_KEYSTORE);
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800379 const unsigned char *input = OEM_KEYSTORE;
Shashank Mittale6797222014-09-19 18:58:43 -0700380
Shashank Mittal64d04852014-08-28 15:02:46 -0700381 if(oem_keystore != NULL)
382 return;
383
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800384 ks = d2i_KEYSTORE(NULL, (const unsigned char **) &input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700385 if(ks != NULL)
386 {
387 oem_keystore = ks;
388 user_keystore = ks;
389 }
390}
391
Shashank Mittal64d04852014-08-28 15:02:46 -0700392uint32_t boot_verify_keystore_init()
393{
394 /* Read OEM Keystore */
395 read_oem_keystore();
396
Shashank Mittal64d04852014-08-28 15:02:46 -0700397 return dev_boot_state;
398}
399
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700400bool send_rot_command(uint32_t is_unlocked)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700401{
402 int ret = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700403 unsigned char *input = NULL;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700404 char *rot_input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700405 unsigned int digest[9] = {0}, final_digest[8] = {0};
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700406 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
407 uint32_t boot_device_state = boot_verify_get_state();
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700408 int app_handle = 0;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700409 uint32_t len_oem_rsa = 0, len_from_cert = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700410 km_set_rot_req_t *read_req;
411 km_set_rot_rsp_t read_rsp;
412 app_handle = get_secapp_handle();
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700413 int n = 0, e = 0;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700414 switch (boot_device_state)
415 {
416 case GREEN:
417 // Locked device and boot.img verified against OEM keystore.
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700418 // Send hash of key from OEM KEYSTORE + Boot device state
419 n = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->n);
420 e = BN_num_bytes(oem_keystore->mykeybag->mykey->key_material->e);
vijay kumara89b9252015-12-10 16:10:03 +0530421 /*this assumes a valid acceptable range for RSA, including 4096 bits of modulo n. */
422 if (n<0 || n>1024)
423 {
424 dprintf(CRITICAL, "Invalid n value from key_material\n");
425 ASSERT(0);
426 }
427 /* 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 */
428 if( e < 0 || e >16)
429 {
430 dprintf(CRITICAL, "Invalid e value from key_material\n");
431 ASSERT(0);
432 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700433 len_oem_rsa = n + e;
434 if(!(input = malloc(len_oem_rsa)))
435 {
436 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
437 ASSERT(0);
438 }
439 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->n, input);
440 BN_bn2bin(oem_keystore->mykeybag->mykey->key_material->e, input+n);
441 hash_find((unsigned char *)input, len_oem_rsa, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700442 digest[8] = is_unlocked;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700443 break;
444 case YELLOW:
445 case RED:
446 // 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 -0700447 if (!rsa_from_cert)
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700448 {
449 dprintf(CRITICAL, "RSA is null from the embedded certificate\n");
450 ASSERT(0);
451 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700452 // Send hash of key from certificate in boot image + boot device state
453 n = BN_num_bytes(rsa_from_cert->n);
454 e = BN_num_bytes(rsa_from_cert->e);
vijay kumara89b9252015-12-10 16:10:03 +0530455 /*this assumes a valid acceptable range for RSA, including 4096 bits of modulo n. */
456 if (n<0 || n>1024)
457 {
458 dprintf(CRITICAL, "Invalid n value from rsa_from_cert\n");
459 ASSERT(0);
460 }
461 /* 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 */
462 if( e < 0 || e >16)
463 {
464 dprintf(CRITICAL, "Invalid e value from rsa_from_cert\n");
465 ASSERT(0);
466 }
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700467 len_from_cert = n + e;
468 if(!(input = malloc(len_from_cert)))
469 {
470 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
471 ASSERT(0);
472 }
473 BN_bn2bin(rsa_from_cert->n, input);
474 BN_bn2bin(rsa_from_cert->e, input+n);
475 hash_find((unsigned char *)input, len_from_cert, (unsigned char *) &digest, auth_algo);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700476 digest[8] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700477 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700478 case ORANGE:
479 // Unlocked device and no verification done.
480 // Send the hash of boot device state
481 input = NULL;
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700482 digest[0] = is_unlocked;
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700483 break;
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700484 }
485
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700486 hash_find((unsigned char *) digest, sizeof(digest), (unsigned char *)&final_digest, auth_algo);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700487 dprintf(SPEW, "Digest: ");
488 for(uint8_t i = 0; i < 8; i++)
489 dprintf(SPEW, "0x%x ", final_digest[i]);
490 dprintf(SPEW, "\n");
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700491 if(!(read_req = malloc(sizeof(km_set_rot_req_t) + sizeof(final_digest))))
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700492 {
493 dprintf(CRITICAL, "Failed to allocate memory for ROT structure\n");
494 ASSERT(0);
495 }
496
497 void *cpy_ptr = (uint8_t *) read_req + sizeof(km_set_rot_req_t);
498 // set ROT stucture
499 read_req->cmd_id = KEYMASTER_SET_ROT;
500 read_req->rot_ofset = (uint32_t) sizeof(km_set_rot_req_t);
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700501 read_req->rot_size = sizeof(final_digest);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700502 // copy the digest
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700503 memcpy(cpy_ptr, (void *) &final_digest, sizeof(final_digest));
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700504 dprintf(SPEW, "Sending Root of Trust to trustzone: start\n");
505
Sridhar Parasuram96300dc2015-06-11 10:37:11 -0700506 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 -0700507 if (ret < 0 || read_rsp.status < 0)
508 {
509 dprintf(CRITICAL, "QSEEcom command for Sending Root of Trust returned error: %d\n", read_rsp.status);
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700510 if(input)
511 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700512 free(read_req);
513 free(rot_input);
514 return false;
515 }
516 dprintf(SPEW, "Sending Root of Trust to trustzone: end\n");
Sridhar Parasuram24fb3952015-08-26 20:25:59 -0700517 if(input)
518 free(input);
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -0700519 free(read_req);
520 free(rot_input);
521 return true;
522}
523
lijuangf214e222015-07-16 20:06:22 +0800524unsigned char* get_boot_fingerprint(unsigned int* buf_size)
525{
526 *buf_size = fp_size;
527
528 return fp;
529}
530
Shashank Mittal64d04852014-08-28 15:02:46 -0700531bool boot_verify_image(unsigned char* img_addr, uint32_t img_size, char *pname)
532{
533 bool ret = false;
lijuangf214e222015-07-16 20:06:22 +0800534 X509 *cert = NULL;
535 const EVP_MD *fp_type = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700536 VERIFIED_BOOT_SIG *sig = NULL;
537 unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700538 uint32_t sig_len = 0;
539 unsigned char *signature = NULL;
Shashank Mittal64d04852014-08-28 15:02:46 -0700540
541 if(dev_boot_state == ORANGE)
542 {
543 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
544 dprintf(INFO, "boot_verifier: Skipping boot verification.\n");
545 return false;
546 }
547
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700548 signature = malloc(ASN1_SIGNATURE_BUFFER_SZ);
549 ASSERT(signature);
550
551 /* Copy the signature from scratch memory to buffer */
552 memcpy(signature, sig_addr, ASN1_SIGNATURE_BUFFER_SZ);
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530553 sig_len = read_der_message_length(signature, ASN1_SIGNATURE_BUFFER_SZ);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700554
Shashank Mittal64d04852014-08-28 15:02:46 -0700555 if(!sig_len)
556 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700557 dprintf(CRITICAL, "boot_verifier: Error while reading signature length.\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700558 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700559 }
560
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700561 if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
562 {
563 dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
564 goto verify_image_error;
565 }
566
Channagoud Kadabicda7e9b2015-09-17 13:25:35 -0700567 if (sig_len > ASN1_SIGNATURE_BUFFER_SZ)
568 {
569 dprintf(CRITICAL, "boot_verifier: Signature length exceeds size signature buffer\n");
570 goto verify_image_error;
571 }
572
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800573 if((sig = d2i_VERIFIED_BOOT_SIG(NULL, (const unsigned char **) &sig_addr, sig_len)) == NULL)
Shashank Mittal64d04852014-08-28 15:02:46 -0700574 {
575 dprintf(CRITICAL,
576 "boot_verifier: verification failure due to target name mismatch\n");
Sridhar Parasuramf391ec92015-08-27 14:01:42 -0700577 ASSERT(0);
Shashank Mittal64d04852014-08-28 15:02:46 -0700578 }
579
lijuangf214e222015-07-16 20:06:22 +0800580 cert = sig->certificate;
581 fp_type = EVP_sha1();
582 if(!X509_digest(cert, fp_type, (unsigned char *)fp, &fp_size)) {
583 dprintf(INFO,"Fail to create certificate fingerprint.\n");
584 }
585
Shashank Mittal64d04852014-08-28 15:02:46 -0700586 ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
587
Shashank Mittal64d04852014-08-28 15:02:46 -0700588 if(sig != NULL)
589 VERIFIED_BOOT_SIG_free(sig);
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -0700590verify_image_error:
591 free(signature);
Shashank Mittal64d04852014-08-28 15:02:46 -0700592 return ret;
593}
594
595void boot_verify_send_event(uint32_t event)
596{
597 switch(event)
598 {
599 case BOOT_INIT:
600 dev_boot_state = GREEN;
601 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700602 case BOOTIMG_KEYSTORE_VERIFICATION_PASS:
603 dev_boot_state = GREEN;
604 break;
605 case BOOTIMG_EMBEDDED_CERT_VERIFICATION_PASS:
Shashank Mittal64d04852014-08-28 15:02:46 -0700606 if(dev_boot_state == GREEN)
607 dev_boot_state = YELLOW;
608 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -0700609 case BOOTIMG_VERIFICATION_FAIL:
Shashank Mittal64d04852014-08-28 15:02:46 -0700610 if(dev_boot_state == GREEN || dev_boot_state == YELLOW)
611 dev_boot_state = RED;
612 break;
613 case DEV_UNLOCK:
614 dev_boot_state = ORANGE;
615 break;
616 case USER_DENIES:
617 if(dev_boot_state == YELLOW || dev_boot_state == ORANGE)
618 dev_boot_state = RED;
619 break;
620 }
621}
622
623uint32_t boot_verify_get_state()
624{
625 return dev_boot_state;
626}
627
628void boot_verify_print_state()
629{
630 switch(dev_boot_state)
631 {
632 case GREEN:
633 dprintf(INFO, "boot_verifier: Device is in GREEN boot state.\n");
634 break;
635 case ORANGE:
636 dprintf(INFO, "boot_verifier: Device is in ORANGE boot state.\n");
637 break;
638 case YELLOW:
639 dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
640 break;
641 case RED:
Unnati Gandhi8a7cdfe2015-05-11 13:04:20 +0530642 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");
643
Shashank Mittal64d04852014-08-28 15:02:46 -0700644 dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
645 break;
646 }
647}
648
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530649bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz)
Shashank Mittal64d04852014-08-28 15:02:46 -0700650{
651 bool ret = false;
652 unsigned char *input = user_addr;
Shashank Mittale6797222014-09-19 18:58:43 -0700653 KEYSTORE *ks = NULL;
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +0530654 uint32_t len = read_der_message_length(input, sz);
Shashank Mittale6797222014-09-19 18:58:43 -0700655 if(!len)
656 {
657 dprintf(CRITICAL, "boot_verifier: keystore length is invalid.\n");
658 return ret;
659 }
660
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800661 ks = d2i_KEYSTORE(NULL, (const unsigned char **)&input, len);
Shashank Mittal64d04852014-08-28 15:02:46 -0700662 if(ks != NULL)
663 {
664 ret = true;
665 }
666 return ret;
667}
668
Channagoud Kadabi1420b002015-01-13 14:48:12 -0800669static bool check_list(const char **list, const char* entry)
Shashank Mittal64d04852014-08-28 15:02:46 -0700670{
Shashank Mittal64d04852014-08-28 15:02:46 -0700671 if(list == NULL || entry == NULL)
672 return false;
673
674 while(*list != NULL)
675 {
676 if(!strcmp(entry, *list))
677 return true;
678
679 list++;
680 }
681
682 return false;
683}
684
Channagoud Kadabi583ea4c2015-09-08 14:55:09 -0700685KEYSTORE *boot_gerity_get_oem_keystore()
686{
687 read_oem_keystore();
688 return oem_keystore;
689}