diff options
author | Luo Ji <ji.luo@nxp.com> | 2018-11-21 15:55:55 +0800 |
---|---|---|
committer | Luo Ji <ji.luo@nxp.com> | 2018-11-22 11:02:09 +0800 |
commit | f39aa82a3dbcab9ac0807b794e524c9226fdf69a (patch) | |
tree | 3d09f5c426dace1f5e6a00ecddf26652cbbba7f3 /lib | |
parent | e26db8caf2c7ed554a3496df3b90f9efcb76cf5f (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/Makefile | 3 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_atx_attributes.c | 145 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_atx_attributes.h | 142 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_avb.c | 392 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_avbkey.c | 1588 | ||||
-rw-r--r-- | lib/avb/fsl/fsl_avbkey.h | 16 |
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 |