Merge "aboot: mdtp: Address security review"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index ca48092..88e192d 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -3010,6 +3010,12 @@
 normal_boot:
 	if (!boot_into_fastboot)
 	{
+#ifdef MDTP_SUPPORT
+			/* Go through Firmware Lock verification before continue with boot process */
+			mdtp_fwlock_verify_lock();
+			display_image_on_screen();
+#endif /* MDTP_SUPPORT */
+
 		if (target_is_emmc_boot())
 		{
 			if(emmc_recovery_init())
@@ -3027,12 +3033,6 @@
 				}
 			}
 
-#ifdef MDTP_SUPPORT
-			/* Go through Firmware Lock verification before continue with boot process */
-			mdtp_fwlock_verify_lock();
-			display_image_on_screen();
-#endif /* MDTP_SUPPORT */
-
 			boot_linux_from_mmc();
 		}
 		else
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 160f6c8..5c5782a 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -44,10 +44,22 @@
 #define DIP_ENCRYPT 0
 #define DIP_DECRYPT 1
 
+#define MDTP_MAJOR_VERSION (0)
+#define MDTP_MINOR_VERSION (2)
+
+/** Extract major version number from complete version. */
+#define MDTP_GET_MAJOR_VERSION(version) ((version) >> 16)
+
+static int is_mdtp_activated = -1;
+
 static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
 
-static int is_mdtp_activated = -1;
+uint32_t g_mdtp_version = (((MDTP_MAJOR_VERSION << 16) & 0xFFFF0000) | (MDTP_MINOR_VERSION & 0x0000FFFF));
+
+int scm_random(uint32_t * rbuf, uint32_t  r_len);
+int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+
 /********************************************************************************/
 
 /* Read the DIP from EMMC */
@@ -102,7 +114,7 @@
 
 	if(mmc_write(ptn, ROUNDUP(sizeof(DIP_t), block_size), (void *)dip))
 	{
-		dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot read DIP info\n");
+		dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot write DIP info\n");
 		return -1;
 	}
 
@@ -136,6 +148,7 @@
 	memset(dec_dip, 0, sizeof(DIP_t));
 
 	dec_dip->status = DIP_STATUS_DEACTIVATED;
+	dec_dip->version = g_mdtp_version;
 
 	ret = mdtp_tzbsp_enc_hash_DIP(dec_dip, enc_dip);
 	if(ret < 0)
@@ -157,19 +170,20 @@
 }
 
 /* Validate a hash calculated on entire given partition */
