Commit d4a0dbd9a467984d7f4a4861213298e2b95a3327
Committed by
faqiang.zhu
1 parent
22ab111509
Exists in
smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga
and in
5 other branches
[iot] Support authenticated unlock
Add fastboot commands "fastboot oem at-get-vboot-unlock-challenge" and "fastboot oem at-unlock-vboot" to support the authenticated unlock feature for Android Things devices. Use software random numbers generator to generate the 16 bytes random challenge, it should be replaced with hardware encrypted random generator when the TEE part is ready. Test: Generate unlock challenge by: ./avbtool make_atx_unlock_credential --output=atx_unlock_credential.bin --intermediate_key_certificate=atx_pik_certificate.bin --unlock_key_certificate=atx_puk_certificate.bin --challenge=my_generated_challenge.bin --unlock_key=testkey_atx_puk.pem validated the unlock credential successfully on imx7d_pico and AIY. Change-Id: I4b8cee87c9e96924169479b65020a081136681f6 Signed-off-by: Ji Luo <ji.luo@nxp.com>
Showing 11 changed files with 144 additions and 10 deletions Side-by-side Diff
- board/freescale/imx8mq_phanbell/imx8m_phanbell.c
- configs/imx8mq_phanbell_androidthings_defconfig
- configs/imx8mq_phanbell_androidthings_uuu_defconfig
- configs/pico-imx7d-trusty_defconfig
- configs/pico-imx7d_defconfig
- drivers/usb/gadget/f_fastboot.c
- include/configs/imx8mq_evk_androidthings.h
- include/fsl_avb.h
- include/fsl_fastboot.h
- lib/Kconfig
- lib/avb/fsl/fsl_avbkey.c
board/freescale/imx8mq_phanbell/imx8m_phanbell.c
... | ... | @@ -368,8 +368,8 @@ |
368 | 368 | int board_late_init(void) |
369 | 369 | { |
370 | 370 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
371 | - setenv("board_name", "Phanbell"); | |
372 | - setenv("board_rev", "iMX8MQ"); | |
371 | + env_set("board_name", "Phanbell"); | |
372 | + env_set("board_rev", "iMX8MQ"); | |
373 | 373 | #endif |
374 | 374 | |
375 | 375 | #ifdef CONFIG_ENV_IS_IN_MMC |
configs/imx8mq_phanbell_androidthings_defconfig
configs/imx8mq_phanbell_androidthings_uuu_defconfig
configs/pico-imx7d-trusty_defconfig
configs/pico-imx7d_defconfig
drivers/usb/gadget/f_fastboot.c
... | ... | @@ -1640,10 +1640,11 @@ |
1640 | 1640 | .read_permanent_attributes = fsl_read_permanent_attributes, |
1641 | 1641 | .read_permanent_attributes_hash = fsl_read_permanent_attributes_hash, |
1642 | 1642 | #ifdef CONFIG_IMX_TRUSTY_OS |
1643 | - .set_key_version = fsl_write_rollback_index_rpmb | |
1643 | + .set_key_version = fsl_write_rollback_index_rpmb, | |
1644 | 1644 | #else |
1645 | - .set_key_version = fsl_set_key_version | |
1645 | + .set_key_version = fsl_set_key_version, | |
1646 | 1646 | #endif |
1647 | + .get_random = fsl_get_random | |
1647 | 1648 | }; |
1648 | 1649 | #endif |
1649 | 1650 | static AvbOps fsl_avb_ops = { |
... | ... | @@ -3320,6 +3321,27 @@ |
3320 | 3321 | strcpy(response, "FAILInternal error!"); |
3321 | 3322 | else |
3322 | 3323 | strcpy(response, "OKAY"); |
3324 | + } else if (endswith(cmd, FASTBOOT_AT_GET_UNLOCK_CHALLENGE)) { | |
3325 | + if (avb_atx_get_unlock_challenge(fsl_avb_ops.atx_ops, | |
3326 | + interface.transfer_buffer, &download_bytes)) | |
3327 | + strcpy(response, "FAILInternal error!"); | |
3328 | + else | |
3329 | + strcpy(response, "OKAY"); | |
3330 | + } else if (endswith(cmd, FASTBOOT_AT_UNLOCK_VBOOT)) { | |
3331 | +#ifdef CONFIG_AT_AUTHENTICATE_UNLOCK | |
3332 | + if (avb_atx_verify_unlock_credential(fsl_avb_ops.atx_ops, | |
3333 | + interface.transfer_buffer)) | |
3334 | + strcpy(response, "FAILIncorrect unlock credential!"); | |
3335 | + else { | |
3336 | +#endif | |
3337 | + status = do_fastboot_unlock(true); | |
3338 | + if (status != FASTBOOT_LOCK_ERROR) | |
3339 | + strcpy(response, "OKAY"); | |
3340 | + else | |
3341 | + strcpy(response, "FAILunlock device failed."); | |
3342 | +#ifdef CONFIG_AT_AUTHENTICATE_UNLOCK | |
3343 | + } | |
3344 | +#endif | |
3323 | 3345 | } |
3324 | 3346 | #endif /* CONFIG_AVB_ATX */ |
3325 | 3347 | #ifdef CONFIG_ANDROID_THINGS_SUPPORT |
3326 | 3348 | |
... | ... | @@ -3366,11 +3388,18 @@ |
3366 | 3388 | strcpy(response, "OKAY"); |
3367 | 3389 | } else if (endswith(cmd, "unlock")) { |
3368 | 3390 | printf("flashing unlock.\n"); |
3391 | +#ifdef CONFIG_AVB_ATX | |
3392 | + /* We should do nothing here For Android Things which | |
3393 | + * enables the authenticated unlock feature. | |
3394 | + */ | |
3395 | + strcpy(response, "OKAY"); | |
3396 | +#else | |
3369 | 3397 | status = do_fastboot_unlock(false); |
3370 | 3398 | if (status != FASTBOOT_LOCK_ERROR) |
3371 | 3399 | strcpy(response, "OKAY"); |
3372 | 3400 | else |
3373 | 3401 | strcpy(response, "FAILunlock device failed."); |
3402 | +#endif | |
3374 | 3403 | } else if (endswith(cmd, "lock")) { |
3375 | 3404 | printf("flashing lock.\n"); |
3376 | 3405 | status = do_fastboot_lock(); |
... | ... | @@ -3438,7 +3467,8 @@ |
3438 | 3467 | /* initialize the response buffer */ |
3439 | 3468 | fb_response_str = response; |
3440 | 3469 | |
3441 | -#ifdef CONFIG_FASTBOOT_LOCK | |
3470 | + /* Always enable image flash for Android Things. */ | |
3471 | +#if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) | |
3442 | 3472 | /* for imx8 boot from USB, lock status can be ignored for uuu.*/ |
3443 | 3473 | if (!(is_imx8() || is_imx8m()) || !(is_boot_from_usb())) { |
3444 | 3474 | int status; |
... | ... | @@ -3462,6 +3492,7 @@ |
3462 | 3492 | fastboot_fail("no flash device defined"); |
3463 | 3493 | |
3464 | 3494 | rx_process_flash(cmd); |
3495 | + | |
3465 | 3496 | #ifdef CONFIG_FASTBOOT_LOCK |
3466 | 3497 | if (strncmp(cmd, "gpt", 3) == 0) { |
3467 | 3498 | int gpt_valid = 0; |
... | ... | @@ -3497,7 +3528,7 @@ |
3497 | 3528 | /* initialize the response buffer */ |
3498 | 3529 | fb_response_str = response; |
3499 | 3530 | |
3500 | -#ifdef CONFIG_FASTBOOT_LOCK | |
3531 | +#if defined(CONFIG_FASTBOOT_LOCK) && !defined(CONFIG_AVB_ATX) | |
3501 | 3532 | FbLockState status; |
3502 | 3533 | status = fastboot_get_lock_stat(); |
3503 | 3534 | if (status == FASTBOOT_LOCK) { |
include/configs/imx8mq_evk_androidthings.h
... | ... | @@ -10,7 +10,6 @@ |
10 | 10 | #define CONFIG_CMD_READ |
11 | 11 | |
12 | 12 | #define CONFIG_ANDROID_AB_SUPPORT |
13 | -#define CONFIG_AVB_SUPPORT | |
14 | 13 | #define CONFIG_SUPPORT_EMMC_RPMB |
15 | 14 | #define CONFIG_SYSTEM_RAMDISK_SUPPORT |
16 | 15 | #define CONFIG_AVB_FUSE_BANK_SIZEW 0 |
... | ... | @@ -51,6 +50,10 @@ |
51 | 50 | #define TEE_LOAD_ADDR_1G 0x7e000000 |
52 | 51 | #define TEE_LOAD_ADDR_3G 0xfe000000 |
53 | 52 | |
53 | + | |
54 | +#define KEYSLOT_HWPARTITION_ID 2 | |
55 | +#define KEYSLOT_BLKS 0x1FFF | |
56 | + | |
54 | 57 | #ifdef CONFIG_SPL_BUILD |
55 | 58 | |
56 | 59 | #define CONFIG_SPL_SHA256 |
... | ... | @@ -64,8 +67,6 @@ |
64 | 67 | #define BOOTLOADER_RBIDX_START 0x1F000 |
65 | 68 | #define BOOTLOADER_RBIDX_LEN 0x08 |
66 | 69 | #define BOOTLOADER_RBIDX_INITVAL 0 |
67 | -#define KEYSLOT_HWPARTITION_ID 2 | |
68 | -#define KEYSLOT_BLKS 0x1FFF | |
69 | 70 | #endif |
70 | 71 | |
71 | 72 | #else |
include/fsl_avb.h
... | ... | @@ -236,12 +236,27 @@ |
236 | 236 | AvbSlotVerifyFlags flags, |
237 | 237 | AvbHashtreeErrorMode hashtree_error_mode, |
238 | 238 | AvbSlotVerifyData** out_data); |
239 | +/* Generates |num_bytes| random bytes and stores them in |output|, | |
240 | + * which must point to a buffer large enough to store the bytes. | |
241 | + * | |
242 | + * Returns AVB_IO_RESULT_OK on success, otherwise an error code. | |
243 | + */ | |
244 | +AvbIOResult fsl_get_random(AvbAtxOps* atx_ops, | |
245 | + size_t num_bytes, | |
246 | + uint8_t* output); | |
239 | 247 | |
240 | 248 | /* Program ATX perm_attr into RPMB partition */ |
241 | 249 | int avb_atx_fuse_perm_attr(uint8_t *staged_buffer, uint32_t size); |
242 | 250 | |
243 | 251 | /* Initialize rpmb key with the staged key */ |
244 | 252 | int fastboot_set_rpmb_key(uint8_t *staged_buf, uint32_t key_size); |
253 | + | |
254 | +/* Generate ATX unlock challenge */ | |
255 | +int avb_atx_get_unlock_challenge(struct AvbAtxOps* atx_ops, | |
256 | + uint8_t *upload_buffer, uint32_t *size); | |
257 | +/* Verify ATX unlock credential */ | |
258 | +int avb_atx_verify_unlock_credential(struct AvbAtxOps* atx_ops, | |
259 | + uint8_t *staged_buffer); | |
245 | 260 | |
246 | 261 | #endif /* __FSL_AVB_H__ */ |
include/fsl_fastboot.h
... | ... | @@ -96,6 +96,8 @@ |
96 | 96 | #define FASTBOOT_BOOTLOADER_VBOOT_KEY "fuse at-bootloader-vboot-key" |
97 | 97 | #ifdef CONFIG_AVB_ATX |
98 | 98 | #define FASTBOOT_AVB_AT_PERM_ATTR "fuse at-perm-attr" |
99 | +#define FASTBOOT_AT_UNLOCK_VBOOT "at-unlock-vboot" | |
100 | +#define FASTBOOT_AT_GET_UNLOCK_CHALLENGE "at-get-vboot-unlock-challenge" | |
99 | 101 | #endif /* CONFIG_AVB_ATX */ |
100 | 102 | #endif /* CONFIG_ANDROID_THINGS_SUPPORT */ |
101 | 103 |
lib/Kconfig
lib/avb/fsl/fsl_avbkey.c
... | ... | @@ -235,6 +235,54 @@ |
235 | 235 | #endif |
236 | 236 | } |
237 | 237 | |
238 | +int avb_atx_get_unlock_challenge(struct AvbAtxOps* atx_ops, | |
239 | + uint8_t *upload_buffer, uint32_t *upload_size) | |
240 | +{ | |
241 | + struct AvbAtxUnlockChallenge *buf = NULL; | |
242 | + int ret, size; | |
243 | + | |
244 | + size = sizeof(struct AvbAtxUnlockChallenge); | |
245 | + buf = (struct AvbAtxUnlockChallenge *)malloc(size); | |
246 | + if (buf == NULL) { | |
247 | + ERR("unable to alloc memory!\n"); | |
248 | + return -1; | |
249 | + } | |
250 | + | |
251 | + if (avb_atx_generate_unlock_challenge(atx_ops, buf) != | |
252 | + AVB_IO_RESULT_OK) { | |
253 | + ERR("generate unlock challenge fail!\n"); | |
254 | + ret = -1; | |
255 | + goto fail; | |
256 | + } | |
257 | + /* Current avbtool only accept 16 bytes random numbers as unlock | |
258 | + * challenge, need to return the whole 'AvbAtxUnlockChallenge' | |
259 | + * when avbtool is ready. | |
260 | + */ | |
261 | + memcpy(upload_buffer, buf->challenge, AVB_ATX_UNLOCK_CHALLENGE_SIZE); | |
262 | + *upload_size = AVB_ATX_UNLOCK_CHALLENGE_SIZE; | |
263 | + ret = 0; | |
264 | +fail: | |
265 | + if (buf != NULL) | |
266 | + free(buf); | |
267 | + return ret; | |
268 | +} | |
269 | + | |
270 | +int avb_atx_verify_unlock_credential(struct AvbAtxOps* atx_ops, | |
271 | + uint8_t *staged_buffer) | |
272 | +{ | |
273 | + bool out_is_trusted; | |
274 | + AvbIOResult ret; | |
275 | + const AvbAtxUnlockCredential* buf = NULL; | |
276 | + | |
277 | + buf = (const AvbAtxUnlockCredential*)staged_buffer; | |
278 | + ret = avb_atx_validate_unlock_credential(atx_ops, buf, &out_is_trusted); | |
279 | + if ((ret != AVB_IO_RESULT_OK) || (out_is_trusted != true)) { | |
280 | + ERR("validate unlock credential fail!\n"); | |
281 | + return -1; | |
282 | + } else | |
283 | + return 0; | |
284 | +} | |
285 | + | |
238 | 286 | /* Reads permanent |attributes| data. There are no restrictions on where this |
239 | 287 | * data is stored. On success, returns AVB_IO_RESULT_OK and populates |
240 | 288 | * |attributes|. |
... | ... | @@ -304,6 +352,33 @@ |
304 | 352 | #endif /* CONFIG_ARM64 */ |
305 | 353 | } |
306 | 354 | |
355 | + /* Generates |num_bytes| random bytes and stores them in |output|, | |
356 | + * which must point to a buffer large enough to store the bytes. | |
357 | + * | |
358 | + * Returns AVB_IO_RESULT_OK on success, otherwise an error code. | |
359 | + */ | |
360 | +AvbIOResult fsl_get_random(AvbAtxOps* atx_ops, | |
361 | + size_t num_bytes, | |
362 | + uint8_t* output) | |
363 | +{ | |
364 | + uint32_t num = 0; | |
365 | + uint32_t i; | |
366 | + | |
367 | + if (output == NULL) { | |
368 | + ERR("Output buffer is NULL!\n"); | |
369 | + return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE; | |
370 | + } | |
371 | + | |
372 | + /* set the seed as device boot time. */ | |
373 | + srand((uint32_t)get_timer(0)); | |
374 | + for (i = 0; i < num_bytes; i++) { | |
375 | + num = rand() % 256; | |
376 | + output[i] = (uint8_t)num; | |
377 | + } | |
378 | + | |
379 | + return AVB_IO_RESULT_OK; | |
380 | +} | |
381 | + | |
307 | 382 | #endif /* CONFIG_AVB_ATX */ |
308 | 383 | #endif /* CONFIG_SPL_BUILD */ |
309 | 384 | |
... | ... | @@ -1386,7 +1461,6 @@ |
1386 | 1461 | if (plain_idx != NULL) |
1387 | 1462 | free(plain_idx); |
1388 | 1463 | } |
1389 | - | |
1390 | 1464 | #endif /* AVB_RPMB && CONFIG_AVB_ATX */ |
1391 | 1465 | |
1392 | 1466 | #if defined(CONFIG_IMX_TRUSTY_OS) && defined(CONFIG_ANDROID_AUTO_SUPPORT) |