vboot: ec: Store vboot hash for EC image in a separate file
authorJulius Werner <jwerner@chromium.org>
Fri, 27 May 2016 23:33:04 +0000 (16:33 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Fri, 3 Jun 2016 14:09:33 +0000 (07:09 -0700)
CBFS attributes are mostly useful for uses within CBFS itself, such as
the transparent compression. Using the CBFS hash attribute for vboot
causes multiple problems: it forces us to use hashes that CBFS can
understand and generate on its own (whereas for some of our newer PD
chips we'd like to feed vboot a "hash" that's not really a hash at all,
but just a version number), and it prevents us from compressing the EC
images in CBFS (since the CBFS hash attribute was originally designed
for verification and thus always hashes the compressed data). Things
will become easier if we just split these two distinct things apart.

This patch instead just assumes that for every EC image file X, there is
also a file X.hash which contains the vboot hash for it (e.g.
"ecrw.hash"). When vboot asks us for the hash we look up this hash file,
and when it asks us for the full image we look up the normal image file.
The hashes will be precomputed by the build system in a way that allows
customization per chip type.

CQ-DEPEND=CL:348054
BRANCH=None
BUG=chrome-os-partner:53780
TEST=Forced software sync on Oak in multiple scenarios.

Change-Id: I3bfcc8eaa54c4559fe7d4c28dd74f030ebc8455c
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/348061
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
src/vboot/callbacks/ec.c

index fb40050..47859da 100644 (file)
 #include "image/index.h"
 #include "vboot/util/flag.h"
 
+#define _EC_FILENAME(devidx, select, suffix) \
+       (select == VB_SELECT_FIRMWARE_READONLY ? "ecro" suffix : \
+        (devidx == 0 ? "ecrw" suffix : "pdrw" suffix))
+#define EC_IMAGE_FILENAME(devidx, select) _EC_FILENAME(devidx, select, "")
+#define EC_HASH_FILENAME(devidx, select) _EC_FILENAME(devidx, select, ".hash")
 
 static struct cbfs_media *ro_cbfs;
-/* Returns the CBFS filename for EC firmware images based on the device index
- * passed in from vboot.
- */
-static const char *get_fw_filename(int devidx, int select)
-{
-       if (select == VB_SELECT_FIRMWARE_READONLY)
-               return "ecro";
-       return devidx == 0 ? "ecrw" : "pdrw";
-}
 
-static struct cbfs_handle *find_file_in_cbfs(
-       const char *filename, enum VbSelectFirmware_t select)
+static void *get_file_from_cbfs(
+       const char *filename, enum VbSelectFirmware_t select, size_t *size)
 {
        if (!IS_ENABLED(CONFIG_DRIVER_CBFS_FLASH))
                return NULL;
@@ -54,38 +50,13 @@ static struct cbfs_handle *find_file_in_cbfs(
                printf("Trying to locate '%s' in RO CBFS\n", filename);
                if (ro_cbfs == NULL)
                        ro_cbfs = cbfs_ro_media();
-               return cbfs_get_handle(ro_cbfs, filename);
+               return cbfs_get_file_content(ro_cbfs, filename,
+                                            CBFS_TYPE_RAW, size);
        }
 
        printf("Trying to locate '%s' in CBFS\n", filename);
-       return cbfs_get_handle(CBFS_DEFAULT_MEDIA, filename);
-}
-
-static const uint8_t *get_file_hash_from_cbfs(
-       const char *filename, int *hash_size, enum VbSelectFirmware_t select)
-{
-       printf("Trying to fetch hash for '%s'\n", filename);
-       struct cbfs_handle *handle = find_file_in_cbfs(filename, select);
-
-       if (handle == NULL) {
-               printf("%s not found\n", filename);
-               return NULL;
-       }
-
-       struct cbfs_file_attr_hash *attr = cbfs_get_attr(handle,
-               CBFS_FILE_ATTR_TAG_HASH);
-
-       if (attr == NULL) {
-               printf("%s found, but without hash\n", filename);
-               return NULL;
-       }
-
-       if (ntohl(attr->hash_type) != VB2_HASH_SHA256) {
-               printf("hash is not SHA256\n");
-               return NULL;
-       }
-       *hash_size = ntohl(attr->len) - sizeof(*attr);
-       return attr->hash_data;
+       return cbfs_get_file_content(CBFS_DEFAULT_MEDIA, filename,
+                                    CBFS_TYPE_RAW, size);
 }
 
 int VbExTrustEC(int devidx)
@@ -159,16 +130,11 @@ VbError_t VbExEcGetExpectedImage(int devidx, enum VbSelectFirmware_t select,
                /* It may be gone in favor of CBFS based RW sections,
                 * so look there, too. */
                size_t size;
-               const char *filename = get_fw_filename(devidx, select);
-               struct cbfs_handle *h = find_file_in_cbfs(filename, select);
-               if (h == NULL)
-                       return VBERROR_UNKNOWN;
-               *image = cbfs_get_contents(h, &size, 0);
-               free(h);
+               const char *filename = EC_IMAGE_FILENAME(devidx, select);
+               *image = get_file_from_cbfs(filename, select, &size);
                if (*image == NULL)
                        return VBERROR_UNKNOWN;
                *image_size = size;
-               printf("found '%s', sized 0x%zx\n", filename, size);
                return VBERROR_SUCCESS;
        }
 
@@ -178,9 +144,6 @@ VbError_t VbExEcGetExpectedImage(int devidx, enum VbSelectFirmware_t select,
        if (!*image)
                return VBERROR_UNKNOWN;
 
-       printf("EC-%s firmware address, size are %p, %d.\n", select ==
-              VB_SELECT_FIRMWARE_READONLY ? "RO" : "RW", *image, *image_size);
-
        return VBERROR_SUCCESS;
 }
 
@@ -224,20 +187,14 @@ VbError_t VbExEcGetExpectedImageHash(int devidx, enum VbSelectFirmware_t select,
        if (!*hash) {
                printf("Didn't find precalculated hash subsection %d.\n",
                       devidx + 1);
-               const char *filename = get_fw_filename(devidx, select);
-               *hash = get_file_hash_from_cbfs(filename, hash_size, select);
+               size_t size;
+               const char *filename = EC_HASH_FILENAME(devidx, select);
+               *hash = get_file_from_cbfs(filename, select, &size);
                if (!*hash)
                        return VBERROR_UNKNOWN;
+               *hash_size = size;
        }
 
-       printf("EC-%s hash address, size are %p, %d.\n", select ==
-              VB_SELECT_FIRMWARE_READONLY ? "RO" : "RW", *hash, *hash_size);
-
-       printf("Hash = ");
-       for (int i = 0; i < *hash_size; i++)
-               printf("%02x", (*hash)[i]);
-       printf("\n");
-
        return VBERROR_SUCCESS;
 }