-static int verify_partition_single_hash(char *name, uint32_t size, DIP_hash_table_entry_t *hash_table)
+static int verify_partition_single_hash(char *name, uint64_t size, DIP_hash_table_entry_t *hash_table)
 {
-	unsigned char digest[32]={0};
+	unsigned char digest[HASH_LEN]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
 	unsigned char *buf = (unsigned char *)target_get_scratch_address();
 	uint32_t block_size = mmc_get_device_blocksize();
-	uint32_t actual_partition_size = ROUNDUP(size, block_size);
+	uint64_t actual_partition_size = ROUNDUP(size, block_size);
 
-	dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
+	dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %llu\n", name, size);
 
 	ASSERT(name != NULL);
 	ASSERT(hash_table != NULL);
+	ASSERT(size > 0);
 
 	index = partition_get_index(name);
 	ptn = partition_get_offset(index);
@@ -181,15 +195,15 @@
 
 	if (mmc_read(ptn, (void *)buf, actual_partition_size))
 	{
-		dprintf(CRITICAL, "mdtp: verify_partition__single_hash: %s: mmc_read() fail.\n", name);
+		dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: mmc_read() fail.\n", name);
 		return -1;
 	}
 
 	/* calculating the hash value using HW crypto */
 	target_crypto_init_params();
-	hash_find(buf, size, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
+	hash_find(buf, size, digest, CRYPTO_AUTH_ALG_SHA256);
 
-	if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
+	if (memcmp(digest, hash_table->hash, HASH_LEN))
 	{
 		dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: Failed partition hash verification\n", name);
 
@@ -203,23 +217,27 @@
 
 /* Validate a hash table calculated per block of a given partition */
 static int verify_partition_block_hash(char *name,
-								uint32_t size,
-								uint32_t total_num_blocks,
+								uint64_t size,
 								uint32_t verify_num_blocks,
 								DIP_hash_table_entry_t *hash_table,
-							    uint8_t *force_verify_block)
+								uint8_t *force_verify_block)
 {
-	unsigned char digest[32]={0};
+	unsigned char digest[HASH_LEN]={0};
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
 	unsigned char *buf = (unsigned char *)target_get_scratch_address();
 	uint32_t bytes_to_read;
 	uint32_t block_num = 0;
+	uint32_t total_num_blocks = ((size - 1) / MDTP_FWLOCK_BLOCK_SIZE) + 1;
+	uint32_t rand_int;
+	uint32_t block_size = mmc_get_device_blocksize();
 
-	dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %u\n", name, size);
+	dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %llu\n", name, size);
 
 	ASSERT(name != NULL);
 	ASSERT(hash_table != NULL);
+	ASSERT(size > 0);
+	ASSERT(force_verify_block != NULL);
 
 	index = partition_get_index(name);
 	ptn = partition_get_offset(index);
@@ -231,13 +249,24 @@
 
 	/* initiating parameters for hash calculation using HW crypto */
 	target_crypto_init_params();
+	if (check_aboot_addr_range_overlap((uint32_t)buf, ROUNDUP(MDTP_FWLOCK_BLOCK_SIZE, block_size)))
+	{
+		dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: image buffer address overlaps with aboot addresses.\n", name);
+		return -1;
+	}
 
 	while (MDTP_FWLOCK_BLOCK_SIZE * block_num < size)
 	{
 		if (*force_verify_block == 0)
 		{
+			if(scm_random((uint32_t *)&rand_int, sizeof(rand_int)))
+			{
+				dprintf(CRITICAL,"mdtp: scm_call for random failed\n");
+				return -1;
+			}
+
 			/* Skip validation of this block with probability of verify_num_blocks / total_num_blocks */
-			if ((rand() % total_num_blocks) >= verify_num_blocks)
+			if ((rand_int % total_num_blocks) >= verify_num_blocks)
 			{
 				block_num++;
 				hash_table += 1;
@@ -255,16 +284,16 @@
 			bytes_to_read = MDTP_FWLOCK_BLOCK_SIZE;
 		}
 
-		if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, bytes_to_read))
+		if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, ROUNDUP(bytes_to_read, block_size)))
 		{
 			dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: mmc_read() fail.\n", name);
 			return -1;
 		}
 
 		/* calculating the hash value using HW */
-		hash_find(buf, bytes_to_read, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
+		hash_find(buf, bytes_to_read, digest, CRYPTO_AUTH_ALG_SHA256);
 
-		if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
+		if (memcmp(digest, hash_table->hash, HASH_LEN))
 		{
 			dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: Failed partition hash[%d] verification\n", name, block_num);
 			return -1;
@@ -280,42 +309,80 @@
 	return 0;
 }
 
-/* Verify a given partitinon */
-static int verify_partition(char *name,
-						uint32_t size,
+/* Validate the partition parameters read from DIP */
+static int validate_partition_params(uint64_t size,
 						mdtp_fwlock_mode_t hash_mode,
-						uint32_t total_num_blocks,
-						uint32_t verify_num_blocks,
-						DIP_hash_table_entry_t *hash_table,
-						uint8_t *force_verify_block)
+						uint32_t verify_ratio)
 {
-
-	ASSERT(name != NULL);
-	ASSERT(hash_table != NULL);
-
-	if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
+	if (size == 0 || size > (uint64_t)MDTP_FWLOCK_BLOCK_SIZE * (uint64_t)MAX_BLOCKS ||
+		hash_mode >= MDTP_FWLOCK_MODE_SIZE || verify_ratio > 100)
 	{
-		return verify_partition_single_hash(name, size, hash_table);
-	} else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
-	{
-		return verify_partition_block_hash(name, size, total_num_blocks, verify_num_blocks, hash_table, force_verify_block);
-	}
-	else
-	{
-		dprintf(CRITICAL, "mdtp: verify_partition: %s: Wrong DIP partition hash mode\n", name);
+		dprintf(CRITICAL, "mdtp: validate_partition_params: error, size=%llu, hash_mode=%d, verify_ratio=%d\n",
+			size, hash_mode, verify_ratio);
 		return -1;
 	}
 
 	return 0;
 }
 
+/* Verify a given partitinon */
+static int verify_partition(char *name,
+						uint64_t size,
+						mdtp_fwlock_mode_t hash_mode,
+						uint32_t verify_num_blocks,
+						DIP_hash_table_entry_t *hash_table,
+						uint8_t *force_verify_block)
+{
+	if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
+	{
+		return verify_partition_single_hash(name, size, hash_table);
+	} else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
+	{
+		return verify_partition_block_hash(name, size, verify_num_blocks, hash_table, force_verify_block);
+	}
+
+	/* Illegal value of hash_mode */
+	return -1;
+}
+
+static int validate_dip(DIP_t *dip)
+{
+	uint8_t *dip_p;
+
+	ASSERT(dip != NULL);
+
+	/* Make sure DIP version is supported by current SW */
+	if (MDTP_GET_MAJOR_VERSION(dip->version) != MDTP_MAJOR_VERSION)
+	{
+		dprintf(CRITICAL, "mdtp: validate_dip: Wrong DIP version 0x%x\n", dip->version);
+		return -1;
+	}
+
+	/* Make sure that deactivated DIP content is as expected */
+	if (dip->status == DIP_STATUS_DEACTIVATED)
+	{
+		dip_p = (uint8_t*)&dip->mdtp_cfg;
+		while (dip_p < dip->hash)
+		{
+			if (*dip_p != 0)
+			{
+				dprintf(CRITICAL, "mdtp: validate_dip: error in deactivated DIP\n");
+				return -1;
+			}
+			dip_p++;
+		}
+	}
+
+	return 0;
+}
+
 /* Display the recovery UI to allow the user to enter the PIN and continue boot */
-static int display_recovery_ui(DIP_t *dip)
+static void display_recovery_ui(DIP_t *dip)
 {
 	uint32_t pin_length = 0;
 	char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
 	uint32_t i;
-	uint32_t equal_count = 0, different_count = 0;
+	char pin_mismatch = 0;
 
 	if (dip->mdtp_cfg.enable_local_pin_authentication)
 	{
@@ -326,8 +393,7 @@
 		if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
 		{
 			dprintf(CRITICAL, "mdtp: display_recovery_ui: Error, invalid PIN length\n");
-			display_error_msg();
-			return -1;
+			display_error_msg(); /* This will never return */
 		}
 
 		// Set entered_pin to initial '0' string + null terminator
@@ -340,49 +406,44 @@
 		// (with INVALID_PIN_DELAY_MSECONDS after each failed attempt)
 		while (1)
 		{
-		    get_pin_from_user(entered_pin, pin_length);
+			get_pin_from_user(entered_pin, pin_length);
 
-		    // Go over the entire PIN in any case, to prevent side-channel attacks
-		    for (i=0; i<pin_length; i++)
-		    {
-		        if (dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] == entered_pin[i])
-		            equal_count++;
-		        else
-		            different_count++;
-		    }
+			// Go over the entire PIN in any case, to prevent side-channel attacks
+			for (i=0; i<pin_length; i++)
+			{
+				pin_mismatch |= dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] ^ entered_pin[i];
+			}
 
-		    if (equal_count == pin_length)
-		    {
-		        // Valid PIN - deactivate and continue boot
-		        dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
-		        write_deactivated_DIP();
-		        return 0;
-		    }
-		    else
-		    {
-		        // Invalid PIN - display an appropriate message (which also includes a wait
-		        // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
-		        dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
-		        display_invalid_pin_msg();
+			if (0 == pin_mismatch)
+			{
+				// Valid PIN - deactivate and continue boot
+				dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
+				write_deactivated_DIP();
+				return;
+			}
+			else
+			{
+				// Invalid PIN - display an appropriate message (which also includes a wait
+				// for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
+				dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
+				display_invalid_pin_msg();
 
-		        equal_count = 0;
-		        different_count = 0;
-		    }
+				pin_mismatch = 0;
+			}
 		}
 	}
 	else
 	{
 		dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
-		display_error_msg();
-		return -1;
+		display_error_msg(); /* This will never return */
 	}
 }
 
 /* Verify all protected partitinons according to the DIP */
