From 7e0728dfca6d4f27c07434c9a6af468c966046a4 Mon Sep 17 00:00:00 2001 From: Mary Ruthven Date: Fri, 18 Dec 2015 11:16:02 -0800 Subject: vboot: Change VbExEc implementations to support RO update This change will be used to support EC-RO software sync by allowing for access to the readonly region of firmware. Currently only the writable section is accessed by vboot using VB_SELECT_FIRMWARE_A and B. BUG=chrome-os-partner:48703 BRANCH=none TEST=built on jerry and check that the RO hash can be read and the image can be updated. CQ-DEPEND=CL:319185,CL:320425,CL:320598 Change-Id: Ic3942d86b65da3123798cfd11a78056f5dab6699 Signed-off-by: Mary Ruthven Reviewed-on: https://chromium-review.googlesource.com/319213 Reviewed-by: Randall Spangler --- firmware/include/vboot_api.h | 25 ++++++++++++++----------- firmware/lib/vboot_api_kernel.c | 37 ++++++++++++++++++------------------- firmware/stub/vboot_api_stub.c | 16 +++++++++------- tests/vboot_api_kernel3_tests.c | 16 +++++++++------- 4 files changed, 50 insertions(+), 44 deletions(-) diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h index 95ef21d8..4b7f1798 100644 --- a/firmware/include/vboot_api.h +++ b/firmware/include/vboot_api.h @@ -891,34 +891,37 @@ VbError_t VbExEcJumpToRW(int devidx); VbError_t VbExEcDisableJump(int devidx); /** - * Read the SHA-256 hash of the rewriteable EC image. + * Read the SHA-256 hash of the selected EC image. */ -VbError_t VbExEcHashRW(int devidx, const uint8_t **hash, int *hash_size); +VbError_t VbExEcHashImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t **hash, int *hash_size); /** * Get the expected contents of the EC image associated with the main firmware * specified by the "select" argument. */ -VbError_t VbExEcGetExpectedRW(int devidx, enum VbSelectFirmware_t select, - const uint8_t **image, int *image_size); +VbError_t VbExEcGetExpectedImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t **image, int *image_size); /** * Read the SHA-256 hash of the expected contents of the EC image associated * with the main firmware specified by the "select" argument. */ -VbError_t VbExEcGetExpectedRWHash(int devidx, enum VbSelectFirmware_t select, - const uint8_t **hash, int *hash_size); +VbError_t VbExEcGetExpectedImageHash(int devidx, enum VbSelectFirmware_t select, + const uint8_t **hash, int *hash_size); /** - * Update the EC rewritable image. + * Update the selected EC image. */ -VbError_t VbExEcUpdateRW(int devidx, const uint8_t *image, int image_size); +VbError_t VbExEcUpdateImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t *image, int image_size); /** - * Lock the EC code to prevent updates until the EC is rebooted. - * Subsequent calls to VbExEcUpdateRW() this boot will fail. + * Lock the selected EC code to prevent updates until the EC is rebooted. + * Subsequent calls to VbExEcUpdateImage() with the same region this boot will + * fail. */ -VbError_t VbExEcProtectRW(int devidx); +VbError_t VbExEcProtect(int devidx, enum VbSelectFirmware_t select); /** * Info the EC of the boot mode selected by the AP. diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index 2bf183b3..903055b7 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -639,16 +639,16 @@ VbError_t VbBootRecovery(VbCommonParams *cparams, LoadKernelParams *p) } /** - * Wrapper around VbExEcProtectRW() which sets recovery reason on error. + * Wrapper around VbExEcProtect() which sets recovery reason on error. */ -static VbError_t EcProtectRW(int devidx) +static VbError_t EcProtect(int devidx, enum VbSelectFirmware_t select) { - int rv = VbExEcProtectRW(devidx); + int rv = VbExEcProtect(devidx, select); if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) { - VBDEBUG(("VbExEcProtectRW() needs reboot\n")); + VBDEBUG(("VbExEcProtect() needs reboot\n")); } else if (rv != VBERROR_SUCCESS) { - VBDEBUG(("VbExEcProtectRW() returned %d\n", rv)); + VBDEBUG(("VbExEcProtect() returned %d\n", rv)); VbSetRecoveryRequest(VBNV_RECOVERY_EC_PROTECT); } return rv; @@ -658,6 +658,7 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) { VbSharedDataHeader *shared = (VbSharedDataHeader *)cparams->shared_data_blob; + enum VbSelectFirmware_t rw; int in_rw = 0; int rv; const uint8_t *ec_hash = NULL; @@ -671,6 +672,8 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) int i; VBDEBUG(("VbEcSoftwareSync(devidx=%d)\n", devidx)); + rw = shared->firmware_index ? VB_SELECT_FIRMWARE_B : + VB_SELECT_FIRMWARE_A; /* Determine whether the EC is in RO or RW */ rv = VbExEcRunningRW(devidx, &in_rw); @@ -719,7 +722,7 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) } /* Protect the RW flash and stay in EC-RO */ - rv = EcProtectRW(devidx); + rv = EcProtect(devidx, rw); if (rv != VBERROR_SUCCESS) return rv; @@ -736,16 +739,16 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) } /* Get hash of EC-RW */ - rv = VbExEcHashRW(devidx, &ec_hash, &ec_hash_size); + rv = VbExEcHashImage(devidx, rw, &ec_hash, &ec_hash_size); if (rv) { VBDEBUG(("VbEcSoftwareSync() - " - "VbExEcHashRW() returned %d\n", rv)); + "VbExEcHashImage() returned %d\n", rv)); VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH_FAILED); return VBERROR_EC_REBOOT_TO_RO_REQUIRED; } if (ec_hash_size != SHA256_DIGEST_SIZE) { VBDEBUG(("VbEcSoftwareSync() - " - "VbExEcHashRW() says size %d, not %d\n", + "VbExEcHashImage() says size %d, not %d\n", ec_hash_size, SHA256_DIGEST_SIZE)); VbSetRecoveryRequest(VBNV_RECOVERY_EC_HASH_SIZE); return VBERROR_EC_REBOOT_TO_RO_REQUIRED; @@ -761,9 +764,7 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) * RO_NORMAL, so we know that the BIOS must be RW-A or RW-B, and * therefore the EC must match. */ - rv = VbExEcGetExpectedRWHash(devidx, shared->firmware_index ? - VB_SELECT_FIRMWARE_B : VB_SELECT_FIRMWARE_A, - &rw_hash, &rw_hash_size); + rv = VbExEcGetExpectedImageHash(devidx, rw, &rw_hash, &rw_hash_size); if (rv == VBERROR_EC_GET_EXPECTED_HASH_FROM_IMAGE) { /* @@ -799,10 +800,8 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) */ if (need_update || !rw_hash) { /* Get expected EC-RW image */ - rv = VbExEcGetExpectedRW(devidx, shared->firmware_index ? - VB_SELECT_FIRMWARE_B : - VB_SELECT_FIRMWARE_A, - &expected, &expected_size); + rv = VbExEcGetExpectedImage(devidx, rw, &expected, + &expected_size); if (rv) { VBDEBUG(("VbEcSoftwareSync() - " "VbExEcGetExpectedRW() returned %d\n", rv)); @@ -891,11 +890,11 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) VbDisplayScreen(cparams, VB_SCREEN_WAIT, 0, &vnc); } - rv = VbExEcUpdateRW(devidx, expected, expected_size); + rv = VbExEcUpdateImage(devidx, rw, expected, expected_size); if (rv != VBERROR_SUCCESS) { VBDEBUG(("VbEcSoftwareSync() - " - "VbExEcUpdateRW() returned %d\n", rv)); + "VbExEcUpdateImage() returned %d\n", rv)); /* * The EC may know it needs a reboot. It may need to @@ -919,7 +918,7 @@ VbError_t VbEcSoftwareSync(int devidx, VbCommonParams *cparams) } /* Protect EC-RW flash */ - rv = EcProtectRW(devidx); + rv = EcProtect(devidx, rw); if (rv != VBERROR_SUCCESS) return rv; diff --git a/firmware/stub/vboot_api_stub.c b/firmware/stub/vboot_api_stub.c index 23e3dfbe..2299a033 100644 --- a/firmware/stub/vboot_api_stub.c +++ b/firmware/stub/vboot_api_stub.c @@ -115,7 +115,8 @@ VbError_t VbExEcDisableJump(int devidx) #define SHA256_HASH_SIZE 32 -VbError_t VbExEcHashRW(int devidx, const uint8_t **hash, int *hash_size) +VbError_t VbExEcHashImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t **hash, int *hash_size) { static const uint8_t fake_hash[32] = {1, 2, 3, 4}; @@ -124,8 +125,8 @@ VbError_t VbExEcHashRW(int devidx, const uint8_t **hash, int *hash_size) return VBERROR_SUCCESS; } -VbError_t VbExEcGetExpectedRW(int devidx, enum VbSelectFirmware_t select, - const uint8_t **image, int *image_size) +VbError_t VbExEcGetExpectedImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t **image, int *image_size) { static uint8_t fake_image[64] = {5, 6, 7, 8}; *image = fake_image; @@ -133,8 +134,8 @@ VbError_t VbExEcGetExpectedRW(int devidx, enum VbSelectFirmware_t select, return VBERROR_SUCCESS; } -VbError_t VbExEcGetExpectedRWHash(int devidx, enum VbSelectFirmware_t select, - const uint8_t **hash, int *hash_size) +VbError_t VbExEcGetExpectedImageHash(int devidx, enum VbSelectFirmware_t select, + const uint8_t **hash, int *hash_size) { static const uint8_t fake_hash[32] = {1, 2, 3, 4}; @@ -143,12 +144,13 @@ VbError_t VbExEcGetExpectedRWHash(int devidx, enum VbSelectFirmware_t select, return VBERROR_SUCCESS; } -VbError_t VbExEcUpdateRW(int devidx, const uint8_t *image, int image_size) +VbError_t VbExEcUpdateImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t *image, int image_size) { return VBERROR_SUCCESS; } -VbError_t VbExEcProtectRW(int devidx) +VbError_t VbExEcProtect(int devidx, enum VbSelectFirmware_t select) { return VBERROR_SUCCESS; } diff --git a/tests/vboot_api_kernel3_tests.c b/tests/vboot_api_kernel3_tests.c index 32a35eca..a4c5ea77 100644 --- a/tests/vboot_api_kernel3_tests.c +++ b/tests/vboot_api_kernel3_tests.c @@ -123,7 +123,7 @@ VbError_t VbExEcRunningRW(int devidx, int *in_rw) return in_rw_retval; } -VbError_t VbExEcProtectRW(int devidx) +VbError_t VbExEcProtect(int devidx, enum VbSelectFirmware_t select) { ec_protected = 1; return protect_retval; @@ -140,15 +140,16 @@ VbError_t VbExEcJumpToRW(int devidx) return run_retval; } -VbError_t VbExEcHashRW(int devidx, const uint8_t **hash, int *hash_size) +VbError_t VbExEcHashImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t **hash, int *hash_size) { *hash = mock_ec_hash; *hash_size = mock_ec_hash_size; return mock_ec_hash_size ? VBERROR_SUCCESS : VBERROR_SIMULATED; } -VbError_t VbExEcGetExpectedRW(int devidx, enum VbSelectFirmware_t select, - const uint8_t **image, int *image_size) +VbError_t VbExEcGetExpectedImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t **image, int *image_size) { static uint8_t fake_image[64] = {5, 6, 7, 8}; *image = fake_image; @@ -156,8 +157,8 @@ VbError_t VbExEcGetExpectedRW(int devidx, enum VbSelectFirmware_t select, return get_expected_retval; } -VbError_t VbExEcGetExpectedRWHash(int devidx, enum VbSelectFirmware_t select, - const uint8_t **hash, int *hash_size) +VbError_t VbExEcGetExpectedImageHash(int devidx, enum VbSelectFirmware_t select, + const uint8_t **hash, int *hash_size) { *hash = want_ec_hash; *hash_size = want_ec_hash_size; @@ -174,7 +175,8 @@ uint8_t *internal_SHA256(const uint8_t *data, uint64_t len, uint8_t *digest) return digest; } -VbError_t VbExEcUpdateRW(int devidx, const uint8_t *image, int image_size) +VbError_t VbExEcUpdateImage(int devidx, enum VbSelectFirmware_t select, + const uint8_t *image, int image_size) { ec_updated = 1; return update_retval; -- cgit v1.2.1