update_fw: Store complete touchpad FW hash

This will be used by the updater to first check that the touchpad
FW on AP side matches the one for which we stored hashes on EC
side.

This guarantee that we do not accidentally try to flash an
incorrect FW, which would render the touchpad non-functional.

BRANCH=none
BUG=b:63993173
TEST=make TOUCHPAD_FW=SA459C-1211_ForGoogleHammer_3.0.bin \
          BOARD=hammer -j
TEST=./usb_updater2 -t
     includes output of
     sha256sum A459C-1211_ForGoogleHammer_3.0.bin

Change-Id: Id30ab2d7c7d7e2d0f25cc893f685d218c44c022e
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/641736
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Nicolas Boichat 2017-08-30 15:02:48 +08:00 committed by chrome-bot
parent 4fdccb6de5
commit 82e0892fc3
4 changed files with 42 additions and 13 deletions

View File

@ -27,6 +27,8 @@
BUILD_ASSERT(sizeof(touchpad_fw_hashes) ==
(CONFIG_TOUCHPAD_FW_CHUNKS * SHA256_DIGEST_SIZE));
BUILD_ASSERT(sizeof(touchpad_fw_hashes[0]) == SHA256_DIGEST_SIZE);
BUILD_ASSERT(sizeof(touchpad_fw_full_hash) == SHA256_DIGEST_SIZE);
#endif
#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)

View File

@ -316,8 +316,12 @@ static int try_vendor_command(struct consumer const *consumer, size_t count)
#ifdef CONFIG_TOUCHPAD_VIRTUAL_OFF
tp.fw_address = CONFIG_TOUCHPAD_VIRTUAL_OFF;
tp.fw_size = CONFIG_TOUCHPAD_VIRTUAL_SIZE;
#endif
#ifdef CONFIG_TOUCHPAD_HASH_FW
memcpy(tp.allowed_fw_hash, touchpad_fw_full_hash,
sizeof(tp.allowed_fw_hash));
#endif
#endif /* CONFIG_TOUCHPAD_VIRTUAL_OFF */
QUEUE_ADD_UNITS(&update_to_usb,
&tp, response_size);
return 1;

View File

@ -201,6 +201,13 @@ struct touchpad_info {
uint32_t fw_address;
uint32_t fw_size;
/*
* SHA256 hash of the trackpad FW accepted by this EC image.
* This is used by the updater to make sure we do not attempt to flash
* a touchpad FW that does not match the one shipped by the EC.
*/
uint8_t allowed_fw_hash[32];
/* Vendor specific data. */
struct {
uint16_t id;
@ -240,4 +247,7 @@ int touchpad_get_info(struct touchpad_info *tp);
/* Touchpad FW update: Write a FW block. */
int touchpad_update_write(int offset, int size, const uint8_t *data);
/* SHA256 hash of the touchpad firmware expected by this image. */
extern const uint8_t touchpad_fw_full_hash[32];
#endif /* ! __CROS_EC_UPDATE_FW_H */

View File

@ -14,15 +14,15 @@
#include "config.h"
static void print_hex(FILE *out, uint8_t digest[SHA256_DIGEST_LENGTH])
static void print_hex(FILE *out, uint8_t *digest, int len, int last)
{
int i;
fputs("\t{ ", out);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
fputs("{ ", out);
for (i = 0; i < len; i++)
fprintf(out, "0x%02x, ", digest[i]);
fputs("},\n", out);
fprintf(out, "}%c\n", last ? ';' : ',');
}
/* Output blank hashes */
@ -31,13 +31,19 @@ static int hash_fw_blank(FILE *hashes)
uint8_t digest[SHA256_DIGEST_LENGTH] = { 0 };
int len;
fputs("{\n", hashes);
fprintf(hashes, "const uint8_t touchpad_fw_hashes[%d][%d] = {\n",
CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE,
SHA256_DIGEST_LENGTH);
for (len = 0; len < CONFIG_TOUCHPAD_VIRTUAL_SIZE;
len += CONFIG_UPDATE_PDU_SIZE) {
print_hex(hashes, digest);
print_hex(hashes, digest, sizeof(digest), 0);
}
fputs("};\n", hashes);
fprintf(hashes, "const uint8_t touchpad_fw_full_hash[%d] =\n\t",
SHA256_DIGEST_LENGTH);
print_hex(hashes, digest, SHA256_DIGEST_LENGTH, 1);
return 0;
}
@ -47,9 +53,13 @@ static int hash_fw(FILE *tp_fw, FILE *hashes)
int len = 0;
int rb;
SHA256_CTX ctx;
SHA256_CTX ctx_all;
uint8_t digest[SHA256_DIGEST_LENGTH];
fputs("{\n", hashes);
SHA256_Init(&ctx_all);
fprintf(hashes, "const uint8_t touchpad_fw_hashes[%d][%d] = {\n",
CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE,
SHA256_DIGEST_LENGTH);
while (1) {
rb = fread(buffer, 1, sizeof(buffer), tp_fw);
len += rb;
@ -62,13 +72,20 @@ static int hash_fw(FILE *tp_fw, FILE *hashes)
SHA256_Update(&ctx, buffer, rb);
SHA256_Final(digest, &ctx);
print_hex(hashes, digest);
SHA256_Update(&ctx_all, buffer, rb);
print_hex(hashes, digest, sizeof(digest), 0);
if (rb < sizeof(buffer))
break;
}
fputs("};\n", hashes);
SHA256_Final(digest, &ctx_all);
fprintf(hashes, "const uint8_t touchpad_fw_full_hash[%d] =\n\t",
SHA256_DIGEST_LENGTH);
print_hex(hashes, digest, SHA256_DIGEST_LENGTH, 1);
if (!feof(tp_fw) || ferror(tp_fw)) {
warn("Error reading input file");
return 1;
@ -129,10 +146,6 @@ int main(int argc, char **argv)
err(1, "Cannot open output file");
fputs("#include <stdint.h>\n\n", hashes);
fprintf(hashes, "const uint8_t touchpad_fw_hashes[%d][%d] = ",
CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE,
SHA256_DIGEST_LENGTH);
if (tp_fw_name) {
tp_fw = fopen(tp_fw_name, "re");