-static int verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
+static void verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
 {
 	int i;
-	int verify_failure = 0;
+	bool verify_failure = FALSE;
 	uint32_t total_num_blocks;
 
 	ASSERT(dip != NULL);
@@ -390,40 +451,53 @@
 
 	*verify_result = VERIFY_FAILED;
 
+	if (validate_dip(dip))
+	{
+		dprintf(CRITICAL, "mdtp: verify_all_partitions: failed DIP validation\n");
+		return;
+	}
+
 	if (dip->status == DIP_STATUS_DEACTIVATED)
 	{
 		*verify_result = VERIFY_SKIPPED;
-		return 0;
+		return;
 	}
-	else if (dip->status == DIP_STATUS_ACTIVATED)
+	else
 	{
 		for(i=0; i<MAX_PARTITIONS; i++)
 		{
 			if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
 			{
 				total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
+				if (validate_partition_params(dip->partition_cfg[i].size,
+					dip->partition_cfg[i].hash_mode,
+					dip->partition_cfg[i].verify_ratio))
+				{
+					dprintf(CRITICAL, "mdtp: verify_all_partitions: Wrong partition parameters\n");
+					verify_failure = TRUE;
+					break;
+				}
 
-				verify_failure |= verify_partition(dip->partition_cfg[i].name,
+				verify_failure |= (verify_partition(dip->partition_cfg[i].name,
 							 dip->partition_cfg[i].size,
 							 dip->partition_cfg[i].hash_mode,
-							 total_num_blocks,
 							 (dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
 							 dip->partition_cfg[i].hash_table,
-							 dip->partition_cfg[i].force_verify_block);
+							 dip->partition_cfg[i].force_verify_block) != 0);
 			}
 		}
 
 		if (verify_failure)
 		{
 			dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
-			return 0;
+			return;
 		}
 		is_mdtp_activated = 1;
 
 	}
 
 	*verify_result = VERIFY_OK;
-	return 0;
+	return;
 }
 
 /* Verify the DIP and all protected partitions */
@@ -440,7 +514,7 @@
 	if (enc_dip == NULL)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
-		return;
+		display_error_msg(); /* This will never return */
 	}
 
 	dec_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
