blob: 9ae9890234d9377f2156bc48ff798a2db68949d1 [file] [log] [blame]
Amit Blay6281ebc2015-01-11 14:44:08 +02001/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <dev/fbcon.h>
31#include <target.h>
32#include <mmc.h>
33#include <partition_parser.h>
34#include <platform.h>
35#include <crypto_hash.h>
36#include <malloc.h>
37#include <sha.h>
38#include <string.h>
39#include <rand.h>
40#include <stdlib.h>
41#include "scm.h"
42#include "mdtp.h"
43
44#define DIP_ENCRYPT 0
45#define DIP_DECRYPT 1
46
Amit Blaydf42d2f2015-02-03 16:37:09 +020047static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
48static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
Amit Blay6281ebc2015-01-11 14:44:08 +020049
50/********************************************************************************/
51
52/* Read the DIP from EMMC */
Amit Blaydf42d2f2015-02-03 16:37:09 +020053static int read_DIP(DIP_t *dip)
Amit Blay6281ebc2015-01-11 14:44:08 +020054{
55 unsigned long long ptn = 0;
56 uint32_t actual_partition_size;
Amit Blaydf42d2f2015-02-03 16:37:09 +020057 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +020058
59 int index = INVALID_PTN;
60
61 ASSERT(dip != NULL);
62
63 index = partition_get_index("dip");
64 ptn = partition_get_offset(index);
65
66 if(ptn == 0)
67 {
68 return -1;
69 }
70
71 actual_partition_size = ROUNDUP(sizeof(DIP_t), block_size);
72
73 if(mmc_read(ptn, (void *)dip, actual_partition_size))
74 {
75 dprintf(CRITICAL, "mdtp: read_DIP: ERROR, cannot read DIP info\n");
76 return -1;
77 }
78
Reut Zysman18411272015-02-09 13:47:27 +020079 dprintf(SPEW, "mdtp: read_DIP: SUCCESS, read %d bytes\n", actual_partition_size);
Amit Blay6281ebc2015-01-11 14:44:08 +020080
81 return 0;
82}
83
84/* Store the DIP into the EMMC */
Amit Blaydf42d2f2015-02-03 16:37:09 +020085static int write_DIP(DIP_t *dip)
Amit Blay6281ebc2015-01-11 14:44:08 +020086{
87 unsigned long long ptn = 0;
Amit Blaydf42d2f2015-02-03 16:37:09 +020088 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +020089
90 int index = INVALID_PTN;
91
92 ASSERT(dip != NULL);
93
94 index = partition_get_index("dip");
95 ptn = partition_get_offset(index);
Reut Zysman18411272015-02-09 13:47:27 +020096
Amit Blay6281ebc2015-01-11 14:44:08 +020097 if(ptn == 0)
98 {
99 return -1;
100 }
101
Reut Zysman18411272015-02-09 13:47:27 +0200102 if(mmc_write(ptn, ROUNDUP(sizeof(DIP_t), block_size), (void *)dip))
Amit Blay6281ebc2015-01-11 14:44:08 +0200103 {
104 dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot read DIP info\n");
105 return -1;
106 }
107
Reut Zysman18411272015-02-09 13:47:27 +0200108 dprintf(SPEW, "mdtp: write_DIP: SUCCESS, write %d bytes\n", ROUNDUP(sizeof(DIP_t), block_size));
109
Amit Blay6281ebc2015-01-11 14:44:08 +0200110 return 0;
111}
112
Reut Zysman18411272015-02-09 13:47:27 +0200113/* Deactivate MDTP by storing the default DIP into the EMMC */
114static void write_deactivated_DIP()
Amit Blay6281ebc2015-01-11 14:44:08 +0200115{
Amit Blaydf42d2f2015-02-03 16:37:09 +0200116 DIP_t *enc_dip;
117 DIP_t *dec_dip;
Amit Blay6281ebc2015-01-11 14:44:08 +0200118 int ret;
119
120 enc_dip = malloc(sizeof(DIP_t));
121 if (enc_dip == NULL)
122 {
Reut Zysman18411272015-02-09 13:47:27 +0200123 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200124 return;
125 }
126
127 dec_dip = malloc(sizeof(DIP_t));
128 if (dec_dip == NULL)
129 {
Reut Zysman18411272015-02-09 13:47:27 +0200130 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200131 free(enc_dip);
132 return;
133 }
134
135 memset(dec_dip, 0, sizeof(DIP_t));
136
137 dec_dip->status = DIP_STATUS_DEACTIVATED;
138
139 ret = mdtp_tzbsp_enc_hash_DIP(dec_dip, enc_dip);
140 if(ret < 0)
141 {
Reut Zysman18411272015-02-09 13:47:27 +0200142 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot cipher DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200143 goto out;
144 }
145
146 ret = write_DIP(enc_dip);
147 if(ret < 0)
148 {
Reut Zysman18411272015-02-09 13:47:27 +0200149 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot write DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200150 goto out;
151 }
152
153out:
154 free(enc_dip);
155 free(dec_dip);
156}
157
158/* Validate a hash calculated on entire given partition */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200159static int verify_partition_single_hash(char *name, uint32_t size, DIP_hash_table_entry_t *hash_table)
Amit Blay6281ebc2015-01-11 14:44:08 +0200160{
Amit Blay6281ebc2015-01-11 14:44:08 +0200161 unsigned char digest[32]={0};
162 unsigned long long ptn = 0;
163 int index = INVALID_PTN;
164 unsigned char *buf = (unsigned char *)target_get_scratch_address();
Amit Blaydf42d2f2015-02-03 16:37:09 +0200165 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200166 uint32_t actual_partition_size = ROUNDUP(size, block_size);
167
Reut Zysman18411272015-02-09 13:47:27 +0200168 dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
Amit Blay6281ebc2015-01-11 14:44:08 +0200169
170 ASSERT(name != NULL);
171 ASSERT(hash_table != NULL);
172
173 index = partition_get_index(name);
174 ptn = partition_get_offset(index);
175
176 if(ptn == 0) {
177 dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: partition was not found\n", name);
178 return -1;
179 }
180
Amit Blay6281ebc2015-01-11 14:44:08 +0200181 if (mmc_read(ptn, (void *)buf, actual_partition_size))
182 {
183 dprintf(CRITICAL, "mdtp: verify_partition__single_hash: %s: mmc_read() fail.\n", name);
184 return -1;
185 }
186
Amit Blayfe649212015-01-25 11:21:10 +0200187 /* calculating the hash value using HW crypto */
188 target_crypto_init_params();
189 hash_find(buf, size, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
Amit Blay6281ebc2015-01-11 14:44:08 +0200190
Amit Blayfe649212015-01-25 11:21:10 +0200191 if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
Amit Blay6281ebc2015-01-11 14:44:08 +0200192 {
193 dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: Failed partition hash verification\n", name);
194
195 return -1;
196 }
197
Reut Zysman18411272015-02-09 13:47:27 +0200198 dprintf(SPEW, "verify_partition_single_hash: %s: VERIFIED!\n", name);
Amit Blay6281ebc2015-01-11 14:44:08 +0200199
200 return 0;
201}
202
203/* Validate a hash table calculated per block of a given partition */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200204static int verify_partition_block_hash(char *name,
Amit Blay6281ebc2015-01-11 14:44:08 +0200205 uint32_t size,
206 uint32_t total_num_blocks,
207 uint32_t verify_num_blocks,
Amit Blaydf42d2f2015-02-03 16:37:09 +0200208 DIP_hash_table_entry_t *hash_table,
Amit Blay6281ebc2015-01-11 14:44:08 +0200209 uint8_t *force_verify_block)
210{
Amit Blay6281ebc2015-01-11 14:44:08 +0200211 unsigned char digest[32]={0};
212 unsigned long long ptn = 0;
213 int index = INVALID_PTN;
214 unsigned char *buf = (unsigned char *)target_get_scratch_address();
215 uint32_t bytes_to_read;
216 uint32_t block_num = 0;
217
Reut Zysman18411272015-02-09 13:47:27 +0200218 dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %u\n", name, size);
Amit Blay6281ebc2015-01-11 14:44:08 +0200219
220 ASSERT(name != NULL);
221 ASSERT(hash_table != NULL);
222
223 index = partition_get_index(name);
224 ptn = partition_get_offset(index);
225
226 if(ptn == 0) {
227 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: partition was not found\n", name);
228 return -1;
229 }
230
Amit Blayfe649212015-01-25 11:21:10 +0200231 /* initiating parameters for hash calculation using HW crypto */
232 target_crypto_init_params();
233
Amit Blay6281ebc2015-01-11 14:44:08 +0200234 while (MDTP_FWLOCK_BLOCK_SIZE * block_num < size)
235 {
236 if (*force_verify_block == 0)
237 {
238 /* Skip validation of this block with probability of verify_num_blocks / total_num_blocks */
239 if ((rand() % total_num_blocks) >= verify_num_blocks)
240 {
241 block_num++;
242 hash_table += 1;
243 force_verify_block += 1;
244 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: skipped verification of block %d\n", name, block_num);
245 continue;
246 }
247 }
248
Amit Blay6281ebc2015-01-11 14:44:08 +0200249 if ((size - (MDTP_FWLOCK_BLOCK_SIZE * block_num) < MDTP_FWLOCK_BLOCK_SIZE))
250 {
251 bytes_to_read = size - (MDTP_FWLOCK_BLOCK_SIZE * block_num);
252 } else
253 {
254 bytes_to_read = MDTP_FWLOCK_BLOCK_SIZE;
255 }
256
257 if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, bytes_to_read))
258 {
259 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: mmc_read() fail.\n", name);
260 return -1;
261 }
262
Amit Blayfe649212015-01-25 11:21:10 +0200263 /* calculating the hash value using HW */
264 hash_find(buf, bytes_to_read, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
Amit Blay6281ebc2015-01-11 14:44:08 +0200265
Amit Blayfe649212015-01-25 11:21:10 +0200266 if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
Amit Blay6281ebc2015-01-11 14:44:08 +0200267 {
268 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: Failed partition hash[%d] verification\n", name, block_num);
269 return -1;
270 }
271
272 block_num++;
273 hash_table += 1;
274 force_verify_block += 1;
275 }
276
Reut Zysman18411272015-02-09 13:47:27 +0200277 dprintf(SPEW, "verify_partition_block_hash: %s: VERIFIED!\n", name);
Amit Blay6281ebc2015-01-11 14:44:08 +0200278
279 return 0;
280}
281
282/* Verify a given partitinon */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200283static int verify_partition(char *name,
Amit Blay6281ebc2015-01-11 14:44:08 +0200284 uint32_t size,
285 mdtp_fwlock_mode_t hash_mode,
286 uint32_t total_num_blocks,
287 uint32_t verify_num_blocks,
288 DIP_hash_table_entry_t *hash_table,
289 uint8_t *force_verify_block)
290{
291
292 ASSERT(name != NULL);
293 ASSERT(hash_table != NULL);
294
295 if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
296 {
297 return verify_partition_single_hash(name, size, hash_table);
298 } else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
299 {
300 return verify_partition_block_hash(name, size, total_num_blocks, verify_num_blocks, hash_table, force_verify_block);
301 }
302 else
303 {
304 dprintf(CRITICAL, "mdtp: verify_partition: %s: Wrong DIP partition hash mode\n", name);
305 return -1;
306 }
307
308 return 0;
309}
310
Reut Zysman18411272015-02-09 13:47:27 +0200311/* Display the recovery UI to allow the user to enter the PIN and continue boot */
312static int display_recovery_ui(DIP_t *dip)
313{
314 uint32_t pin_length = 0;
315 char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
316 uint32_t i;
317 uint32_t equal_count = 0, different_count = 0;
318
319 if (dip->mdtp_cfg.enable_local_pin_authentication)
320 {
321 dprintf(SPEW, "mdtp: display_recovery_ui: Local deactivation enabled\n");
322
323 pin_length = strlen(dip->mdtp_cfg.mdtp_pin.mdtp_pin);
324
325 if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
326 {
327 dprintf(CRITICAL, "mdtp: display_recovery_ui: Error, invalid PIN length\n");
328 display_error_msg();
329 return -1;
330 }
331
332 // Set entered_pin to initial '0' string + null terminator
333 for (i=0; i<pin_length; i++)
334 {
335 entered_pin[i] = '0';
336 }
337
338 // Allow the user to enter the PIN as many times as he wishes
339 // (with INVALID_PIN_DELAY_MSECONDS after each failed attempt)
340 while (1)
341 {
342 get_pin_from_user(entered_pin, pin_length);
343
344 // Go over the entire PIN in any case, to prevent side-channel attacks
345 for (i=0; i<pin_length; i++)
346 {
347 if (dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] == entered_pin[i])
348 equal_count++;
349 else
350 different_count++;
351 }
352
353 if (equal_count == pin_length)
354 {
355 // Valid PIN - deactivate and continue boot
356 dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
357 write_deactivated_DIP();
358 return 0;
359 }
360 else
361 {
362 // Invalid PIN - display an appropriate message (which also includes a wait
363 // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
364 dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
365 display_invalid_pin_msg();
366
367 equal_count = 0;
368 different_count = 0;
369 }
370 }
371 }
372 else
373 {
374 dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
375 display_error_msg();
376 return -1;
377 }
378}
379
Amit Blay6281ebc2015-01-11 14:44:08 +0200380/* Verify all protected partitinons according to the DIP */
381static int verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
382{
383 int i;
384 int verify_failure = 0;
385 uint32_t total_num_blocks;
386
387 ASSERT(dip != NULL);
388 ASSERT(verify_result != NULL);
389
390 *verify_result = VERIFY_FAILED;
391
392 if (dip->status == DIP_STATUS_DEACTIVATED)
393 {
394 *verify_result = VERIFY_SKIPPED;
395 return 0;
396 }
397 else if (dip->status == DIP_STATUS_ACTIVATED)
398 {
Amit Blay6281ebc2015-01-11 14:44:08 +0200399 for(i=0; i<MAX_PARTITIONS; i++)
400 {
401 if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
402 {
403 total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
404
405 verify_failure |= verify_partition(dip->partition_cfg[i].name,
406 dip->partition_cfg[i].size,
407 dip->partition_cfg[i].hash_mode,
408 total_num_blocks,
409 (dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
410 dip->partition_cfg[i].hash_table,
411 dip->partition_cfg[i].force_verify_block);
412 }
413 }
414
415 if (verify_failure)
416 {
417 dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
Reut Zysman18411272015-02-09 13:47:27 +0200418 return 0;
Amit Blay6281ebc2015-01-11 14:44:08 +0200419 }
420
421 }
422
423 *verify_result = VERIFY_OK;
Amit Blay6281ebc2015-01-11 14:44:08 +0200424 return 0;
425}
426
427/* Verify the DIP and all protected partitions */
428static void validate_DIP_and_firmware()
429{
430 int ret;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200431 DIP_t *enc_dip;
432 DIP_t *dec_dip;
Amit Blay6281ebc2015-01-11 14:44:08 +0200433 uint32_t verified = 0;
434 verify_result_t verify_result;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200435 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200436
437 enc_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
438 if (enc_dip == NULL)
439 {
Reut Zysman18411272015-02-09 13:47:27 +0200440 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200441 return;
442 }
443
444 dec_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
445 if (dec_dip == NULL)
446 {
Reut Zysman18411272015-02-09 13:47:27 +0200447 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200448 free(enc_dip);
449 return;
450 }
451
452 /* Read the DIP holding the MDTP Firmware Lock state from the DIP partition */
453 ret = read_DIP(enc_dip);
454 if(ret < 0)
455 {
456 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot read DIP\n");
457 goto out;
458 }
459
460 /* Decrypt and verify the integrity of the DIP */
461 ret = mdtp_tzbsp_dec_verify_DIP(enc_dip, dec_dip, &verified);
462 if(ret < 0)
463 {
464 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify DIP\n");
Reut Zysman18411272015-02-09 13:47:27 +0200465 display_error_msg();
Amit Blay6281ebc2015-01-11 14:44:08 +0200466 goto out;
467 }
468
469 /* In case DIP integrity verification fails, notify the user and halt */
470 if(!verified)
471 {
472 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted DIP\n");
Reut Zysman18411272015-02-09 13:47:27 +0200473 display_error_msg();
Amit Blay6281ebc2015-01-11 14:44:08 +0200474 goto out;
475 }
476
477 /* Verify the integrity of the partitions which are protectedm, according to the content of the DIP */
478 ret = verify_all_partitions(dec_dip, &verify_result);
479 if(ret < 0)
480 {
481 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify firmware\n");
482 goto out;
483 }
484
485 if (verify_result == VERIFY_OK)
486 {
Reut Zysman18411272015-02-09 13:47:27 +0200487 dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200488 }
489 else if (verify_result == VERIFY_FAILED)
490 {
491 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
Reut Zysman18411272015-02-09 13:47:27 +0200492 display_recovery_ui(dec_dip);
Amit Blay6281ebc2015-01-11 14:44:08 +0200493 } else /* VERIFY_SKIPPED */
494 {
Reut Zysman18411272015-02-09 13:47:27 +0200495 dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200496 }
497
498out:
499 free(enc_dip);
500 free(dec_dip);
501
502 return;
503}
504
505/********************************************************************************/
506
507/** Entry point of the MDTP Firmware Lock: If needed, verify the DIP
508 * and all protected partitions **/
509
510int mdtp_fwlock_verify_lock()
511{
Amit Blaydf42d2f2015-02-03 16:37:09 +0200512 int ret;
513 bool enabled;
Amit Blay6281ebc2015-01-11 14:44:08 +0200514
Amit Blaydf42d2f2015-02-03 16:37:09 +0200515 ret = mdtp_fuse_get_enabled(&enabled);
516 if(ret)
Amit Blay6281ebc2015-01-11 14:44:08 +0200517 {
Amit Blaydf42d2f2015-02-03 16:37:09 +0200518 dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200519 return -1;
520 }
521
Amit Blaydf42d2f2015-02-03 16:37:09 +0200522 /* Continue with Firmware Lock verification only if enabled by eFuse */
523 if (enabled)
Amit Blay6281ebc2015-01-11 14:44:08 +0200524 {
525 validate_DIP_and_firmware();
526 }
527
528 return 0;
529}
530
531/********************************************************************************/
532
Amit Blay6281ebc2015-01-11 14:44:08 +0200533/* Decrypt a given DIP and verify its integrity */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200534static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified)
Amit Blay6281ebc2015-01-11 14:44:08 +0200535{
Amit Blaydf42d2f2015-02-03 16:37:09 +0200536 unsigned char *hash_p;
Amit Blay6281ebc2015-01-11 14:44:08 +0200537 unsigned char hash[HASH_LEN];
538 SHA256_CTX sha256_ctx;
539 int ret;
540
541 ASSERT(enc_dip != NULL);
542 ASSERT(dec_dip != NULL);
543 ASSERT(verified != NULL);
544
545 ret = mdtp_cipher_dip_cmd((uint8_t*)enc_dip, sizeof(DIP_t),
546 (uint8_t*)dec_dip, sizeof(DIP_t),
547 DIP_DECRYPT);
548 if (ret)
549 {
550 dprintf(CRITICAL, "mdtp: mdtp_tzbsp_dec_verify_DIP: ERROR, cannot cipher DIP\n");
551 *verified = 0;
552 return -1;
553 }
554
555 SHA256_Init(&sha256_ctx);
556 SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
557 SHA256_Final(hash, &sha256_ctx);
558
559 hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
560
561 if (memcmp(hash, hash_p, HASH_LEN))
562 {
563 *verified = 0;
564 }
565 else
566 {
567 *verified = 1;
568 }
569
570 return 0;
571}
572
Amit Blaydf42d2f2015-02-03 16:37:09 +0200573static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
Amit Blay6281ebc2015-01-11 14:44:08 +0200574{
Amit Blaydf42d2f2015-02-03 16:37:09 +0200575 unsigned char *hash_p;
Amit Blay6281ebc2015-01-11 14:44:08 +0200576 SHA256_CTX sha256_ctx;
577 int ret;
578
579 ASSERT(dec_dip != NULL);
580 ASSERT(enc_dip != NULL);
581
582 hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
583
584 SHA256_Init(&sha256_ctx);
585 SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
586 SHA256_Final(hash_p, &sha256_ctx);
587
588 ret = mdtp_cipher_dip_cmd((uint8_t*)dec_dip, sizeof(DIP_t),
589 (uint8_t*)enc_dip, sizeof(DIP_t),
590 DIP_ENCRYPT);
591 if (ret)
592 {
593 dprintf(CRITICAL, "mdtp: mdtp_tzbsp_enc_hash_DIP: ERROR, cannot cipher DIP\n");
594 return -1;
595 }
596
597 return 0;
598}