summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLuo Ji <ji.luo@nxp.com>2018-11-21 15:55:55 +0800
committerLuo Ji <ji.luo@nxp.com>2018-11-22 11:02:09 +0800
commitf39aa82a3dbcab9ac0807b794e524c9226fdf69a (patch)
tree3d09f5c426dace1f5e6a00ecddf26652cbbba7f3 /lib
parente26db8caf2c7ed554a3496df3b90f9efcb76cf5f (diff)
MA-13487 Refine fsl avb functions
Too many macros are used in fsl_avbkey.c and make it difficult to maintain. This patch made some refine by: 1. Move all avb/atx operations to fsl_avb.c. 2. Refine the functions logic. 3. Drop some unsupported conditions/functions. Test: build and boot on imx8qm_mek/imx8mq_evk/imx6qp_sabresd/imx7d_pico/imx8m_aiy. Change-Id: I5c99732acfc47d53cdf188d69223983777e577f4 Signed-off-by: Luo Ji <ji.luo@nxp.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/avb/fsl/Makefile3
-rw-r--r--lib/avb/fsl/fsl_atx_attributes.c145
-rw-r--r--lib/avb/fsl/fsl_atx_attributes.h142
-rw-r--r--lib/avb/fsl/fsl_avb.c392
-rw-r--r--lib/avb/fsl/fsl_avbkey.c1588
-rw-r--r--lib/avb/fsl/fsl_avbkey.h16
6 files changed, 1057 insertions, 1229 deletions
diff --git a/lib/avb/fsl/Makefile b/lib/avb/fsl/Makefile
index 930f98e27f..9c2fb44fc0 100644
--- a/lib/avb/fsl/Makefile
+++ b/lib/avb/fsl/Makefile
@@ -1,5 +1,3 @@
-ccflags-y += -Werror
-
ifndef CONFIG_SPL_BUILD
obj-y += fsl_avb.o
obj-y += fsl_bootctl.o
@@ -9,3 +7,4 @@ endif
obj-y += fsl_avbkey.o
obj-y += utils.o
obj-y += fsl_avb_ab_flow.o
+obj-$(CONFIG_AVB_ATX) += fsl_atx_attributes.o
diff --git a/lib/avb/fsl/fsl_atx_attributes.c b/lib/avb/fsl/fsl_atx_attributes.c
new file mode 100644
index 0000000000..2297140dd1
--- /dev/null
+++ b/lib/avb/fsl/fsl_atx_attributes.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* This product_id is generated from
+ * extern/avb/test/data/atx_product_id.bin */
+unsigned char fsl_atx_product_id[16] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+};
+/* This product_root_public_key is generated form
+ * extern/avb/test/data/testkey_atx_prk.pem */
+unsigned char fsl_product_root_public_key[1032] = {
+ 0x00,0x00,0x10,0x00,0x9f,0x35,0xef,0x65,
+ 0xc3,0x29,0x4c,0x23,0x16,0x10,0xac,0x32,
+ 0xc1,0x3c,0xd5,0xc5,0xab,0xa1,0xd9,0xe7,
+ 0x13,0x3f,0x7e,0xd1,0xe6,0x61,0x5d,0xa3,
+ 0xa1,0x60,0xda,0x57,0x4b,0xb2,0xe6,0x0f,
+ 0xe1,0x50,0xbf,0x47,0xff,0x09,0xaf,0xcd,
+ 0x49,0x2d,0x82,0x33,0x76,0xa1,0xfe,0x28,
+ 0x5f,0x89,0x62,0xb3,0xc0,0xf1,0x11,0xaf,
+ 0x15,0x09,0x27,0xdb,0xeb,0x06,0x01,0xa2,
+ 0xf8,0xb7,0xd7,0x9c,0xe4,0x88,0x3a,0x86,
+ 0x05,0x02,0x20,0x69,0xb2,0x36,0x4c,0x3e,
+ 0x25,0x03,0xed,0xfc,0x0c,0x6b,0x1b,0x0a,
+ 0x04,0x9c,0xce,0x7f,0x83,0x82,0x60,0xd9,
+ 0x52,0x7e,0xc4,0x35,0x7b,0x1c,0xe6,0x64,
+ 0x9c,0x17,0xec,0x81,0xe7,0x9c,0x0c,0x8b,
+ 0x4b,0x7e,0x48,0xbe,0x00,0x98,0xa8,0x20,
+ 0x10,0x4c,0x9b,0xd1,0x16,0x5b,0x25,0xe9,
+ 0x4e,0x61,0xda,0x7c,0x63,0x80,0x8f,0xa4,
+ 0xac,0x74,0xee,0xa8,0x06,0xac,0x26,0xd5,
+ 0x71,0x6f,0xaa,0x73,0x20,0x9c,0x7f,0xcd,
+ 0x73,0xd4,0xa9,0xa0,0x7e,0x5a,0xb5,0x61,
+ 0xb0,0x88,0xb0,0xdd,0xdb,0x6b,0x79,0xd1,
+ 0x5a,0x9e,0x54,0x49,0x55,0xc6,0x89,0x76,
+ 0x7a,0xc6,0x78,0x99,0xdc,0xc9,0x00,0x5d,
+ 0x20,0xf5,0xfc,0x8f,0x39,0x46,0xf3,0x02,
+ 0x96,0x0d,0x9b,0xfb,0xbc,0xd5,0xcf,0x5a,
+ 0x4f,0xc4,0xb8,0x0b,0xd0,0xf3,0x19,0x3c,
+ 0x74,0x04,0xd5,0x94,0x2c,0x19,0x15,0x64,
+ 0xbf,0x53,0x67,0x97,0x7b,0x9e,0xc6,0xe0,
+ 0xfb,0x29,0x5b,0x90,0xad,0x04,0x8a,0xd8,
+ 0x5b,0xdf,0x69,0x09,0xe4,0xa5,0xe9,0xd9,
+ 0x0f,0xc4,0xff,0xae,0xb7,0x44,0x12,0xae,
+ 0xad,0x03,0x97,0xb8,0xda,0xd7,0x60,0x37,
+ 0x15,0xf2,0xb9,0xdb,0x10,0xf6,0xe2,0x26,
+ 0x48,0x7e,0x3e,0x3e,0xc3,0x67,0xd3,0xa6,
+ 0x02,0xf7,0xbc,0x60,0xed,0x45,0xdf,0x37,
+ 0xef,0xf9,0xea,0x97,0x5f,0x37,0xb4,0xeb,
+ 0xb4,0x91,0x6c,0x39,0x4d,0xed,0x52,0x15,
+ 0x39,0x47,0x59,0x62,0xde,0x32,0x55,0xe1,
+ 0xd4,0x15,0x58,0x7d,0x52,0x41,0x12,0x78,
+ 0xee,0x9f,0x0d,0xc8,0x5e,0x34,0x91,0xf9,
+ 0xe7,0x4c,0x1e,0xe7,0x2f,0x90,0x7f,0xbb,
+ 0xf8,0x99,0x3e,0xc9,0x79,0xab,0x01,0xdb,
+ 0x24,0x39,0xe3,0xb4,0xc9,0x52,0x73,0xdb,
+ 0x65,0x42,0xa5,0x2e,0x43,0x56,0xa0,0x33,
+ 0x8c,0x1a,0xb7,0xa1,0xed,0x5c,0xd0,0x14,
+ 0x93,0x8d,0x23,0x78,0x93,0xcb,0x3a,0x03,
+ 0x1f,0xbb,0xc6,0x7b,0xcd,0x51,0x4e,0xaa,
+ 0x14,0x01,0xe9,0x03,0x27,0x13,0xe2,0xb2,
+ 0xf8,0x36,0xc6,0xe3,0xc3,0x7f,0xb5,0x74,
+ 0x20,0x5e,0x17,0xaa,0x25,0x07,0x9b,0x60,
+ 0xda,0x83,0x98,0xb5,0x55,0xae,0x1b,0x7a,
+ 0xc1,0x1f,0x49,0x72,0xe2,0xcb,0x6a,0x11,
+ 0x77,0xdf,0x3f,0xc0,0x9f,0x8f,0x33,0xc7,
+ 0x10,0x17,0x8c,0xfc,0xd5,0xb7,0x5f,0x5e,
+ 0xb2,0xe3,0x7b,0x2e,0xdc,0xc7,0x34,0xdb,
+ 0x31,0xb0,0xdc,0x5d,0x14,0x98,0xb6,0x1a,
+ 0x2a,0xd4,0xb4,0x04,0x2c,0xf0,0x68,0x1c,
+ 0x91,0x60,0x28,0xa5,0x3b,0x01,0x98,0xb6,
+ 0x1e,0x6e,0xaa,0x35,0x89,0xc7,0x94,0xaa,
+ 0x9e,0xf0,0x11,0x52,0x0f,0x28,0xa1,0x3d,
+ 0xd3,0x17,0xb5,0x08,0xd8,0x7a,0x41,0xf9,
+ 0x07,0xe2,0x87,0x36,0xcd,0x86,0x3e,0x79,
+ 0x99,0x73,0x50,0x21,0x30,0x00,0xd2,0xf3,
+ 0x88,0x60,0x32,0x59,0x58,0x2f,0x55,0x93,
+ 0x86,0x56,0x9a,0x96,0xb9,0xf8,0xbf,0x24,
+ 0xc4,0xba,0xea,0xa4,0x73,0xb0,0x0c,0xa6,
+ 0xdb,0x09,0x2d,0x0a,0x36,0x3f,0x80,0xe6,
+ 0x85,0x7a,0xf3,0x01,0x90,0x3a,0xc6,0xee,
+ 0x2d,0xa8,0xce,0xb4,0x3f,0x3a,0xa6,0xa3,
+ 0xaf,0xb9,0x21,0xef,0x40,0x6f,0xf4,0x7f,
+ 0x78,0x25,0x55,0x39,0x53,0x67,0x53,0x56,
+ 0x8d,0x81,0xaf,0x63,0x97,0x68,0x86,0x75,
+ 0x66,0x14,0x1e,0xa6,0x63,0x1e,0x02,0xd0,
+ 0x41,0xd8,0x78,0x75,0x0d,0x76,0x77,0xfa,
+ 0x9c,0xc5,0xcc,0x54,0x06,0x25,0x53,0x95,
+ 0xeb,0x4b,0x7c,0xb4,0xc8,0xbb,0x5d,0x6b,
+ 0x6e,0xf0,0xd7,0x8d,0x3f,0xdf,0x93,0x4c,
+ 0x30,0x5b,0x02,0xf5,0x0e,0x49,0x87,0x60,
+ 0x5f,0x19,0x06,0x24,0x3d,0x5d,0x97,0x37,
+ 0x61,0xef,0x3e,0x0b,0x9e,0x85,0x1c,0x1a,
+ 0xa6,0x53,0x91,0xd2,0x2c,0x18,0x7c,0x8f,
+ 0x5b,0x4a,0xd5,0xdd,0xd9,0x8a,0xc3,0x92,
+ 0x19,0x54,0x39,0xde,0x33,0xa1,0xe1,0x37,
+ 0x60,0x3c,0x3b,0x3b,0xc5,0xed,0x1b,0xef,
+ 0x28,0xf5,0xdf,0x44,0x91,0xa3,0x1e,0x69,
+ 0x6a,0x35,0x85,0x6e,0x26,0x46,0x22,0x4d,
+ 0x87,0x92,0x44,0x6b,0x96,0xdb,0x75,0xfe,
+ 0x76,0x03,0x60,0xf7,0xfd,0x90,0x55,0x7d,
+ 0x6e,0xd7,0xaa,0x44,0x05,0xc7,0x23,0x37,
+ 0x12,0xa8,0xd4,0xb2,0x2b,0xed,0x41,0x5f,
+ 0x23,0x38,0x7c,0x16,0xe6,0x16,0xd3,0x10,
+ 0x19,0x12,0xcc,0x8b,0x6e,0xcd,0xd6,0xa6,
+ 0x39,0x8a,0x1b,0x24,0x3f,0x4d,0x6f,0xa6,
+ 0x00,0x7c,0xa0,0xa1,0x4a,0xfd,0xcd,0x68,
+ 0x50,0x76,0xc8,0x68,0x9d,0xeb,0xdf,0x24,
+ 0x39,0xaf,0x77,0xb2,0xb6,0xaf,0xb6,0x34,
+ 0x61,0x37,0x6a,0xfd,0xc7,0x6d,0x02,0x9f,
+ 0x29,0xd5,0x45,0xf4,0x89,0xd8,0x8c,0x5c,
+ 0xd3,0x31,0xa0,0x58,0x19,0x54,0x33,0x46,
+ 0x92,0xbc,0x1e,0x4b,0x14,0xac,0x73,0xa5,
+ 0x09,0x9f,0xb6,0x2b,0x2b,0x73,0x6b,0x83,
+ 0x86,0x13,0x6e,0x03,0xf7,0xe0,0x7d,0x81,
+ 0x47,0x18,0x08,0xea,0x09,0x10,0x24,0x61,
+ 0x6d,0x09,0x1d,0xb8,0x8e,0xba,0x04,0x4d,
+ 0xcc,0xe6,0xff,0x28,0x27,0x86,0x38,0x01,
+ 0x86,0xbe,0xf0,0x5b,0xf8,0x1a,0xd6,0xde,
+ 0xbe,0xf9,0x3b,0x76,0x3f,0x85,0x82,0x22,
+ 0x92,0x4b,0xe0,0x76,0x15,0xb2,0x57,0x5a,
+ 0xb0,0x64,0xde,0xce,0x93,0xb8,0x9f,0x25,
+ 0x53,0x8c,0x5e,0xdf,0x29,0x4e,0x50,0x69,
+ 0xfb,0x7e,0x33,0xcb,0x0e,0x28,0x01,0x6c,
+ 0xab,0xfa,0xd8,0x88,0x02,0xbc,0xf2,0xb1,
+ 0x0e,0x2f,0x6d,0x1c,0x8d,0xe4,0x11,0x23,
+ 0xcc,0x67,0x94,0x7b,0xf7,0x8a,0xf3,0x68,
+ 0x52,0xe4,0x82,0x25,0x86,0xc6,0x72,0x19,
+ 0x77,0x80,0x28,0xe3,0x86,0xc8,0x8a,0xea,
+ 0x3d,0x54,0x2f,0x0b,0x64,0x0a,0xc5,0x12,
+ 0x8c,0xb2,0x07,0x72,0x1b,0x09,0x9f,0x32,
+ 0xbd,0xa3,0xb0,0x0c,0x95,0xc8,0x4d,0xe5,
+ 0xd7,0x20,0xdb,0xf8,0x34,0x2a,0x9d,0x91,
+ 0x58,0x38,0x7a,0x9c,0xe0,0xa3,0x0f,0x40,
+ 0x9d,0xff,0xeb,0x4b,0xe2,0x16,0x94,0x32,
+ 0xce,0xe8,0x52,0x75,0x49,0xf4,0x71,0x13,
+ 0xbc,0x59,0x7d,0x9a,0xe8,0x60,0x29,0x58,
+ 0x1a,0x14,0x94,0xe6,0x37,0x23,0xad,0xfe,
+ 0x0b,0xf0,0x63,0x60,0x4f,0x5d,0x10,0x91,
+ 0xf2,0x50,0x8e,0x0b,0x4a,0x47,0xc9,0x0c,
+ 0x1f,0xdc,0x94,0x75,0x25,0x52,0x99,0xfc
+};
diff --git a/lib/avb/fsl/fsl_atx_attributes.h b/lib/avb/fsl/fsl_atx_attributes.h
index 14592e02d3..e6e43835a1 100644
--- a/lib/avb/fsl/fsl_atx_attributes.h
+++ b/lib/avb/fsl/fsl_atx_attributes.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 NXP
+ * Copyright 2018 NXP
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -10,143 +10,9 @@
#define fsl_version 1
/* This product_id is generated from
* extern/avb/test/data/atx_product_id.bin */
-unsigned char fsl_atx_product_id[] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-};
+extern unsigned char fsl_atx_product_id[17];
/* This product_root_public_key is generated form
* extern/avb/test/data/testkey_atx_prk.pem */
-unsigned char fsl_product_root_public_key[] = {
- 0x00,0x00,0x10,0x00,0x9f,0x35,0xef,0x65,
- 0xc3,0x29,0x4c,0x23,0x16,0x10,0xac,0x32,
- 0xc1,0x3c,0xd5,0xc5,0xab,0xa1,0xd9,0xe7,
- 0x13,0x3f,0x7e,0xd1,0xe6,0x61,0x5d,0xa3,
- 0xa1,0x60,0xda,0x57,0x4b,0xb2,0xe6,0x0f,
- 0xe1,0x50,0xbf,0x47,0xff,0x09,0xaf,0xcd,
- 0x49,0x2d,0x82,0x33,0x76,0xa1,0xfe,0x28,
- 0x5f,0x89,0x62,0xb3,0xc0,0xf1,0x11,0xaf,
- 0x15,0x09,0x27,0xdb,0xeb,0x06,0x01,0xa2,
- 0xf8,0xb7,0xd7,0x9c,0xe4,0x88,0x3a,0x86,
- 0x05,0x02,0x20,0x69,0xb2,0x36,0x4c,0x3e,
- 0x25,0x03,0xed,0xfc,0x0c,0x6b,0x1b,0x0a,
- 0x04,0x9c,0xce,0x7f,0x83,0x82,0x60,0xd9,
- 0x52,0x7e,0xc4,0x35,0x7b,0x1c,0xe6,0x64,
- 0x9c,0x17,0xec,0x81,0xe7,0x9c,0x0c,0x8b,
- 0x4b,0x7e,0x48,0xbe,0x00,0x98,0xa8,0x20,
- 0x10,0x4c,0x9b,0xd1,0x16,0x5b,0x25,0xe9,
- 0x4e,0x61,0xda,0x7c,0x63,0x80,0x8f,0xa4,
- 0xac,0x74,0xee,0xa8,0x06,0xac,0x26,0xd5,
- 0x71,0x6f,0xaa,0x73,0x20,0x9c,0x7f,0xcd,
- 0x73,0xd4,0xa9,0xa0,0x7e,0x5a,0xb5,0x61,
- 0xb0,0x88,0xb0,0xdd,0xdb,0x6b,0x79,0xd1,
- 0x5a,0x9e,0x54,0x49,0x55,0xc6,0x89,0x76,
- 0x7a,0xc6,0x78,0x99,0xdc,0xc9,0x00,0x5d,
- 0x20,0xf5,0xfc,0x8f,0x39,0x46,0xf3,0x02,
- 0x96,0x0d,0x9b,0xfb,0xbc,0xd5,0xcf,0x5a,
- 0x4f,0xc4,0xb8,0x0b,0xd0,0xf3,0x19,0x3c,
- 0x74,0x04,0xd5,0x94,0x2c,0x19,0x15,0x64,
- 0xbf,0x53,0x67,0x97,0x7b,0x9e,0xc6,0xe0,
- 0xfb,0x29,0x5b,0x90,0xad,0x04,0x8a,0xd8,
- 0x5b,0xdf,0x69,0x09,0xe4,0xa5,0xe9,0xd9,
- 0x0f,0xc4,0xff,0xae,0xb7,0x44,0x12,0xae,
- 0xad,0x03,0x97,0xb8,0xda,0xd7,0x60,0x37,
- 0x15,0xf2,0xb9,0xdb,0x10,0xf6,0xe2,0x26,
- 0x48,0x7e,0x3e,0x3e,0xc3,0x67,0xd3,0xa6,
- 0x02,0xf7,0xbc,0x60,0xed,0x45,0xdf,0x37,
- 0xef,0xf9,0xea,0x97,0x5f,0x37,0xb4,0xeb,
- 0xb4,0x91,0x6c,0x39,0x4d,0xed,0x52,0x15,
- 0x39,0x47,0x59,0x62,0xde,0x32,0x55,0xe1,
- 0xd4,0x15,0x58,0x7d,0x52,0x41,0x12,0x78,
- 0xee,0x9f,0x0d,0xc8,0x5e,0x34,0x91,0xf9,
- 0xe7,0x4c,0x1e,0xe7,0x2f,0x90,0x7f,0xbb,
- 0xf8,0x99,0x3e,0xc9,0x79,0xab,0x01,0xdb,
- 0x24,0x39,0xe3,0xb4,0xc9,0x52,0x73,0xdb,
- 0x65,0x42,0xa5,0x2e,0x43,0x56,0xa0,0x33,
- 0x8c,0x1a,0xb7,0xa1,0xed,0x5c,0xd0,0x14,
- 0x93,0x8d,0x23,0x78,0x93,0xcb,0x3a,0x03,
- 0x1f,0xbb,0xc6,0x7b,0xcd,0x51,0x4e,0xaa,
- 0x14,0x01,0xe9,0x03,0x27,0x13,0xe2,0xb2,
- 0xf8,0x36,0xc6,0xe3,0xc3,0x7f,0xb5,0x74,
- 0x20,0x5e,0x17,0xaa,0x25,0x07,0x9b,0x60,
- 0xda,0x83,0x98,0xb5,0x55,0xae,0x1b,0x7a,
- 0xc1,0x1f,0x49,0x72,0xe2,0xcb,0x6a,0x11,
- 0x77,0xdf,0x3f,0xc0,0x9f,0x8f,0x33,0xc7,
- 0x10,0x17,0x8c,0xfc,0xd5,0xb7,0x5f,0x5e,
- 0xb2,0xe3,0x7b,0x2e,0xdc,0xc7,0x34,0xdb,
- 0x31,0xb0,0xdc,0x5d,0x14,0x98,0xb6,0x1a,
- 0x2a,0xd4,0xb4,0x04,0x2c,0xf0,0x68,0x1c,
- 0x91,0x60,0x28,0xa5,0x3b,0x01,0x98,0xb6,
- 0x1e,0x6e,0xaa,0x35,0x89,0xc7,0x94,0xaa,
- 0x9e,0xf0,0x11,0x52,0x0f,0x28,0xa1,0x3d,
- 0xd3,0x17,0xb5,0x08,0xd8,0x7a,0x41,0xf9,
- 0x07,0xe2,0x87,0x36,0xcd,0x86,0x3e,0x79,
- 0x99,0x73,0x50,0x21,0x30,0x00,0xd2,0xf3,
- 0x88,0x60,0x32,0x59,0x58,0x2f,0x55,0x93,
- 0x86,0x56,0x9a,0x96,0xb9,0xf8,0xbf,0x24,
- 0xc4,0xba,0xea,0xa4,0x73,0xb0,0x0c,0xa6,
- 0xdb,0x09,0x2d,0x0a,0x36,0x3f,0x80,0xe6,
- 0x85,0x7a,0xf3,0x01,0x90,0x3a,0xc6,0xee,
- 0x2d,0xa8,0xce,0xb4,0x3f,0x3a,0xa6,0xa3,
- 0xaf,0xb9,0x21,0xef,0x40,0x6f,0xf4,0x7f,
- 0x78,0x25,0x55,0x39,0x53,0x67,0x53,0x56,
- 0x8d,0x81,0xaf,0x63,0x97,0x68,0x86,0x75,
- 0x66,0x14,0x1e,0xa6,0x63,0x1e,0x02,0xd0,
- 0x41,0xd8,0x78,0x75,0x0d,0x76,0x77,0xfa,
- 0x9c,0xc5,0xcc,0x54,0x06,0x25,0x53,0x95,
- 0xeb,0x4b,0x7c,0xb4,0xc8,0xbb,0x5d,0x6b,
- 0x6e,0xf0,0xd7,0x8d,0x3f,0xdf,0x93,0x4c,
- 0x30,0x5b,0x02,0xf5,0x0e,0x49,0x87,0x60,
- 0x5f,0x19,0x06,0x24,0x3d,0x5d,0x97,0x37,
- 0x61,0xef,0x3e,0x0b,0x9e,0x85,0x1c,0x1a,
- 0xa6,0x53,0x91,0xd2,0x2c,0x18,0x7c,0x8f,
- 0x5b,0x4a,0xd5,0xdd,0xd9,0x8a,0xc3,0x92,
- 0x19,0x54,0x39,0xde,0x33,0xa1,0xe1,0x37,
- 0x60,0x3c,0x3b,0x3b,0xc5,0xed,0x1b,0xef,
- 0x28,0xf5,0xdf,0x44,0x91,0xa3,0x1e,0x69,
- 0x6a,0x35,0x85,0x6e,0x26,0x46,0x22,0x4d,
- 0x87,0x92,0x44,0x6b,0x96,0xdb,0x75,0xfe,
- 0x76,0x03,0x60,0xf7,0xfd,0x90,0x55,0x7d,
- 0x6e,0xd7,0xaa,0x44,0x05,0xc7,0x23,0x37,
- 0x12,0xa8,0xd4,0xb2,0x2b,0xed,0x41,0x5f,
- 0x23,0x38,0x7c,0x16,0xe6,0x16,0xd3,0x10,
- 0x19,0x12,0xcc,0x8b,0x6e,0xcd,0xd6,0xa6,
- 0x39,0x8a,0x1b,0x24,0x3f,0x4d,0x6f,0xa6,
- 0x00,0x7c,0xa0,0xa1,0x4a,0xfd,0xcd,0x68,
- 0x50,0x76,0xc8,0x68,0x9d,0xeb,0xdf,0x24,
- 0x39,0xaf,0x77,0xb2,0xb6,0xaf,0xb6,0x34,
- 0x61,0x37,0x6a,0xfd,0xc7,0x6d,0x02,0x9f,
- 0x29,0xd5,0x45,0xf4,0x89,0xd8,0x8c,0x5c,
- 0xd3,0x31,0xa0,0x58,0x19,0x54,0x33,0x46,
- 0x92,0xbc,0x1e,0x4b,0x14,0xac,0x73,0xa5,
- 0x09,0x9f,0xb6,0x2b,0x2b,0x73,0x6b,0x83,
- 0x86,0x13,0x6e,0x03,0xf7,0xe0,0x7d,0x81,
- 0x47,0x18,0x08,0xea,0x09,0x10,0x24,0x61,
- 0x6d,0x09,0x1d,0xb8,0x8e,0xba,0x04,0x4d,
- 0xcc,0xe6,0xff,0x28,0x27,0x86,0x38,0x01,
- 0x86,0xbe,0xf0,0x5b,0xf8,0x1a,0xd6,0xde,
- 0xbe,0xf9,0x3b,0x76,0x3f,0x85,0x82,0x22,
- 0x92,0x4b,0xe0,0x76,0x15,0xb2,0x57,0x5a,
- 0xb0,0x64,0xde,0xce,0x93,0xb8,0x9f,0x25,
- 0x53,0x8c,0x5e,0xdf,0x29,0x4e,0x50,0x69,
- 0xfb,0x7e,0x33,0xcb,0x0e,0x28,0x01,0x6c,
- 0xab,0xfa,0xd8,0x88,0x02,0xbc,0xf2,0xb1,
- 0x0e,0x2f,0x6d,0x1c,0x8d,0xe4,0x11,0x23,
- 0xcc,0x67,0x94,0x7b,0xf7,0x8a,0xf3,0x68,
- 0x52,0xe4,0x82,0x25,0x86,0xc6,0x72,0x19,
- 0x77,0x80,0x28,0xe3,0x86,0xc8,0x8a,0xea,
- 0x3d,0x54,0x2f,0x0b,0x64,0x0a,0xc5,0x12,
- 0x8c,0xb2,0x07,0x72,0x1b,0x09,0x9f,0x32,
- 0xbd,0xa3,0xb0,0x0c,0x95,0xc8,0x4d,0xe5,
- 0xd7,0x20,0xdb,0xf8,0x34,0x2a,0x9d,0x91,
- 0x58,0x38,0x7a,0x9c,0xe0,0xa3,0x0f,0x40,
- 0x9d,0xff,0xeb,0x4b,0xe2,0x16,0x94,0x32,
- 0xce,0xe8,0x52,0x75,0x49,0xf4,0x71,0x13,
- 0xbc,0x59,0x7d,0x9a,0xe8,0x60,0x29,0x58,
- 0x1a,0x14,0x94,0xe6,0x37,0x23,0xad,0xfe,
- 0x0b,0xf0,0x63,0x60,0x4f,0x5d,0x10,0x91,
- 0xf2,0x50,0x8e,0x0b,0x4a,0x47,0xc9,0x0c,
- 0x1f,0xdc,0x94,0x75,0x25,0x52,0x99,0xfc
-};
+extern unsigned char fsl_product_root_public_key[1032];
-#endif
-/* __FSL_ATX_ATTRIBUTES_H__ */
+#endif /* __FSL_ATX_ATTRIBUTES_H__ */
diff --git a/lib/avb/fsl/fsl_avb.c b/lib/avb/fsl/fsl_avb.c
index 64f0a372c5..a1c56b196f 100644
--- a/lib/avb/fsl/fsl_avb.c
+++ b/lib/avb/fsl/fsl_avb.c
@@ -15,6 +15,9 @@
#include "fsl_avbkey.h"
#include "utils.h"
#include "debug.h"
+#include "trusty/avb.h"
+#include "fsl_public_key.h"
+#include "fsl_atx_attributes.h"
#define FSL_AVB_DEV "mmc"
@@ -435,3 +438,392 @@ AvbIOResult fsl_get_size_of_partition(AvbOps* ops,
*out_size_num_bytes = (uint64_t)(pte->length * 512);
return AVB_IO_RESULT_OK;
}
+
+#ifdef CONFIG_AVB_ATX
+/* Reads permanent |attributes| data. There are no restrictions on where this
+ * data is stored. On success, returns AVB_IO_RESULT_OK and populates
+ * |attributes|.
+ */
+AvbIOResult fsl_read_permanent_attributes(
+ AvbAtxOps* atx_ops, AvbAtxPermanentAttributes* attributes) {
+#ifdef CONFIG_IMX_TRUSTY_OS
+ if (!trusty_read_permanent_attributes((uint8_t *)attributes,
+ sizeof(AvbAtxPermanentAttributes))) {
+ return AVB_IO_RESULT_OK;
+ }
+ ERR("No perm-attr fused. Will use hard code one.\n");
+#endif /* CONFIG_IMX_TRUSTY_OS */
+
+ /* use hard code permanent attributes due to limited fuse and RPMB */
+ attributes->version = fsl_version;
+ memcpy(attributes->product_root_public_key, fsl_product_root_public_key,
+ sizeof(fsl_product_root_public_key));
+ memcpy(attributes->product_id, fsl_atx_product_id,
+ sizeof(fsl_atx_product_id));
+
+ return AVB_IO_RESULT_OK;
+}
+
+/* Reads a |hash| of permanent attributes. This hash MUST be retrieved from a
+ * permanently read-only location (e.g. fuses) when a device is LOCKED. On
+ * success, returned AVB_IO_RESULT_OK and populates |hash|.
+ */
+AvbIOResult fsl_read_permanent_attributes_hash(
+ AvbAtxOps* atx_ops, uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
+#ifdef CONFIG_ARM64
+ /* calculate sha256(permanent attributes) */
+ if (permanent_attributes_sha256_hash(hash) != RESULT_OK) {
+ return AVB_IO_RESULT_ERROR_IO;
+ } else {
+ return AVB_IO_RESULT_OK;
+ }
+#else
+ uint8_t sha256_hash_buf[AVB_SHA256_DIGEST_SIZE];
+ uint32_t sha256_hash_fuse[ATX_FUSE_BANK_NUM];
+
+ /* read first 112 bits of sha256(permanent attributes) from fuse */
+ if (fsl_fuse_read(sha256_hash_fuse, ATX_FUSE_BANK_NUM,
+ PERMANENT_ATTRIBUTE_HASH_OFFSET)) {
+ printf("ERROR - read permanent attributes hash from "
+ "fuse error\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ /* only take the lower 2 bytes of last bank */
+ sha256_hash_fuse[ATX_FUSE_BANK_NUM - 1] &= ATX_FUSE_BANK_MASK;
+
+ /* calculate sha256(permanent attributes) */
+ if (permanent_attributes_sha256_hash(sha256_hash_buf) != RESULT_OK) {
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ /* check if the sha256(permanent attributes) hash match the calculated one,
+ * if not match, just return all zeros hash.
+ */
+ if (memcmp(sha256_hash_fuse, sha256_hash_buf, ATX_HASH_LENGTH)) {
+ printf("ERROR - sha256(permanent attributes) does not match\n");
+ memset(hash, 0, AVB_SHA256_DIGEST_SIZE);
+ } else {
+ memcpy(hash, sha256_hash_buf, AVB_SHA256_DIGEST_SIZE);
+ }
+
+ return AVB_IO_RESULT_OK;
+#endif /* CONFIG_ARM64 */
+}
+
+ /* Generates |num_bytes| random bytes and stores them in |output|,
+ * which must point to a buffer large enough to store the bytes.
+ *
+ * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
+ */
+AvbIOResult fsl_get_random(AvbAtxOps* atx_ops,
+ size_t num_bytes,
+ uint8_t* output)
+{
+ uint32_t num = 0;
+ uint32_t i;
+
+ if (output == NULL) {
+ ERR("Output buffer is NULL!\n");
+ return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
+ }
+
+ /* set the seed as device boot time. */
+ srand((uint32_t)get_timer(0));
+ for (i = 0; i < num_bytes; i++) {
+ num = rand() % 256;
+ output[i] = (uint8_t)num;
+ }
+
+ return AVB_IO_RESULT_OK;
+}
+/* Provides the key version of a key used during verification. This may be
+ * useful for managing the minimum key version.
+ */
+void fsl_set_key_version(AvbAtxOps* atx_ops,
+ size_t rollback_index_location,
+ uint64_t key_version) {
+ kblb_hdr_t hdr;
+ kblb_tag_t *rbk;
+ uint64_t *plain_idx = NULL;
+ struct mmc *mmc_dev;
+ static const uint32_t kTypeMask = 0xF000;
+
+ DEBUGAVB("[rpmb] write to rollback slot: (%zu, %" PRIu64 ")\n",
+ rollback_index_location, key_version);
+
+ assert(atx_ops != NULL);
+
+ if ((mmc_dev = get_mmc()) == NULL) {
+ ERR("err get mmc device\n");
+ }
+ /* read the kblb header */
+ if (rpmb_read(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
+ ERR("read RPMB error\n");
+ }
+
+ if (memcmp(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN) != 0) {
+ ERR("magic not match\n");
+ }
+
+ /* rollback index for Android Things key versions */
+ rbk = &hdr.atx_rbk_tags[rollback_index_location & ~kTypeMask];
+
+ plain_idx = malloc(rbk->len);
+ if (plain_idx == NULL)
+ printf("\nError! allocate memory fail!\n");
+ memset(plain_idx, 0, rbk->len);
+ *plain_idx = key_version;
+
+ /* write rollback_index keyblob */
+ if (rpmb_write(mmc_dev, (uint8_t *)plain_idx, rbk->len, rbk->offset) !=
+ 0) {
+ ERR("write rollback index error\n");
+ goto fail;
+ }
+fail:
+ if (plain_idx != NULL)
+ free(plain_idx);
+}
+#endif /* CONFIG_AVB_ATX */
+
+#ifdef AVB_RPMB
+/* Checks if the given public key used to sign the 'vbmeta'
+ * partition is trusted. Boot loaders typically compare this with
+ * embedded key material generated with 'avbtool
+ * extract_public_key'.
+ *
+ * If AVB_IO_RESULT_OK is returned then |out_is_trusted| is set -
+ * true if trusted or false if untrusted.
+ */
+AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops,
+ const uint8_t* public_key_data,
+ size_t public_key_length,
+ const uint8_t* public_key_metadata,
+ size_t public_key_metadata_length,
+ bool* out_is_trusted) {
+ AvbIOResult ret;
+ assert(ops != NULL && out_is_trusted != NULL);
+ *out_is_trusted = false;
+
+ /* match given public key */
+ if (memcmp(fsl_public_key, public_key_data, public_key_length)) {
+ ret = AVB_IO_RESULT_ERROR_IO;
+ ERR("public key not match\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ *out_is_trusted = true;
+ ret = AVB_IO_RESULT_OK;
+
+ return ret;
+}
+
+/* Sets the rollback index corresponding to the slot given by
+ * |rollback_index_slot| to |rollback_index|. Returns
+ * AVB_IO_RESULT_OK if the rollback index was set, otherwise an
+ * error code.
+ *
+ * A device may have a limited amount of rollback index slots (say,
+ * one or four) so may error out if |rollback_index_slot| exceeds
+ * this number.
+ */
+AvbIOResult fsl_write_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
+ uint64_t rollback_index) {
+ AvbIOResult ret;
+#ifdef CONFIG_IMX_TRUSTY_OS
+ if (trusty_write_rollback_index(rollback_index_slot, rollback_index)) {
+ ERR("write rollback from Trusty error!");
+ ret = AVB_IO_RESULT_ERROR_IO;
+ } else {
+ ret = AVB_IO_RESULT_OK;
+ }
+ return ret;
+#else
+ kblb_hdr_t hdr;
+ kblb_tag_t *rbk;
+ uint64_t *plain_idx = NULL;
+ struct mmc *mmc_dev;
+#ifdef CONFIG_AVB_ATX
+ static const uint32_t kTypeMask = 0xF000;
+ static const unsigned int kTypeShift = 12;
+#endif
+
+ DEBUGAVB("[rpmb] write to rollback slot: (%zu, %" PRIu64 ")\n",
+ rollback_index_slot, rollback_index);
+
+ assert(ops != NULL);
+ /* check if the rollback index location exceed the limit */
+#ifdef CONFIG_AVB_ATX
+ if ((rollback_index_slot & ~kTypeMask) >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
+#else
+ if (rollback_index_slot >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
+#endif /* CONFIG_AVB_ATX */
+ return AVB_IO_RESULT_ERROR_IO;
+
+ if ((mmc_dev = get_mmc()) == NULL) {
+ ERR("err get mmc device\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ /* read the kblb header */
+ if (rpmb_read(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
+ ERR("read RPMB error\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ if (memcmp(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN) != 0) {
+ ERR("magic not match\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ /* choose rollback index type */
+#ifdef CONFIG_AVB_ATX
+ if ((rollback_index_slot & kTypeMask) >> kTypeShift) {
+ /* rollback index for Android Things key versions */
+ rbk = &hdr.atx_rbk_tags[rollback_index_slot & ~kTypeMask];
+ } else {
+ /* rollback index for vbmeta */
+ rbk = &hdr.rbk_tags[rollback_index_slot & ~kTypeMask];
+ }
+#else
+ rbk = &hdr.rbk_tags[rollback_index_slot];
+#endif /* CONFIG_AVB_ATX */
+ plain_idx = malloc(rbk->len);
+ if (plain_idx == NULL)
+ return AVB_IO_RESULT_ERROR_OOM;
+ memset(plain_idx, 0, rbk->len);
+ *plain_idx = rollback_index;
+
+ /* write rollback_index keyblob */
+ if (rpmb_write(mmc_dev, (uint8_t *)plain_idx, rbk->len, rbk->offset) !=
+ 0) {
+ ERR("write rollback index error\n");
+ ret = AVB_IO_RESULT_ERROR_IO;
+ goto fail;
+ }
+ ret = AVB_IO_RESULT_OK;
+fail:
+ if (plain_idx != NULL)
+ free(plain_idx);
+ return ret;
+#endif /* CONFIG_IMX_TRUSTY_OS */
+}
+
+/* Gets the rollback index corresponding to the slot given by
+ * |rollback_index_slot|. The value is returned in
+ * |out_rollback_index|. Returns AVB_IO_RESULT_OK if the rollback
+ * index was retrieved, otherwise an error code.
+ *
+ * A device may have a limited amount of rollback index slots (say,
+ * one or four) so may error out if |rollback_index_slot| exceeds
+ * this number.
+ */
+AvbIOResult fsl_read_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
+ uint64_t* out_rollback_index) {
+ AvbIOResult ret;
+#ifdef CONFIG_IMX_TRUSTY_OS
+ if (trusty_read_rollback_index(rollback_index_slot, out_rollback_index)) {
+ ERR("read rollback from Trusty error!");
+ ret = AVB_IO_RESULT_ERROR_IO;
+ } else {
+ ret = AVB_IO_RESULT_OK;
+ }
+ return ret;
+#else
+ kblb_hdr_t hdr;
+ kblb_tag_t *rbk;
+ uint64_t *extract_idx = NULL;
+ struct mmc *mmc_dev;
+#ifdef CONFIG_AVB_ATX
+ static const uint32_t kTypeMask = 0xF000;
+ static const unsigned int kTypeShift = 12;
+#endif
+
+ assert(ops != NULL && out_rollback_index != NULL);
+ *out_rollback_index = ~0;
+
+ DEBUGAVB("[rpmb] read rollback slot: %zu\n", rollback_index_slot);
+
+ /* check if the rollback index location exceed the limit */
+#ifdef CONFIG_AVB_ATX
+ if ((rollback_index_slot & ~kTypeMask) >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
+#else
+ if (rollback_index_slot >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
+#endif
+ return AVB_IO_RESULT_ERROR_IO;
+
+ if ((mmc_dev = get_mmc()) == NULL) {
+ ERR("err get mmc device\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ /* read the kblb header */
+ if (rpmb_read(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
+ ERR("read RPMB error\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+
+ if (memcmp(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN) != 0) {
+ ERR("magic not match\n");
+ return AVB_IO_RESULT_ERROR_IO;
+ }
+ /* choose rollback index type */
+#ifdef CONFIG_AVB_ATX
+ if ((rollback_index_slot & kTypeMask) >> kTypeShift) {
+ /* rollback index for Android Things key versions */
+ rbk = &hdr.atx_rbk_tags[rollback_index_slot & ~kTypeMask];
+ } else {
+ /* rollback index for vbmeta */
+ rbk = &hdr.rbk_tags[rollback_index_slot & ~kTypeMask];
+ }
+#else
+ rbk = &hdr.rbk_tags[rollback_index_slot];
+#endif /* CONFIG_AVB_ATX */
+ extract_idx = malloc(rbk->len);
+ if (extract_idx == NULL)
+ return AVB_IO_RESULT_ERROR_OOM;
+
+ /* read rollback_index keyblob */
+ if (rpmb_read(mmc_dev, (uint8_t *)extract_idx, rbk->len, rbk->offset) != 0) {
+ ERR("read rollback index error\n");
+ ret = AVB_IO_RESULT_ERROR_IO;
+ goto fail;
+ }
+
+#ifdef AVB_VVDEBUG
+ printf("\n----idx dump: ---\n");
+ print_buffer(0, extract_idx, HEXDUMP_WIDTH, rbk->len, 0);
+ printf("--- end ---\n");
+#endif
+ *out_rollback_index = *extract_idx;
+ DEBUGAVB("rollback_index = %" PRIu64 "\n", *out_rollback_index);
+ ret = AVB_IO_RESULT_OK;
+fail:
+ if (extract_idx != NULL)
+ free(extract_idx);
+ return ret;
+#endif /* CONFIG_IMX_TRUSTY_OS */
+}
+#else /* AVB_RPMB */
+/*
+ * In no security enhanced ARM64, we cannot protect public key.
+ * So that we choose to trust the key from vbmeta image
+ */
+AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops,
+ const uint8_t* public_key_data,
+ size_t public_key_length,
+ const uint8_t* public_key_metadata,
+ size_t public_key_metadata_length,
+ bool* out_is_trusted) {
+ *out_is_trusted = true;
+ return AVB_IO_RESULT_OK;
+}
+
+/* In no security enhanced ARM64, rollback index has no protection so no use it */
+AvbIOResult fsl_write_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
+ uint64_t rollback_index) {
+ return AVB_IO_RESULT_OK;
+
+}
+AvbIOResult fsl_read_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
+ uint64_t* out_rollback_index) {
+ *out_rollback_index = 0;
+ return AVB_IO_RESULT_OK;
+}
+#endif /* AVB_RPMB */
diff --git a/lib/avb/fsl/fsl_avbkey.c b/lib/avb/fsl/fsl_avbkey.c
index fc9aa04b8a..56adf44c5a 100644
--- a/lib/avb/fsl/fsl_avbkey.c
+++ b/lib/avb/fsl/fsl_avbkey.c
@@ -19,425 +19,36 @@
#include <trusty/libtipc.h>
#endif
#include "fsl_avbkey.h"
-#include "fsl_public_key.h"
-#include "fsl_atx_attributes.h"
#include "utils.h"
#include "debug.h"
#include <memalign.h>
#include "trusty/hwcrypto.h"
+#include "fsl_atx_attributes.h"
#define INITFLAG_FUSE_OFFSET 0
#define INITFLAG_FUSE_MASK 0x00000001
#define INITFLAG_FUSE 0x00000001
#define RPMB_BLKSZ 256
-#define RPMBKEY_FUSE_OFFSET 1
#define RPMBKEY_LENGTH 32
-#define RPMBKEY_FUSE_LEN ((RPMBKEY_LENGTH) + (CAAM_PAD))
-#define RPMBKEY_FUSE_LENW (RPMBKEY_FUSE_LEN / 4)
#define RPMBKEY_BLOB_LEN ((RPMBKEY_LENGTH) + (CAAM_PAD))
-#ifdef CONFIG_AVB_ATX
-#define ATX_FUSE_BANK_NUM 4
-#define ATX_FUSE_BANK_MASK 0xFFFF
-#define ATX_HASH_LENGTH 14
-#endif
-
-#define RESULT_ERROR -1
-#define RESULT_OK 0
-
-#ifndef CONFIG_SPL_BUILD
-#if defined(CONFIG_AVB_ATX)
-static int fsl_fuse_ops(uint32_t *buffer, uint32_t length, uint32_t offset,
- const uint8_t read) {
-
- unsigned short bs, ws, bksz, cnt;
- unsigned short num_done = 0;
- margin_pos_t margin;
- int i;
-
- /* read from fuse */
- bksz = CONFIG_AVB_FUSE_BANK_SIZEW;
- if(get_margin_pos(CONFIG_AVB_FUSE_BANK_START, CONFIG_AVB_FUSE_BANK_END, bksz,
- &margin, offset, length, false))
- return -1;
- bs = (unsigned short)margin.blk_start;
- ws = (unsigned short)margin.start;
-
- while (num_done < length) {
- cnt = bksz - ws;
- if (num_done + cnt > length)
- cnt = length - num_done;
- for (i = 0; i < cnt; i++) {
- VDEBUG("cur: bank=%d, word=%d\n",bs, ws);
- if (read) {
- if (fuse_sense(bs, ws, buffer)) {
- ERR("read fuse bank %d, word %d error\n", bs, ws);
- return -1;
- }
- } else {
-#ifdef CONFIG_AVB_FUSE
- if (fuse_prog(bs, ws, *buffer)) {
-#else
- if (fuse_override(bs, ws, *buffer)) {
-#endif
- ERR("write fuse bank %d, word %d error\n", bs, ws);
- return -1;
- }
- }
- ws++;
- buffer++;
- }
- bs++;
- num_done += cnt;
- ws = 0;
- }
- return 0;
-}
-
-static int fsl_fuse_read(uint32_t *buffer, uint32_t length, uint32_t offset) {
-
- return fsl_fuse_ops(
- buffer,
- length,
- offset,
- 1
- );
-}
-
-static int fsl_fuse_write(const uint32_t *buffer, uint32_t length, uint32_t offset) {
-
- return fsl_fuse_ops(
- (uint32_t *)buffer,
- length,
- offset,
- 0
- );
-}
-#endif /* defined(CONFIG_AVB_ATX) && !defined(CONFIG_ARM64) */
-
-#if defined(CONFIG_AVB_ATX)
-static int sha256(unsigned char* data, int len, unsigned char* output) {
- struct hash_algo *algo;
- void *buf;
-
- if (hash_lookup_algo("sha256", &algo)) {
- printf("error in lookup sha256 algo!\n");
- return RESULT_ERROR;
- }
- buf = map_sysmem((ulong)data, len);
- algo->hash_func_ws(buf, len, output, algo->chunk_size);
- unmap_sysmem(buf);
-
- return algo->digest_size;
-}
-
-static int permanent_attributes_sha256_hash(unsigned char* output) {
- AvbAtxPermanentAttributes attributes;
-
-#ifdef CONFIG_IMX_TRUSTY_OS
- if(!trusty_read_permanent_attributes((uint8_t *)(&attributes),
- sizeof(AvbAtxPermanentAttributes))) {
- goto calc_sha256;
- } else {
- ERR("No perm-attr fused. Will use hard code one.\n");
- }
-#endif
- /* get permanent attributes */
- attributes.version = fsl_version;
- memcpy(attributes.product_root_public_key, fsl_product_root_public_key,
- sizeof(fsl_product_root_public_key));
- memcpy(attributes.product_id, fsl_atx_product_id,
- sizeof(fsl_atx_product_id));
-#ifdef CONFIG_IMX_TRUSTY_OS
-calc_sha256:
-#endif
- /* calculate sha256(permanent attributes) hash */
- if (sha256((unsigned char *)&attributes, sizeof(AvbAtxPermanentAttributes),
- output) == RESULT_ERROR) {
- printf("ERROR - calculate permanent attributes hash error");
- return RESULT_ERROR;
- }
-
- return RESULT_OK;
-}
-
-static int init_permanent_attributes_fuse(void) {
-
-#ifdef CONFIG_ARM64
- return RESULT_OK;
-#else
- uint8_t sha256_hash[AVB_SHA256_DIGEST_SIZE];
- uint32_t buffer[ATX_FUSE_BANK_NUM];
- int num = 0;
-
- /* read first 112 bits of sha256(permanent attributes) from fuse */
- if (fsl_fuse_read(buffer, ATX_FUSE_BANK_NUM, PERMANENT_ATTRIBUTE_HASH_OFFSET)) {
- printf("ERROR - read permanent attributes hash from fuse error\n");
- return RESULT_ERROR;
- }
- /* only take the lower 2 bytes of the last bank */
- buffer[ATX_FUSE_BANK_NUM - 1] &= ATX_FUSE_BANK_MASK;
-
- /* return RESULT_OK if fuse has been initialized before */
- for (num = 0; num < ATX_FUSE_BANK_NUM; num++) {
- if (buffer[num])
- return RESULT_OK;
- }
-
- /* calculate sha256(permanent attributes) */
- if (permanent_attributes_sha256_hash(sha256_hash) != RESULT_OK) {
- printf("ERROR - calculating permanent attributes SHA256 error!\n");
- return RESULT_ERROR;
- }
-
- /* write first 112 bits of sha256(permanent attributes) into fuse */
- memset(buffer, 0, sizeof(buffer));
- memcpy(buffer, sha256_hash, ATX_HASH_LENGTH);
- if (fsl_fuse_write(buffer, ATX_FUSE_BANK_NUM, PERMANENT_ATTRIBUTE_HASH_OFFSET)) {
- printf("ERROR - write permanent attributes hash to fuse error\n");
- return RESULT_ERROR;
- }
-
- return RESULT_OK;
-#endif /* CONFIG_ARM64 */
-}
-#endif
-
-#ifdef CONFIG_AVB_ATX
-int avb_atx_fuse_perm_attr(uint8_t *staged_buffer, uint32_t size) {
-
- if (staged_buffer == NULL) {
- ERR("Error. Get null staged_buffer\n");
- return -1;
- }
- if (size != sizeof(AvbAtxPermanentAttributes)) {
- ERR("Error. expect perm_attr length %u, but get %u.\n",
- (uint32_t)sizeof(AvbAtxPermanentAttributes), size);
- return -1;
- }
-#ifdef CONFIG_IMX_TRUSTY_OS
- if (trusty_write_permanent_attributes(staged_buffer, size)) {
- ERR("Error. Failed to write permanent attributes into secure storage\n");
- return -1;
- }
- else
- return init_permanent_attributes_fuse();
-#else
- /*
- * TODO:
- * Need to handle this when no Trusty OS support.
- * But now every Android Things will have Trusty OS support.
- */
- ERR("No Trusty OS enabled in bootloader.\n");
- return 0;
-#endif
-}
-
-int avb_atx_get_unlock_challenge(struct AvbAtxOps* atx_ops,
- uint8_t *upload_buffer, uint32_t *upload_size)
-{
- struct AvbAtxUnlockChallenge *buf = NULL;
- int ret, size;
-
- size = sizeof(struct AvbAtxUnlockChallenge);
- buf = (struct AvbAtxUnlockChallenge *)malloc(size);
- if (buf == NULL) {
- ERR("unable to alloc memory!\n");
- return -1;
- }
-
- if (avb_atx_generate_unlock_challenge(atx_ops, buf) !=
- AVB_IO_RESULT_OK) {
- ERR("generate unlock challenge fail!\n");
- ret = -1;
- goto fail;
- }
- /* Current avbtool only accept 16 bytes random numbers as unlock
- * challenge, need to return the whole 'AvbAtxUnlockChallenge'
- * when avbtool is ready.
- */
- memcpy(upload_buffer, buf->challenge, AVB_ATX_UNLOCK_CHALLENGE_SIZE);
- *upload_size = AVB_ATX_UNLOCK_CHALLENGE_SIZE;
- ret = 0;
-fail:
- if (buf != NULL)
- free(buf);
- return ret;
-}
-
-int avb_atx_verify_unlock_credential(struct AvbAtxOps* atx_ops,
- uint8_t *staged_buffer)
-{
- bool out_is_trusted;
- AvbIOResult ret;
- const AvbAtxUnlockCredential* buf = NULL;
-
- buf = (const AvbAtxUnlockCredential*)staged_buffer;
- ret = avb_atx_validate_unlock_credential(atx_ops, buf, &out_is_trusted);
- if ((ret != AVB_IO_RESULT_OK) || (out_is_trusted != true)) {
- ERR("validate unlock credential fail!\n");
- return -1;
- } else
- return 0;
-}
-
-bool perm_attr_are_fused(void)
-{
-#ifdef CONFIG_IMX_TRUSTY_OS
- AvbAtxPermanentAttributes attributes;
- if(!trusty_read_permanent_attributes((uint8_t *)(&attributes),
- sizeof(AvbAtxPermanentAttributes))) {
- return true;
- } else {
- ERR("No perm-attr fused, please fuse your perm-attr first!.\n");
- return false;
- }
-#else
- /* We hard code the perm-attr if trusty is not enabled. */
- return true;
-#endif
-}
-
-bool at_unlock_vboot_is_disabled(void)
-{
- uint32_t unlock_vboot_status;
-
- if (fsl_fuse_read(&unlock_vboot_status, 1,
- UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) {
- printf("Read at unlock vboot status error!\n");
- return false;
- }
-
- if (unlock_vboot_status & (1 << UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT))
- return true;
- else
- return false;
-}
-
-int at_disable_vboot_unlock(void)
-{
- uint32_t unlock_vboot_status = 0;
-
- /* Read the status first */
- if (fsl_fuse_read(&unlock_vboot_status, 1,
- UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) {
- ERR("Read unlock vboot status error!\n");
- return -1;
- }
-
- /* Set the disable unlock vboot bit */
- unlock_vboot_status |= (1 << UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT);
-
- /* Write disable unlock vboot bit to fuse */
- if (fsl_fuse_write(&unlock_vboot_status, 1,
- UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) {
- ERR("Write unlock vboot status fail!\n");
- return -1;
- }
-
- return 0;
-}
-/* Reads permanent |attributes| data. There are no restrictions on where this
- * data is stored. On success, returns AVB_IO_RESULT_OK and populates
- * |attributes|.
- */
-AvbIOResult fsl_read_permanent_attributes(
- AvbAtxOps* atx_ops, AvbAtxPermanentAttributes* attributes) {
-#ifdef CONFIG_IMX_TRUSTY_OS
- if (!trusty_read_permanent_attributes((uint8_t *)attributes,
- sizeof(AvbAtxPermanentAttributes))) {
- return AVB_IO_RESULT_OK;
- }
- ERR("No perm-attr fused. Will use hard code one.\n");
-#endif /* CONFIG_IMX_TRUSTY_OS */
-
- /* use hard code permanent attributes due to limited fuse and RPMB */
- attributes->version = fsl_version;
- memcpy(attributes->product_root_public_key, fsl_product_root_public_key,
- sizeof(fsl_product_root_public_key));
- memcpy(attributes->product_id, fsl_atx_product_id,
- sizeof(fsl_atx_product_id));
-
- return AVB_IO_RESULT_OK;
-}
-
-/* Reads a |hash| of permanent attributes. This hash MUST be retrieved from a
- * permanently read-only location (e.g. fuses) when a device is LOCKED. On
- * success, returned AVB_IO_RESULT_OK and populates |hash|.
- */
-AvbIOResult fsl_read_permanent_attributes_hash(
- AvbAtxOps* atx_ops, uint8_t hash[AVB_SHA256_DIGEST_SIZE]) {
-#ifdef CONFIG_ARM64
- /* calculate sha256(permanent attributes) */
- if (permanent_attributes_sha256_hash(hash) != RESULT_OK) {
- return AVB_IO_RESULT_ERROR_IO;
- } else {
- return AVB_IO_RESULT_OK;
- }
-#else
- uint8_t sha256_hash_buf[AVB_SHA256_DIGEST_SIZE];
- uint32_t sha256_hash_fuse[ATX_FUSE_BANK_NUM];
-
- /* read first 112 bits of sha256(permanent attributes) from fuse */
- if (fsl_fuse_read(sha256_hash_fuse, ATX_FUSE_BANK_NUM,
- PERMANENT_ATTRIBUTE_HASH_OFFSET)) {
- printf("ERROR - read permanent attributes hash from "
- "fuse error\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
- /* only take the lower 2 bytes of last bank */
- sha256_hash_fuse[ATX_FUSE_BANK_NUM - 1] &= ATX_FUSE_BANK_MASK;
-
- /* calculate sha256(permanent attributes) */
- if (permanent_attributes_sha256_hash(sha256_hash_buf) != RESULT_OK) {
- return AVB_IO_RESULT_ERROR_IO;
- }
- /* check if the sha256(permanent attributes) hash match the calculated one,
- * if not match, just return all zeros hash.
- */
- if (memcmp(sha256_hash_fuse, sha256_hash_buf, ATX_HASH_LENGTH)) {
- printf("ERROR - sha256(permanent attributes) does not match\n");
- memset(hash, 0, AVB_SHA256_DIGEST_SIZE);
- } else {
- memcpy(hash, sha256_hash_buf, AVB_SHA256_DIGEST_SIZE);
- }
-
- return AVB_IO_RESULT_OK;
-#endif /* CONFIG_ARM64 */
-}
-
- /* Generates |num_bytes| random bytes and stores them in |output|,
- * which must point to a buffer large enough to store the bytes.
- *
- * Returns AVB_IO_RESULT_OK on success, otherwise an error code.
- */
-AvbIOResult fsl_get_random(AvbAtxOps* atx_ops,
- size_t num_bytes,
- uint8_t* output)
-{
- uint32_t num = 0;
- uint32_t i;
-
- if (output == NULL) {
- ERR("Output buffer is NULL!\n");
- return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE;
- }
+extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
- /* set the seed as device boot time. */
- srand((uint32_t)get_timer(0));
- for (i = 0; i < num_bytes; i++) {
- num = rand() % 256;
- output[i] = (uint8_t)num;
- }
+#ifdef AVB_RPMB
+static int mmc_dev_no = -1;
- return AVB_IO_RESULT_OK;
+struct mmc *get_mmc(void) {
+ extern int mmc_get_env_devno(void);
+ struct mmc *mmc;
+ if (mmc_dev_no < 0 && (mmc_dev_no = mmc_get_env_dev()) < 0)
+ return NULL;
+ mmc = find_mmc_device(mmc_dev_no);
+ if (!mmc || mmc_init(mmc))
+ return NULL;
+ return mmc;
}
-#endif /* CONFIG_AVB_ATX */
-#endif /* CONFIG_SPL_BUILD */
-
-#if defined(AVB_RPMB) || defined(CONFIG_IMX_TRUSTY_OS)
void fill_secure_keyslot_package(struct keyslot_package *kp) {
memcpy((void*)CAAM_ARB_BASE_ADDR, kp, sizeof(struct keyslot_package));
@@ -521,61 +132,211 @@ fail:
#endif
return ret;
}
-#endif /* (AVB_RPMB) || defined(CONFIG_IMX_TRUSTY_OS) */
-#ifndef AVB_RPMB
-/* ARM64 won't avbkey and rollback index in this stage directly. */
-int avbkey_init(uint8_t *plainkey, uint32_t keylen) {
- return 0;
-}
+#ifdef CONFIG_FSL_CAAM_KB
+int rpmb_read(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset) {
-int rbkidx_erase(void) {
- return 0;
-}
+ unsigned char *bdata = NULL;
+ unsigned char *out_buf = (unsigned char *)buffer;
+ unsigned long s, cnt;
+ unsigned long blksz;
+ size_t num_read = 0;
+ unsigned short part_start, part_length, part_end, bs, be;
+ margin_pos_t margin;
+ char original_part;
+ uint8_t *blob = NULL;
+ struct blk_desc *desc = mmc_get_blk_desc(mmc);
+ ALLOC_CACHE_ALIGN_BUFFER(uint8_t, extract_key, RPMBKEY_LENGTH);
-/*
- * In no security enhanced ARM64, we cannot protect public key.
- * So that we choose to trust the key from vbmeta image
- */
-AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_is_trusted) {
- *out_is_trusted = true;
- return AVB_IO_RESULT_OK;
-}
+ struct keyslot_package kp;
+ int ret;
-/* In no security enhanced ARM64, rollback index has no protection so no use it */
-AvbIOResult fsl_write_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
- uint64_t rollback_index) {
- return AVB_IO_RESULT_OK;
+ blksz = RPMB_BLKSZ;
+ part_length = mmc->capacity_rpmb >> 8;
+ part_start = 0;
+ part_end = part_start + part_length - 1;
-}
-AvbIOResult fsl_read_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
- uint64_t* out_rollback_index) {
- *out_rollback_index = 0;
- return AVB_IO_RESULT_OK;
-}
-#else /* AVB_RPMB */
-static int mmc_dev_no = -1;
+ DEBUGAVB("[rpmb]: offset=%ld, num_bytes=%zu\n", (long)offset, num_bytes);
+
+ if(get_margin_pos(part_start, part_end, blksz,
+ &margin, offset, num_bytes, false))
+ return -1;
+
+ bs = (unsigned short)margin.blk_start;
+ be = (unsigned short)margin.blk_end;
+ s = margin.start;
+
+ /* Switch to the RPMB partition */
+ original_part = desc->hwpart;
+ if (desc->hwpart != MMC_PART_RPMB) {
+ if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0)
+ return -1;
+ desc->hwpart = MMC_PART_RPMB;
+ }
+
+ /* get rpmb key */
+ blob = (uint8_t *)memalign(ARCH_DMA_MINALIGN, RPMBKEY_BLOB_LEN);
+ if (read_keyslot_package(&kp)) {
+ ERR("read rpmb key error\n");
+ ret = -1;
+ goto fail;
+ }
+ /* copy rpmb key to blob */
+ memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
+ caam_open();
+ if (caam_decap_blob((ulong)extract_key, (ulong)blob,
+ RPMBKEY_LENGTH)) {
+ ERR("decap rpmb key error\n");
+ ret = -1;
+ goto fail;
+ }
+
+ /* alloc a blksz mem */
+ bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz);
+ if (bdata == NULL) {
+ ret = -1;
+ goto fail;
+ }
+ /* one block a time */
+ while (bs <= be) {
+ memset(bdata, 0, blksz);
+ if (mmc_rpmb_read(mmc, bdata, bs, 1, extract_key) != 1) {
+ ret = -1;
+ goto fail;
+ }
+ cnt = blksz - s;
+ if (num_read + cnt > num_bytes)
+ cnt = num_bytes - num_read;
+ VDEBUG("cur: bs=%d, start=%ld, cnt=%ld bdata=0x%p\n",
+ bs, s, cnt, bdata);
+ memcpy(out_buf, bdata + s, cnt);
+ bs++;
+ num_read += cnt;
+ out_buf += cnt;
+ s = 0;
+ }
+ ret = 0;
+
+fail:
+ /* Return to original partition */
+ if (desc->hwpart != original_part) {
+ if (mmc_switch_part(mmc, original_part) != 0)
+ return -1;
+ desc->hwpart = original_part;
+ }
+ if (blob != NULL)
+ free(blob);
+ if (bdata != NULL)
+ free(bdata);
+ return ret;
-struct mmc *get_mmc(void) {
- extern int mmc_get_env_devno(void);
- struct mmc *mmc;
- if (mmc_dev_no < 0 && (mmc_dev_no = mmc_get_env_dev()) < 0)
- return NULL;
- mmc = find_mmc_device(mmc_dev_no);
- if (!mmc || mmc_init(mmc))
- return NULL;
- return mmc;
}
-int rpmb_read(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset);
-int rpmb_write(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset);
+int rpmb_write(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset) {
+
+ unsigned char *bdata = NULL;
+ unsigned char *in_buf = (unsigned char *)buffer;
+ unsigned long s, cnt;
+ unsigned long blksz;
+ size_t num_write = 0;
+ unsigned short part_start, part_length, part_end, bs;
+ margin_pos_t margin;
+ char original_part;
+ uint8_t *blob = NULL;
+ struct blk_desc *desc = mmc_get_blk_desc(mmc);
+ ALLOC_CACHE_ALIGN_BUFFER(uint8_t, extract_key, RPMBKEY_LENGTH);
+
+ struct keyslot_package kp;
+ int ret;
+
+ blksz = RPMB_BLKSZ;
+ part_length = mmc->capacity_rpmb >> 8;
+ part_start = 0;
+ part_end = part_start + part_length - 1;
+
+ DEBUGAVB("[rpmb]: offset=%ld, num_bytes=%zu\n", (long)offset, num_bytes);
+
+ if(get_margin_pos(part_start, part_end, blksz,
+ &margin, offset, num_bytes, false)) {
+ ERR("get_margin_pos err\n");
+ return -1;
+ }
+
+ bs = (unsigned short)margin.blk_start;
+ s = margin.start;
+
+ /* Switch to the RPMB partition */
+ original_part = desc->hwpart;
+ if (desc->hwpart != MMC_PART_RPMB) {
+ if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0)
+ return -1;
+ desc->hwpart = MMC_PART_RPMB;
+ }
+
+ /* get rpmb key */
+ blob = (uint8_t *)memalign(ARCH_DMA_MINALIGN, RPMBKEY_BLOB_LEN);
+ if (read_keyslot_package(&kp)) {
+ ERR("read rpmb key error\n");
+ ret = -1;
+ goto fail;
+ }
+ /* copy rpmb key to blob */
+ memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
+ caam_open();
+ if (caam_decap_blob((ulong)extract_key, (ulong)blob,
+ RPMBKEY_LENGTH)) {
+ ERR("decap rpmb key error\n");
+ ret = -1;
+ goto fail;
+ }
+ /* alloc a blksz mem */
+ bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz);
+ if (bdata == NULL) {
+ ret = -1;
+ goto fail;
+ }
+ while (num_write < num_bytes) {
+ memset(bdata, 0, blksz);
+ cnt = blksz - s;
+ if (num_write + cnt > num_bytes)
+ cnt = num_bytes - num_write;
+ if (!s || cnt != blksz) { /* read blk first */
+ if (mmc_rpmb_read(mmc, bdata, bs, 1, extract_key) != 1) {
+ ERR("mmc_rpmb_read err, mmc= 0x%08x\n", (uint32_t)(ulong)mmc);
+ ret = -1;
+ goto fail;
+ }
+ }
+ memcpy(bdata + s, in_buf, cnt); /* change data */
+ VDEBUG("cur: bs=%d, start=%ld, cnt=%ld\n", bs, s, cnt);
+ if (mmc_rpmb_write(mmc, bdata, bs, 1, extract_key) != 1) {
+ ret = -1;
+ goto fail;
+ }
+ bs++;
+ num_write += cnt;
+ in_buf += cnt;
+ if (s != 0)
+ s = 0;
+ }
+ ret = 0;
+
+fail:
+ /* Return to original partition */
+ if (desc->hwpart != original_part) {
+ if (mmc_switch_part(mmc, original_part) != 0)
+ return -1;
+ desc->hwpart = original_part;
+ }
+ if (blob != NULL)
+ free(blob);
+ if (bdata != NULL)
+ free(bdata);
+
+ return ret;
+
+}
-#if !defined(CONFIG_IMX_TRUSTY_OS) || defined(CONFIG_SPL_BUILD)
int rpmb_init(void) {
#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_DUAL_BOOTLOADER)
int i;
@@ -692,9 +453,7 @@ int rpmb_init(void) {
return 0;
}
-#endif /* !CONFIG_IMX_TRUSTY_OS || CONFIG_SPL_BUILD */
-#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_ARM64)
int gen_rpmb_key(struct keyslot_package *kp) {
char original_part;
unsigned char* fill = NULL;
@@ -715,9 +474,13 @@ int gen_rpmb_key(struct keyslot_package *kp) {
printf("boota: cannot find '%d' mmc device\n", mmcc);
return -1;
}
+#ifndef CONFIG_BLK
original_part = mmc->block_dev.hwpart;
-
dev_desc = blk_get_dev("mmc", mmcc);
+#else
+ dev_desc = mmc_get_blk_desc(mmc);
+ original_part = dev_desc->hwpart;
+#endif
if (NULL == dev_desc) {
printf("** Block device MMC %d not supported\n", mmcc);
goto fail;
@@ -766,11 +529,19 @@ int gen_rpmb_key(struct keyslot_package *kp) {
}
/* program key to mmc */
+#ifndef CONFIG_BLK
if (mmc->block_dev.hwpart != MMC_PART_RPMB) {
if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0)
- goto fail;
+ return -1;
mmc->block_dev.hwpart = MMC_PART_RPMB;
}
+#else
+ if (dev_desc->hwpart != MMC_PART_RPMB) {
+ if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0)
+ return -1;
+ dev_desc->hwpart = MMC_PART_RPMB;
+ }
+#endif
if (mmc_rpmb_set_key(mmc, plain_key)) {
ERR("Key already programmed ?\n");
goto fail;
@@ -783,236 +554,22 @@ fail:
free(fill);
/* Return to original partition */
+#ifndef CONFIG_BLK
if (mmc->block_dev.hwpart != original_part) {
if (mmc_switch_part(mmc, original_part) != 0)
return -1;
mmc->block_dev.hwpart = original_part;
}
- return ret;
-
-}
-
-int rpmb_read(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset) {
-
- unsigned char *bdata = NULL;
- unsigned char *out_buf = (unsigned char *)buffer;
- unsigned long s, cnt;
- unsigned long blksz;
- size_t num_read = 0;
- unsigned short part_start, part_length, part_end, bs, be;
- margin_pos_t margin;
- char original_part;
- uint8_t *blob = NULL;
- struct blk_desc *desc = mmc_get_blk_desc(mmc);
- ALLOC_CACHE_ALIGN_BUFFER(uint8_t, extract_key, RPMBKEY_LENGTH);
-
-#ifdef AVB_RPMB
- struct keyslot_package kp;
-#endif
-
- int ret;
-
- blksz = RPMB_BLKSZ;
- part_length = mmc->capacity_rpmb >> 8;
- part_start = 0;
- part_end = part_start + part_length - 1;
-
- DEBUGAVB("[rpmb]: offset=%ld, num_bytes=%zu\n", (long)offset, num_bytes);
-
- if(get_margin_pos(part_start, part_end, blksz,
- &margin, offset, num_bytes, false))
- return -1;
-
- bs = (unsigned short)margin.blk_start;
- be = (unsigned short)margin.blk_end;
- s = margin.start;
-
- /* Switch to the RPMB partition */
- original_part = desc->hwpart;
- if (desc->hwpart != MMC_PART_RPMB) {
- if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0)
- return -1;
- desc->hwpart = MMC_PART_RPMB;
- }
-
- /* get rpmb key */
- blob = (uint8_t *)memalign(ARCH_DMA_MINALIGN, RPMBKEY_BLOB_LEN);
-#ifdef AVB_RPMB
- if (read_keyslot_package(&kp)) {
#else
- if (fsl_fuse_read((uint32_t *)blob, RPMBKEY_FUSE_LENW, RPMBKEY_FUSE_OFFSET)){
-#endif
- ERR("read rpmb key error\n");
- ret = -1;
- goto fail;
- }
- /* copy rpmb key to blob */
-#ifdef AVB_RPMB
- memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
-#endif
- caam_open();
- if (caam_decap_blob((ulong)extract_key, (ulong)blob,
- RPMBKEY_LENGTH)) {
- ERR("decap rpmb key error\n");
- ret = -1;
- goto fail;
- }
-
- /* alloc a blksz mem */
- bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz);
- if (bdata == NULL) {
- ret = -1;
- goto fail;
- }
- /* one block a time */
- while (bs <= be) {
- memset(bdata, 0, blksz);
- if (mmc_rpmb_read(mmc, bdata, bs, 1, extract_key) != 1) {
- ret = -1;
- goto fail;
- }
- cnt = blksz - s;
- if (num_read + cnt > num_bytes)
- cnt = num_bytes - num_read;
- VDEBUG("cur: bs=%d, start=%ld, cnt=%ld bdata=0x%p\n",
- bs, s, cnt, bdata);
- memcpy(out_buf, bdata + s, cnt);
- bs++;
- num_read += cnt;
- out_buf += cnt;
- s = 0;
- }
- ret = 0;
-
-fail:
- /* Return to original partition */
- if (desc->hwpart != original_part) {
+ if (dev_desc->hwpart != original_part) {
if (mmc_switch_part(mmc, original_part) != 0)
return -1;
- desc->hwpart = original_part;
- }
- if (blob != NULL)
- free(blob);
- if (bdata != NULL)
- free(bdata);
- return ret;
-
-}
-int rpmb_write(struct mmc *mmc, uint8_t *buffer, size_t num_bytes, int64_t offset) {
-
- unsigned char *bdata = NULL;
- unsigned char *in_buf = (unsigned char *)buffer;
- unsigned long s, cnt;
- unsigned long blksz;
- size_t num_write = 0;
- unsigned short part_start, part_length, part_end, bs;
- margin_pos_t margin;
- char original_part;
- uint8_t *blob = NULL;
- struct blk_desc *desc = mmc_get_blk_desc(mmc);
- ALLOC_CACHE_ALIGN_BUFFER(uint8_t, extract_key, RPMBKEY_LENGTH);
-
-#ifdef AVB_RPMB
- struct keyslot_package kp;
-#endif
-
- int ret;
-
- blksz = RPMB_BLKSZ;
- part_length = mmc->capacity_rpmb >> 8;
- part_start = 0;
- part_end = part_start + part_length - 1;
-
- DEBUGAVB("[rpmb]: offset=%ld, num_bytes=%zu\n", (long)offset, num_bytes);
-
- if(get_margin_pos(part_start, part_end, blksz,
- &margin, offset, num_bytes, false)) {
- ERR("get_margin_pos err\n");
- return -1;
- }
-
- bs = (unsigned short)margin.blk_start;
- s = margin.start;
-
- /* Switch to the RPMB partition */
- original_part = desc->hwpart;
- if (desc->hwpart != MMC_PART_RPMB) {
- if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0)
- return -1;
- desc->hwpart = MMC_PART_RPMB;
- }
-
- /* get rpmb key */
- blob = (uint8_t *)memalign(ARCH_DMA_MINALIGN, RPMBKEY_BLOB_LEN);
-#ifdef AVB_RPMB
- if (read_keyslot_package(&kp)) {
-#else
- if (fsl_fuse_read((uint32_t *)blob, RPMBKEY_FUSE_LENW, RPMBKEY_FUSE_OFFSET)){
-#endif
- ERR("read rpmb key error\n");
- ret = -1;
- goto fail;
+ dev_desc->hwpart = original_part;
}
- /* copy rpmb key to blob */
-#ifdef AVB_RPMB
- memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
#endif
- caam_open();
- if (caam_decap_blob((ulong)extract_key, (ulong)blob,
- RPMBKEY_LENGTH)) {
- ERR("decap rpmb key error\n");
- ret = -1;
- goto fail;
- }
- /* alloc a blksz mem */
- bdata = (unsigned char *)memalign(ALIGN_BYTES, blksz);
- if (bdata == NULL) {
- ret = -1;
- goto fail;
- }
- while (num_write < num_bytes) {
- memset(bdata, 0, blksz);
- cnt = blksz - s;
- if (num_write + cnt > num_bytes)
- cnt = num_bytes - num_write;
- if (!s || cnt != blksz) { /* read blk first */
- if (mmc_rpmb_read(mmc, bdata, bs, 1, extract_key) != 1) {
- ERR("mmc_rpmb_read err, mmc= 0x%08x\n", (uint32_t)(ulong)mmc);
- ret = -1;
- goto fail;
- }
- }
- memcpy(bdata + s, in_buf, cnt); /* change data */
- VDEBUG("cur: bs=%d, start=%ld, cnt=%ld\n", bs, s, cnt);
- if (mmc_rpmb_write(mmc, bdata, bs, 1, extract_key) != 1) {
- ret = -1;
- goto fail;
- }
- bs++;
- num_write += cnt;
- in_buf += cnt;
- if (s != 0)
- s = 0;
- }
- ret = 0;
-
-fail:
- /* Return to original partition */
- if (desc->hwpart != original_part) {
- if (mmc_switch_part(mmc, original_part) != 0)
- return -1;
- desc->hwpart = original_part;
- }
- if (blob != NULL)
- free(blob);
- if (bdata != NULL)
- free(bdata);
-
return ret;
}
-#endif /* CONFIG_SPL_BUILD || !CONFIG_ARM64 */
-//#ifndef CONFIG_SPL_BUILD
int init_avbkey(void) {
#ifndef CONFIG_ARM64
@@ -1035,90 +592,7 @@ int init_avbkey(void) {
return RESULT_OK;
}
-#ifndef CONFIG_SPL_BUILD
-#ifndef CONFIG_ARM64
-static int rpmb_key(struct mmc *mmc) {
- char original_part;
- int ret = 0;
- struct blk_desc *desc = mmc_get_blk_desc(mmc);
- ALLOC_CACHE_ALIGN_BUFFER(uint8_t, blob, RPMBKEY_FUSE_LEN);
- ALLOC_CACHE_ALIGN_BUFFER(uint8_t, plain_key, RPMBKEY_LENGTH);
-
- DEBUGAVB("[rpmb]: set kley\n");
-
- /* Switch to the RPMB partition */
- original_part = desc->hwpart;
- if (desc->hwpart != MMC_PART_RPMB) {
- if (mmc_switch_part(mmc, MMC_PART_RPMB) != 0) {
- ERR("failed to switch part!\n");
- return -1;
- }
- desc->hwpart = MMC_PART_RPMB;
- }
-
- /* use caam hwrng to generate */
- caam_open();
- if (caam_hwrng(plain_key, RPMBKEY_LENGTH)) {
- ERR("ERROR - caam rng\n");
- ret = -1;
- goto fail;
- }
-
- /* generate keyblob and program to fuse */
- if (caam_gen_blob((ulong)plain_key, (ulong)blob,
- RPMBKEY_LENGTH)) {
- ERR("gen rpmb key blb error\n");
- ret = -1;
- goto fail;
- }
-
- if (fsl_fuse_write((uint32_t *)blob, RPMBKEY_FUSE_LENW, RPMBKEY_FUSE_OFFSET)){
- ERR("write rpmb key to fuse error\n");
- ret = -1;
- goto fail;
- }
-
-#ifdef CONFIG_AVB_FUSE
- /* program key to mmc */
- if (mmc_rpmb_set_key(mmc, plain_key)) {
- ERR("Key already programmed ?\n");
- ret = -1;
- goto fail;
- }
-#endif
-
-#ifdef CONFIG_AVB_DEBUG
- /* debug */
- ALLOC_CACHE_ALIGN_BUFFER(uint8_t, ext_key, RPMBKEY_LENGTH);
- printf(" RPMB plain kay---\n");
- print_buffer(0, plain_key, HEXDUMP_WIDTH, RPMBKEY_LENGTH, 0);
- if (fsl_fuse_read((uint32_t *)blob, RPMBKEY_FUSE_LENW, RPMBKEY_FUSE_OFFSET)){
- ERR("read rpmb key to fuse error\n");
- ret = -1;
- goto fail;
- }
- printf(" RPMB blob---\n");
- print_buffer(0, blob, HEXDUMP_WIDTH, RPMBKEY_FUSE_LEN, 0);
- if (caam_decap_blob((uint32_t)ext_key, (uint32_t)blob, RPMBKEY_LENGTH)) {
- ret = -1;
- goto fail;
- }
- printf(" RPMB extract---\n");
- print_buffer(0, ext_key, HEXDUMP_WIDTH, RPMBKEY_LENGTH, 0);
- /* debug done */
-#endif
-
-fail:
- /* Return to original partition */
- if (desc->hwpart != original_part) {
- if (mmc_switch_part(mmc, original_part) != 0)
- return -1;
- desc->hwpart = original_part;
- }
- return ret;
-
-}
-
+#ifndef CONFIG_IMX_TRUSTY_OS
int rbkidx_erase(void) {
int i;
kblb_hdr_t hdr;
@@ -1169,407 +643,347 @@ int rbkidx_erase(void) {
}
return 0;
}
+#endif /* CONFIG_FSL_CAAM_KB */
+#endif /* CONFIG_IMX_TRUSTY_OS */
+#else /* AVB_RPMB */
+int rbkidx_erase(void) {
+ return 0;
+}
+#endif /* AVB_RPMB */
-int avbkey_init(uint8_t *plainkey, uint32_t keylen) {
- int i;
- kblb_hdr_t hdr;
- kblb_tag_t *tag;
- struct mmc *mmc_dev;
- uint32_t init_flag;
-
- /* int ret; */
-
- assert(plainkey != NULL);
-
- /* check overflow */
- if (keylen > AVB_RBIDX_START - AVB_PUBKY_OFFSET) {
- ERR("key len overflow\n");
- return -1;
- }
+#ifdef CONFIG_SPL_BUILD
+#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT)
+int check_rpmb_blob(struct mmc *mmc)
+{
+ int ret = 0;
+ char original_part;
+ struct keyslot_package kp;
- /* check init status */
- if (fsl_fuse_read(&init_flag, 1, INITFLAG_FUSE_OFFSET)) {
- ERR("ERROR - read fuse init flag error\n");
- return -1;
- }
- if ((init_flag & INITFLAG_FUSE_MASK) == INITFLAG_FUSE) {
- ERR("ERROR - already inited\n");
- return -1;
+ read_keyslot_package(&kp);
+ if (strcmp(kp.magic, KEYPACK_MAGIC)) {
+ printf("keyslot package magic error, do nothing here!\n");
+ return 0;
}
- init_flag = INITFLAG_FUSE & INITFLAG_FUSE_MASK;
+ /* If keyslot package valid, copy it to secure memory */
+ fill_secure_keyslot_package(&kp);
- /* generate and write key to mmc/fuse */
- if ((mmc_dev = get_mmc()) == NULL) {
- ERR("ERROR - get mmc device\n");
- return -1;
+ /* switch to boot1 partition. */
+ original_part = mmc->block_dev.hwpart;
+ if (mmc_switch_part(mmc, KEYSLOT_HWPARTITION_ID) != 0) {
+ printf("ERROR - can't switch to boot1 partition! \n");
+ ret = -1;
+ goto fail;
+ } else
+ mmc->block_dev.hwpart = KEYSLOT_HWPARTITION_ID;
+ /* write power-on write protection for boot1 partition. */
+ if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) {
+ printf("ERROR - unable to set power-on write protection!\n");
+ ret = -1;
+ goto fail;
}
- if (rpmb_key(mmc_dev)) {
- ERR("ERROR - write mmc rpmb key\n");
- return -1;
+fail:
+ /* return to original partition. */
+ if (mmc->block_dev.hwpart != original_part) {
+ if (mmc_switch_part(mmc, original_part) != 0)
+ return -1;
+ mmc->block_dev.hwpart = original_part;
}
- if (fsl_fuse_write(&init_flag, 1, INITFLAG_FUSE_OFFSET)){
- ERR("write fuse init error\n");
- return -1;
- }
+ return ret;
+}
+#endif /* CONFIG_IMX_TRUSTY_OS && CONFIG_ANDROID_AUTO_SUPPORT */
+#else /* CONFIG_SPL_BUILD */
+#ifdef CONFIG_AVB_ATX
+static int fsl_fuse_ops(uint32_t *buffer, uint32_t length, uint32_t offset,
+ const uint8_t read) {
- /* init pubkey */
- tag = &hdr.pubk_tag;
- tag->flag = AVB_PUBKY_FLAG;
- tag->offset = AVB_PUBKY_OFFSET;
- tag->len = keylen;
+ unsigned short bs, ws, bksz, cnt;
+ unsigned short num_done = 0;
+ margin_pos_t margin;
+ int i;
- if (rpmb_write(mmc_dev, plainkey, tag->len, tag->offset) != 0) {
- ERR("write RPMB error\n");
+ /* read from fuse */
+ bksz = CONFIG_AVB_FUSE_BANK_SIZEW;
+ if(get_margin_pos(CONFIG_AVB_FUSE_BANK_START, CONFIG_AVB_FUSE_BANK_END, bksz,
+ &margin, offset, length, false))
return -1;
- }
+ bs = (unsigned short)margin.blk_start;
+ ws = (unsigned short)margin.start;
- /* init rollback index */
- uint32_t offset = AVB_RBIDX_START;
- uint32_t rbidx_len = AVB_RBIDX_LEN;
- uint8_t *rbidx = malloc(rbidx_len);
- if (rbidx == NULL)
- return -1;
- memset(rbidx, 0, rbidx_len);
- *(uint64_t *)rbidx = AVB_RBIDX_INITVAL;
- for (i = 0; i < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; i++) {
- tag = &hdr.rbk_tags[i];
- tag->flag = AVB_RBIDX_FLAG;
- tag->offset = offset;
- tag->len = rbidx_len;
- if (rpmb_write(mmc_dev, rbidx, tag->len, tag->offset) != 0) {
- ERR("write RBKIDX RPMB error\n");
- free(rbidx);
- return -1;
+ while (num_done < length) {
+ cnt = bksz - ws;
+ if (num_done + cnt > length)
+ cnt = length - num_done;
+ for (i = 0; i < cnt; i++) {
+ VDEBUG("cur: bank=%d, word=%d\n",bs, ws);
+ if (read) {
+ if (fuse_sense(bs, ws, buffer)) {
+ ERR("read fuse bank %d, word %d error\n", bs, ws);
+ return -1;
+ }
+ } else {
+#ifdef CONFIG_AVB_FUSE
+ if (fuse_prog(bs, ws, *buffer)) {
+#else
+ if (fuse_override(bs, ws, *buffer)) {
+#endif
+ ERR("write fuse bank %d, word %d error\n", bs, ws);
+ return -1;
+ }
+ }
+ ws++;
+ buffer++;
}
- offset += AVB_RBIDX_ALIGN;
+ bs++;
+ num_done += cnt;
+ ws = 0;
}
- free(rbidx);
+ return 0;
+}
- /* init hdr */
- memcpy(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN);
- if (rpmb_write(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
- ERR("write RPMB hdr error\n");
- return -1;
- }
+int fsl_fuse_read(uint32_t *buffer, uint32_t length, uint32_t offset) {
- return 0;
+ return fsl_fuse_ops(
+ buffer,
+ length,
+ offset,
+ 1
+ );
}
-#endif /* CONFIG_ARM64 */
-/* Checks if the given public key used to sign the 'vbmeta'
- * partition is trusted. Boot loaders typically compare this with
- * embedded key material generated with 'avbtool
- * extract_public_key'.
- *
- * If AVB_IO_RESULT_OK is returned then |out_is_trusted| is set -
- * true if trusted or false if untrusted.
- */
-AvbIOResult fsl_validate_vbmeta_public_key_rpmb(AvbOps* ops,
- const uint8_t* public_key_data,
- size_t public_key_length,
- const uint8_t* public_key_metadata,
- size_t public_key_metadata_length,
- bool* out_is_trusted) {
- AvbIOResult ret;
- assert(ops != NULL && out_is_trusted != NULL);
- *out_is_trusted = false;
+int fsl_fuse_write(const uint32_t *buffer, uint32_t length, uint32_t offset) {
- /* match given public key */
- if (memcmp(fsl_public_key, public_key_data, public_key_length)) {
- ret = AVB_IO_RESULT_ERROR_IO;
- ERR("public key not match\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
+ return fsl_fuse_ops(
+ (uint32_t *)buffer,
+ length,
+ offset,
+ 0
+ );
+}
- *out_is_trusted = true;
- ret = AVB_IO_RESULT_OK;
+static int sha256(unsigned char* data, int len, unsigned char* output) {
+ struct hash_algo *algo;
+ void *buf;
- return ret;
+ if (hash_lookup_algo("sha256", &algo)) {
+ printf("error in lookup sha256 algo!\n");
+ return RESULT_ERROR;
+ }
+ buf = map_sysmem((ulong)data, len);
+ algo->hash_func_ws(buf, len, output, algo->chunk_size);
+ unmap_sysmem(buf);
+
+ return algo->digest_size;
}
-/* Gets the rollback index corresponding to the slot given by
- * |rollback_index_slot|. The value is returned in
- * |out_rollback_index|. Returns AVB_IO_RESULT_OK if the rollback
- * index was retrieved, otherwise an error code.
- *
- * A device may have a limited amount of rollback index slots (say,
- * one or four) so may error out if |rollback_index_slot| exceeds
- * this number.
- */
-AvbIOResult fsl_read_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
- uint64_t* out_rollback_index) {
- AvbIOResult ret;
+int permanent_attributes_sha256_hash(unsigned char* output) {
+ AvbAtxPermanentAttributes attributes;
+
#ifdef CONFIG_IMX_TRUSTY_OS
- if (trusty_read_rollback_index(rollback_index_slot, out_rollback_index)) {
- ERR("read rollback from Trusty error!");
- ret = AVB_IO_RESULT_ERROR_IO;
+ if(!trusty_read_permanent_attributes((uint8_t *)(&attributes),
+ sizeof(AvbAtxPermanentAttributes))) {
+ goto calc_sha256;
} else {
- ret = AVB_IO_RESULT_OK;
+ ERR("No perm-attr fused. Will use hard code one.\n");
}
- return ret;
-#else
- kblb_hdr_t hdr;
- kblb_tag_t *rbk;
- uint64_t *extract_idx = NULL;
- struct mmc *mmc_dev;
-#ifdef CONFIG_AVB_ATX
- static const uint32_t kTypeMask = 0xF000;
- static const unsigned int kTypeShift = 12;
#endif
+ /* get permanent attributes */
+ attributes.version = fsl_version;
+ memcpy(attributes.product_root_public_key, fsl_product_root_public_key,
+ sizeof(fsl_product_root_public_key));
+ memcpy(attributes.product_id, fsl_atx_product_id,
+ sizeof(fsl_atx_product_id));
+#ifdef CONFIG_IMX_TRUSTY_OS
+calc_sha256:
+#endif
+ /* calculate sha256(permanent attributes) hash */
+ if (sha256((unsigned char *)&attributes, sizeof(AvbAtxPermanentAttributes),
+ output) == RESULT_ERROR) {
+ printf("ERROR - calculate permanent attributes hash error");
+ return RESULT_ERROR;
+ }
- assert(ops != NULL && out_rollback_index != NULL);
- *out_rollback_index = ~0;
+ return RESULT_OK;
+}
- DEBUGAVB("[rpmb] read rollback slot: %zu\n", rollback_index_slot);
+static int init_permanent_attributes_fuse(void) {
- /* check if the rollback index location exceed the limit */
-#ifdef CONFIG_AVB_ATX
- if ((rollback_index_slot & ~kTypeMask) >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
+#ifdef CONFIG_ARM64
+ return RESULT_OK;
#else
- if (rollback_index_slot >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
-#endif
- return AVB_IO_RESULT_ERROR_IO;
+ uint8_t sha256_hash[AVB_SHA256_DIGEST_SIZE];
+ uint32_t buffer[ATX_FUSE_BANK_NUM];
+ int num = 0;
- if ((mmc_dev = get_mmc()) == NULL) {
- ERR("err get mmc device\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
- /* read the kblb header */
- if (rpmb_read(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
- ERR("read RPMB error\n");
- return AVB_IO_RESULT_ERROR_IO;
+ /* read first 112 bits of sha256(permanent attributes) from fuse */
+ if (fsl_fuse_read(buffer, ATX_FUSE_BANK_NUM, PERMANENT_ATTRIBUTE_HASH_OFFSET)) {
+ printf("ERROR - read permanent attributes hash from fuse error\n");
+ return RESULT_ERROR;
}
+ /* only take the lower 2 bytes of the last bank */
+ buffer[ATX_FUSE_BANK_NUM - 1] &= ATX_FUSE_BANK_MASK;
- if (memcmp(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN) != 0) {
- ERR("magic not match\n");
- return AVB_IO_RESULT_ERROR_IO;
+ /* return RESULT_OK if fuse has been initialized before */
+ for (num = 0; num < ATX_FUSE_BANK_NUM; num++) {
+ if (buffer[num])
+ return RESULT_OK;
}
- /* choose rollback index type */
-#ifdef CONFIG_AVB_ATX
- if ((rollback_index_slot & kTypeMask) >> kTypeShift) {
- /* rollback index for Android Things key versions */
- rbk = &hdr.atx_rbk_tags[rollback_index_slot & ~kTypeMask];
- } else {
- /* rollback index for vbmeta */
- rbk = &hdr.rbk_tags[rollback_index_slot & ~kTypeMask];
+
+ /* calculate sha256(permanent attributes) */
+ if (permanent_attributes_sha256_hash(sha256_hash) != RESULT_OK) {
+ printf("ERROR - calculating permanent attributes SHA256 error!\n");
+ return RESULT_ERROR;
}
-#else
- rbk = &hdr.rbk_tags[rollback_index_slot];
-#endif /* CONFIG_AVB_ATX */
- extract_idx = malloc(rbk->len);
- if (extract_idx == NULL)
- return AVB_IO_RESULT_ERROR_OOM;
-
- /* read rollback_index keyblob */
- if (rpmb_read(mmc_dev, (uint8_t *)extract_idx, rbk->len, rbk->offset) != 0) {
- ERR("read rollback index error\n");
- ret = AVB_IO_RESULT_ERROR_IO;
- goto fail;
+
+ /* write first 112 bits of sha256(permanent attributes) into fuse */
+ memset(buffer, 0, sizeof(buffer));
+ memcpy(buffer, sha256_hash, ATX_HASH_LENGTH);
+ if (fsl_fuse_write(buffer, ATX_FUSE_BANK_NUM, PERMANENT_ATTRIBUTE_HASH_OFFSET)) {
+ printf("ERROR - write permanent attributes hash to fuse error\n");
+ return RESULT_ERROR;
}
-#ifdef AVB_VVDEBUG
- printf("\n----idx dump: ---\n");
- print_buffer(0, extract_idx, HEXDUMP_WIDTH, rbk->len, 0);
- printf("--- end ---\n");
-#endif
- *out_rollback_index = *extract_idx;
- DEBUGAVB("rollback_index = %" PRIu64 "\n", *out_rollback_index);
- ret = AVB_IO_RESULT_OK;
-fail:
- if (extract_idx != NULL)
- free(extract_idx);
- return ret;
-#endif /* CONFIG_IMX_TRUSTY_OS */
+ return RESULT_OK;
+#endif /* CONFIG_ARM64 */
}
-/* Sets the rollback index corresponding to the slot given by
- * |rollback_index_slot| to |rollback_index|. Returns
- * AVB_IO_RESULT_OK if the rollback index was set, otherwise an
- * error code.
- *
- * A device may have a limited amount of rollback index slots (say,
- * one or four) so may error out if |rollback_index_slot| exceeds
- * this number.
- */
-AvbIOResult fsl_write_rollback_index_rpmb(AvbOps* ops, size_t rollback_index_slot,
- uint64_t rollback_index) {
- AvbIOResult ret;
+int avb_atx_fuse_perm_attr(uint8_t *staged_buffer, uint32_t size) {
+
+ if (staged_buffer == NULL) {
+ ERR("Error. Get null staged_buffer\n");
+ return -1;
+ }
+ if (size != sizeof(AvbAtxPermanentAttributes)) {
+ ERR("Error. expect perm_attr length %u, but get %u.\n",
+ (uint32_t)sizeof(AvbAtxPermanentAttributes), size);
+ return -1;
+ }
#ifdef CONFIG_IMX_TRUSTY_OS
- if (trusty_write_rollback_index(rollback_index_slot, rollback_index)) {
- ERR("write rollback from Trusty error!");
- ret = AVB_IO_RESULT_ERROR_IO;
- } else {
- ret = AVB_IO_RESULT_OK;
+ if (trusty_write_permanent_attributes(staged_buffer, size)) {
+ ERR("Error. Failed to write permanent attributes into secure storage\n");
+ return -1;
}
- return ret;
+ else
+ return init_permanent_attributes_fuse();
#else
- kblb_hdr_t hdr;
- kblb_tag_t *rbk;
- uint64_t *plain_idx = NULL;
- struct mmc *mmc_dev;
-#ifdef CONFIG_AVB_ATX
- static const uint32_t kTypeMask = 0xF000;
- static const unsigned int kTypeShift = 12;
+ /*
+ * TODO:
+ * Need to handle this when no Trusty OS support.
+ * But now every Android Things will have Trusty OS support.
+ */
+ ERR("No Trusty OS enabled in bootloader.\n");
+ return 0;
#endif
+}
- DEBUGAVB("[rpmb] write to rollback slot: (%zu, %" PRIu64 ")\n",
- rollback_index_slot, rollback_index);
-
- assert(ops != NULL);
- /* check if the rollback index location exceed the limit */
-#ifdef CONFIG_AVB_ATX
- if ((rollback_index_slot & ~kTypeMask) >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
-#else
- if (rollback_index_slot >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS)
-#endif /* CONFIG_AVB_ATX */
- return AVB_IO_RESULT_ERROR_IO;
+int avb_atx_get_unlock_challenge(struct AvbAtxOps* atx_ops,
+ uint8_t *upload_buffer, uint32_t *upload_size)
+{
+ struct AvbAtxUnlockChallenge *buf = NULL;
+ int ret, size;
- if ((mmc_dev = get_mmc()) == NULL) {
- ERR("err get mmc device\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
- /* read the kblb header */
- if (rpmb_read(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
- ERR("read RPMB error\n");
- return AVB_IO_RESULT_ERROR_IO;
+ size = sizeof(struct AvbAtxUnlockChallenge);
+ buf = (struct AvbAtxUnlockChallenge *)malloc(size);
+ if (buf == NULL) {
+ ERR("unable to alloc memory!\n");
+ return -1;
}
- if (memcmp(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN) != 0) {
- ERR("magic not match\n");
- return AVB_IO_RESULT_ERROR_IO;
- }
- /* choose rollback index type */
-#ifdef CONFIG_AVB_ATX
- if ((rollback_index_slot & kTypeMask) >> kTypeShift) {
- /* rollback index for Android Things key versions */
- rbk = &hdr.atx_rbk_tags[rollback_index_slot & ~kTypeMask];
- } else {
- /* rollback index for vbmeta */
- rbk = &hdr.rbk_tags[rollback_index_slot & ~kTypeMask];
- }
-#else
- rbk = &hdr.rbk_tags[rollback_index_slot];
-#endif /* CONFIG_AVB_ATX */
- plain_idx = malloc(rbk->len);
- if (plain_idx == NULL)
- return AVB_IO_RESULT_ERROR_OOM;
- memset(plain_idx, 0, rbk->len);
- *plain_idx = rollback_index;
-
- /* write rollback_index keyblob */
- if (rpmb_write(mmc_dev, (uint8_t *)plain_idx, rbk->len, rbk->offset) !=
- 0) {
- ERR("write rollback index error\n");
- ret = AVB_IO_RESULT_ERROR_IO;
+ if (avb_atx_generate_unlock_challenge(atx_ops, buf) !=
+ AVB_IO_RESULT_OK) {
+ ERR("generate unlock challenge fail!\n");
+ ret = -1;
goto fail;
}
- ret = AVB_IO_RESULT_OK;
+ /* Current avbtool only accept 16 bytes random numbers as unlock
+ * challenge, need to return the whole 'AvbAtxUnlockChallenge'
+ * when avbtool is ready.
+ */
+ memcpy(upload_buffer, buf->challenge, AVB_ATX_UNLOCK_CHALLENGE_SIZE);
+ *upload_size = AVB_ATX_UNLOCK_CHALLENGE_SIZE;
+ ret = 0;
fail:
- if (plain_idx != NULL)
- free(plain_idx);
+ if (buf != NULL)
+ free(buf);
return ret;
-#endif /* CONFIG_IMX_TRUSTY_OS */
}
-#endif /* CONFIG_SPL_BUILD */
-#endif /* AVB_RPMB */
-
-#if defined(AVB_RPMB) && defined(CONFIG_AVB_ATX) && !defined(CONFIG_SPL_BUILD)
-/* Provides the key version of a key used during verification. This may be
- * useful for managing the minimum key version.
- */
-void fsl_set_key_version(AvbAtxOps* atx_ops,
- size_t rollback_index_location,
- uint64_t key_version) {
- kblb_hdr_t hdr;
- kblb_tag_t *rbk;
- uint64_t *plain_idx = NULL;
- struct mmc *mmc_dev;
- static const uint32_t kTypeMask = 0xF000;
-
- DEBUGAVB("[rpmb] write to rollback slot: (%zu, %" PRIu64 ")\n",
- rollback_index_location, key_version);
- assert(atx_ops != NULL);
+int avb_atx_verify_unlock_credential(struct AvbAtxOps* atx_ops,
+ uint8_t *staged_buffer)
+{
+ bool out_is_trusted;
+ AvbIOResult ret;
+ const AvbAtxUnlockCredential* buf = NULL;
- if ((mmc_dev = get_mmc()) == NULL) {
- ERR("err get mmc device\n");
- }
- /* read the kblb header */
- if (rpmb_read(mmc_dev, (uint8_t *)&hdr, sizeof(hdr), 0) != 0) {
- ERR("read RPMB error\n");
- }
+ buf = (const AvbAtxUnlockCredential*)staged_buffer;
+ ret = avb_atx_validate_unlock_credential(atx_ops, buf, &out_is_trusted);
+ if ((ret != AVB_IO_RESULT_OK) || (out_is_trusted != true)) {
+ ERR("validate unlock credential fail!\n");
+ return -1;
+ } else
+ return 0;
+}
- if (memcmp(hdr.magic, AVB_KBLB_MAGIC, AVB_KBLB_MAGIC_LEN) != 0) {
- ERR("magic not match\n");
+bool perm_attr_are_fused(void)
+{
+#ifdef CONFIG_IMX_TRUSTY_OS
+ AvbAtxPermanentAttributes attributes;
+ if(!trusty_read_permanent_attributes((uint8_t *)(&attributes),
+ sizeof(AvbAtxPermanentAttributes))) {
+ return true;
+ } else {
+ ERR("No perm-attr fused, please fuse your perm-attr first!.\n");
+ return false;
}
+#else
+ /* We hard code the perm-attr if trusty is not enabled. */
+ return true;
+#endif
+}
- /* rollback index for Android Things key versions */
- rbk = &hdr.atx_rbk_tags[rollback_index_location & ~kTypeMask];
-
- plain_idx = malloc(rbk->len);
- if (plain_idx == NULL)
- printf("\nError! allocate memory fail!\n");
- memset(plain_idx, 0, rbk->len);
- *plain_idx = key_version;
+bool at_unlock_vboot_is_disabled(void)
+{
+ uint32_t unlock_vboot_status;
- /* write rollback_index keyblob */
- if (rpmb_write(mmc_dev, (uint8_t *)plain_idx, rbk->len, rbk->offset) !=
- 0) {
- ERR("write rollback index error\n");
- goto fail;
+ if (fsl_fuse_read(&unlock_vboot_status, 1,
+ UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) {
+ printf("Read at unlock vboot status error!\n");
+ return false;
}
-fail:
- if (plain_idx != NULL)
- free(plain_idx);
-}
-#endif /* AVB_RPMB && CONFIG_AVB_ATX */
-#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT)
-
-extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
+ if (unlock_vboot_status & (1 << UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT))
+ return true;
+ else
+ return false;
+}
-#ifdef CONFIG_SPL_BUILD
-int check_rpmb_blob(struct mmc *mmc)
+int at_disable_vboot_unlock(void)
{
- int ret = 0;
- char original_part;
- struct keyslot_package kp;
+ uint32_t unlock_vboot_status = 0;
- read_keyslot_package(&kp);
- if (strcmp(kp.magic, KEYPACK_MAGIC)) {
- printf("keyslot package magic error, do nothing here!\n");
- return 0;
+ /* Read the status first */
+ if (fsl_fuse_read(&unlock_vboot_status, 1,
+ UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) {
+ ERR("Read unlock vboot status error!\n");
+ return -1;
}
- /* If keyslot package valid, copy it to secure memory */
- fill_secure_keyslot_package(&kp);
- /* switch to boot1 partition. */
- original_part = mmc->block_dev.hwpart;
- if (mmc_switch_part(mmc, KEYSLOT_HWPARTITION_ID) != 0) {
- printf("ERROR - can't switch to boot1 partition! \n");
- ret = -1;
- goto fail;
- } else
- mmc->block_dev.hwpart = KEYSLOT_HWPARTITION_ID;
- /* write power-on write protection for boot1 partition. */
- if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) {
- printf("ERROR - unable to set power-on write protection!\n");
- ret = -1;
- goto fail;
- }
-fail:
- /* return to original partition. */
- if (mmc->block_dev.hwpart != original_part) {
- if (mmc_switch_part(mmc, original_part) != 0)
- return -1;
- mmc->block_dev.hwpart = original_part;
+ /* Set the disable unlock vboot bit */
+ unlock_vboot_status |= (1 << UNLOCK_VBOOT_STATUS_OFFSET_IN_BIT);
+
+ /* Write disable unlock vboot bit to fuse */
+ if (fsl_fuse_write(&unlock_vboot_status, 1,
+ UNLOCK_VBOOT_STATUS_OFFSET_IN_WORD)) {
+ ERR("Write unlock vboot status fail!\n");
+ return -1;
}
- return ret;
+ return 0;
}
-#else /* CONFIG_SPL_BUILD */
+#endif /* CONFIG_AVB_ATX */
+
+#if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT)
bool rpmbkey_is_set(void)
{
int mmcc;
@@ -1715,5 +1129,5 @@ fail:
return ret;
}
+#endif /* CONFIG_IMX_TRUSTY_OS && CONFIG_ANDROID_AUTO_SUPPORT */
#endif /* CONFIG_SPL_BUILD */
-#endif
diff --git a/lib/avb/fsl/fsl_avbkey.h b/lib/avb/fsl/fsl_avbkey.h
index 863d8b1dbf..ed497a99cb 100644
--- a/lib/avb/fsl/fsl_avbkey.h
+++ b/lib/avb/fsl/fsl_avbkey.h
@@ -44,6 +44,15 @@ struct bl_rbindex_package {
#define RPMB_KEY_MAGIC "RPMB"
#endif
+#ifdef CONFIG_AVB_ATX
+#define ATX_FUSE_BANK_NUM 4
+#define ATX_FUSE_BANK_MASK 0xFFFF
+#define ATX_HASH_LENGTH 14
+#endif
+
+#define RESULT_ERROR -1
+#define RESULT_OK 0
+
struct kblb_tag {
uint32_t flag;
uint32_t offset;
@@ -59,7 +68,7 @@ struct kblb_hdr {
*/
#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
kblb_tag_t bootloader_rbk_tags;
-#else
+#endif
/* public key keyblb tag */
kblb_tag_t pubk_tag;
/* vbmeta rollback index keyblb tag */
@@ -68,7 +77,6 @@ struct kblb_hdr {
/* Android Things key versions rollback index keyblb tag */
kblb_tag_t atx_rbk_tags[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS];
#endif
-#endif
};
typedef struct kblb_hdr kblb_hdr_t;
@@ -93,4 +101,8 @@ int rpmb_write(struct mmc *mmc, uint8_t *buffer, size_t num_bytes,
int check_rpmb_blob(struct mmc *mmc);
bool rpmbkey_is_set(void);
+int fsl_fuse_write(const uint32_t *buffer, uint32_t length, uint32_t offset);
+int fsl_fuse_read(uint32_t *buffer, uint32_t length, uint32_t offset);
+int permanent_attributes_sha256_hash(unsigned char* output);
+struct mmc *get_mmc(void);
#endif