@@ -448,7 +522,7 @@
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
 		free(enc_dip);
-		return;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Read the DIP holding the MDTP Firmware Lock state from the DIP partition */
@@ -456,7 +530,7 @@
 	if(ret < 0)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot read DIP\n");
-		goto out;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Decrypt and verify the integrity of the DIP */
@@ -464,40 +538,35 @@
 	if(ret < 0)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify DIP\n");
-		display_error_msg();
-		goto out;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* In case DIP integrity verification fails, notify the user and halt */
 	if(!verified)
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted DIP\n");
-		display_error_msg();
-		goto out;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Verify the integrity of the partitions which are protectedm, according to the content of the DIP */
-	ret = verify_all_partitions(dec_dip, &verify_result);
-	if(ret < 0)
-	{
-		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify firmware\n");
-		goto out;
-	}
+	verify_all_partitions(dec_dip, &verify_result);
+
+	/* Clear decrypted DIP since we don't need it anymore */
+	memset(dec_dip, 0, sizeof(DIP_t));
 
 	if (verify_result == VERIFY_OK)
 	{
 		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
 	}
-	else if (verify_result  == VERIFY_FAILED)
+	else if (verify_result  == VERIFY_SKIPPED)
+	{
+		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
+	} else /* VERIFY_FAILED */
 	{
 		dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
 		display_recovery_ui(dec_dip);
-	} else /* VERIFY_SKIPPED */
-	{
-		dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
 	}
 
-out:
 	free(enc_dip);
 	free(dec_dip);
 
@@ -509,7 +578,7 @@
 /** Entry point of the MDTP Firmware Lock: If needed, verify the DIP
  *  and all protected partitions **/
 
-int mdtp_fwlock_verify_lock()
+void mdtp_fwlock_verify_lock()
 {
 	int ret;
 	bool enabled;
@@ -521,16 +590,15 @@
 	if(ret)
 	{
 		dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
-		return -1;
+		display_error_msg(); /* This will never return */
 	}
 
 	/* Continue with Firmware Lock verification only if enabled by eFuse */
 	if (enabled)
 	{
+		/* This function will handle firmware verification failure via UI */
 		validate_DIP_and_firmware();
 	}
-
-	return 0;
 }
 /********************************************************************************/
 
@@ -550,7 +618,6 @@
 /* Decrypt a given DIP and verify its integrity */
 static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified)
 {
-	unsigned char *hash_p;
 	unsigned char hash[HASH_LEN];
 	SHA256_CTX sha256_ctx;
 	int ret;
@@ -566,6 +633,7 @@
 	{
 		dprintf(CRITICAL, "mdtp: mdtp_tzbsp_dec_verify_DIP: ERROR, cannot cipher DIP\n");
 		*verified = 0;
+		memset(dec_dip, 0, sizeof(DIP_t));
 		return -1;
 	}
 
@@ -573,11 +641,10 @@
 	SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
 	SHA256_Final(hash, &sha256_ctx);
 
-	hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
-
-	if (memcmp(hash, hash_p, HASH_LEN))
+	if (memcmp(hash, dec_dip->hash, HASH_LEN))
 	{
 		*verified = 0;
+		memset(dec_dip, 0, sizeof(DIP_t));
 	}
 	else
 	{
@@ -589,18 +656,15 @@
 
 static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
 {
-	unsigned char *hash_p;
 	SHA256_CTX sha256_ctx;
 	int ret;
 
 	ASSERT(dec_dip != NULL);
 	ASSERT(enc_dip != NULL);
 
-	hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
-
 	SHA256_Init(&sha256_ctx);
 	SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
-	SHA256_Final(hash_p, &sha256_ctx);
+	SHA256_Final(dec_dip->hash, &sha256_ctx);
 
 	ret = mdtp_cipher_dip_cmd((uint8_t*)dec_dip, sizeof(DIP_t),
 								(uint8_t*)enc_dip, sizeof(DIP_t),
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index 865c791..0f30b54 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -29,21 +29,21 @@
 #ifndef __APP_MDTP_H
 #define __APP_MDTP_H
 
-#define TOKEN_LEN 16
-#define MAX_BLOCKS 512
-#define MAX_PARTITIONS 3
-#define MAX_PARTITION_NAME_LEN 100
-#define HASH_LEN 32
-#define MDTP_MIN_PIN_LEN 5
-#define MDTP_MAX_PIN_LEN 8
-#define DIP_PADDING 11
+#define TOKEN_LEN              (16)
+#define MAX_BLOCKS             (512)
+#define MAX_PARTITIONS         (3)
+#define MAX_PARTITION_NAME_LEN (100)
+#define HASH_LEN               (32)
+#define MDTP_MAX_PIN_LEN       (8)
+#define MDTP_MIN_PIN_LEN       (5)
+#define DIP_PADDING            (15)
 
 #define INITIAL_DELAY_MSECONDS      5000
 #define INVALID_PIN_DELAY_MSECONDS  5000
 
 #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
-#define MDTP_FWLOCK_BLOCK_SIZE (1024*1024*16)
-#define MDTP_FWLOCK_MAX_FILES (100)
+#define MDTP_FWLOCK_BLOCK_SIZE          (1024*1024*16)
+#define MDTP_FWLOCK_MAX_FILES           (100)
 #define MDTP_FWLOCK_MAX_FILE_NAME_LEN   (100)
 
 #pragma pack(push, mdtp, 1)
@@ -66,7 +66,7 @@
 } DIP_hash_table_entry_t;
 
 typedef struct DIP_partition_cfg {
-	uint32_t size;                                  /* DIP size */
+	uint64_t size;                                  /* Partition size in bytes */
 	char name[MAX_PARTITION_NAME_LEN];              /* Partition name */
 	uint8_t lock_enabled;                           /* Image locked? */
 	mdtp_fwlock_mode_t hash_mode;                   /* Hash per IMAGE or BLOCK */
@@ -114,9 +114,9 @@
  *
  * Start Firmware Lock verification process.
  *
- * @return - negative value for an error, 0 for success.
+ * @return - None.
  */
-int mdtp_fwlock_verify_lock();
+void mdtp_fwlock_verify_lock();
 
 /**
  * mdtp_fuse_get_enabled
diff --git a/app/aboot/mdtp_fuse.c b/app/aboot/mdtp_fuse.c
index 1487057..239d263 100644
--- a/app/aboot/mdtp_fuse.c
+++ b/app/aboot/mdtp_fuse.c
@@ -36,8 +36,6 @@
 #include "mdtp.h"
 #include "scm.h"
 
-#define MAX_EFUSES              (8)
-#define EFUSE_END               (MDTP_EFUSE_START + MAX_EFUSES - 1)
 #define MAX_METADATA_SIZE       (0x1000)
 #define QFPROM_ADDR_SPACE_RAW   (0)
 
@@ -228,7 +226,7 @@
  * Read the Firmware Lock eFuses and return whether the Firmware
  * Lock is currently enabled or disabled in HW.
  *
- * @param[out] enabled: 0 - enable, 1 - disable.
+ * @param[out] enabled: 0 - disabled, 1 - enabled.
  *
  * @return - negative value for an error, 0 for success.
  */
@@ -237,6 +235,8 @@
 	int status;
 	mdtp_eFuses_t eFuses;
 
+	*enabled = 1;
+
 	status = read_fuse(&eFuses.mask);
 	if (status)
 	{
@@ -244,14 +244,12 @@
 		return -1;
 	}
 
-	if ((eFuses.bitwise.enable1 && !eFuses.bitwise.disable1) ||
-		(eFuses.bitwise.enable2 && !eFuses.bitwise.disable2) ||
-		(eFuses.bitwise.enable3 && !eFuses.bitwise.disable3))
+	if (!(eFuses.bitwise.enable1 && !eFuses.bitwise.disable1) &&
+		!(eFuses.bitwise.enable2 && !eFuses.bitwise.disable2) &&
+		!(eFuses.bitwise.enable3 && !eFuses.bitwise.disable3))
 	{
-		*enabled = 1;
-	}
-	else
 		*enabled = 0;
+	}
 
 	return 0;
 }
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 48d899e..7a94ad6 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -78,7 +78,7 @@
 #define BITS_PER_BYTE                       (8)
 
 
-#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width)         ((screen_width-image_width)/2)
+#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width)         (((screen_width)-(image_width))/2)
 
 extern void mdelay(unsigned msecs);
 extern uint32_t target_volume_up();
@@ -131,8 +131,9 @@
 	if (fb_config)
 	{
 		uint8_t *base = logo->image;
+		unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
 
-		if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*3, block_size))) {
+		if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
 				fbcon_clear();
 				dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
 				return NULL;
@@ -180,7 +181,7 @@
 	else
 	{
 	    dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
-	    display_error_msg();
+	    display_error_msg(); /* This will never return */
 	}
 }
 
@@ -218,11 +219,15 @@
 	if (bytes_per_bpp == 3)
 	{
 		if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
-			return;
-
-		if (fbimg->width > fb_config->width || fbimg->height > fb_config->height)
 		{
-		    dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen\n");
+			dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
+			return;
+		}
+
+		if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
+				 (x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
+		{
+		    dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
 		    return;
 		}
 
@@ -232,6 +237,11 @@
 				logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
 		}
 	}
+	else
+	{
+		dprintf(CRITICAL,"ERROR: invalid bpp value\n");
+		display_error_msg(); /* This will never return */
+	}
 
 	fbcon_flush();
 
@@ -240,17 +250,6 @@
         mipi_dsi_cmd_mode_trigger();
 #endif
 
-#else
-    if (bytes_per_bpp == 2)
-    {
-        for (i = 0; i < fbimg->width; i++)
-        {
-            memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
-		   fbimg->image + (i * fbimg->height * bytes_per_bpp),
-		   fbimg->height * bytes_per_bpp);
-        }
-    }
-    fbcon_flush();
 #endif
 }
 
@@ -261,8 +260,6 @@
 {
     struct mdtp_fbimage *fbimg;
 
-    fb_config = fbcon_display();
-
     if (fb_config)
 	{
         uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_ERROR_MSG_WIDTH,fb_config->width);
@@ -300,7 +297,7 @@
         if (NULL == fbimg)
         {
             dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
-            display_error_msg();
+            display_error_msg(); /* This will never return */
         }
 
         fbcon_putImage_in_location(fbimg, x, y);
@@ -308,7 +305,7 @@
     else
     {
         dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
-        display_error_msg();
+        display_error_msg(); /* This will never return */
     }
 }
 
@@ -442,7 +439,7 @@
 		fbcon_clear();
 
 		if (display_error_message())
-		    display_error_msg();
+		    display_error_msg(); /* This will never return */
 		display_initial_delay();
 
 		mdelay(INITIAL_DELAY_MSECONDS);
@@ -452,12 +449,12 @@
 		uint32_t total_pin_length = pin_length*MDTP_PIN_DIGIT_WIDTH + DIGIT_SPACE*(pin_length - 1);
 		uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
 
-		for (int i=0; i<(int)pin_length; i++)
+		for (uint32_t i=0; i<pin_length; i++)
 		{
 			g_pin_frames_x_location[i] = complete_pin_centered + i*(DIGIT_SPACE+MDTP_PIN_DIGIT_WIDTH);
 		}
 
-		for (int i=0; i<(int)pin_length; i++)
+		for (uint32_t i=0; i<pin_length; i++)
 		{
 			display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
 		}
@@ -469,8 +466,7 @@
 	else
 	{
 	    dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
-	    display_error_msg();
-		return;
+	    display_error_msg(); /* This will never return */
 	}
 }
 
@@ -588,15 +584,17 @@
  */
 void display_error_msg()
 {
-    fbcon_clear();
-	display_error_message();   // No point in checking the return value here
+	fb_config = fbcon_display();
+
+	if (fb_config)
+	{
+		fbcon_clear();
+		display_error_message();   // No point in checking the return value here
+	}
 
 	// Invalid state. Nothing to be done but contacting the OEM.
 	// Stop boot process.
 	dprintf(CRITICAL,"ERROR: blocking boot process\n");
-	while(1)
-	{
-
-	}
+	for(;;);
 }