summaryrefslogtreecommitdiff
path: root/common/rollback.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/rollback.c')
-rw-r--r--common/rollback.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/common/rollback.c b/common/rollback.c
index 1b2962fc5a..590c1224af 100644
--- a/common/rollback.c
+++ b/common/rollback.c
@@ -209,14 +209,25 @@ BUILD_ASSERT(SHA256_DIGEST_SIZE == CONFIG_ROLLBACK_SECRET_SIZE);
static int rollback_update(int32_t next_min_version,
uint8_t *entropy, unsigned int length)
{
- struct rollback_data data;
+ /*
+ * When doing flash_write operation, the data needs to be in blocks
+ * of CONFIG_FLASH_WRITE_SIZE, pad rollback_data as required.
+ */
+ uint8_t block[CONFIG_FLASH_WRITE_SIZE *
+ DIV_ROUND_UP(sizeof(struct rollback_data),
+ CONFIG_FLASH_WRITE_SIZE)];
+ struct rollback_data *data = (struct rollback_data *)block;
+ BUILD_ASSERT(sizeof(block) >= sizeof(*data));
uintptr_t offset;
int region;
if (flash_get_protect() & EC_FLASH_PROTECT_ROLLBACK_NOW)
return EC_ERROR_ACCESS_DENIED;
- region = get_latest_rollback(&data);
+ /* Initialize the rest of the block. */
+ memset(&block[sizeof(*data)], 0xff, sizeof(block)-sizeof(*data));
+
+ region = get_latest_rollback(data);
if (region < 0)
return EC_ERROR_UNKNOWN;
@@ -224,17 +235,17 @@ static int rollback_update(int32_t next_min_version,
#ifdef CONFIG_ROLLBACK_SECRET_SIZE
if (entropy) {
/* Do not accept to decrease the value. */
- if (next_min_version < data.rollback_min_version)
- next_min_version = data.rollback_min_version;
+ if (next_min_version < data->rollback_min_version)
+ next_min_version = data->rollback_min_version;
} else
#endif
{
/* Do not accept to decrease the value. */
- if (next_min_version < data.rollback_min_version)
+ if (next_min_version < data->rollback_min_version)
return EC_ERROR_INVAL;
/* No need to update if version is already correct. */
- if (next_min_version == data.rollback_min_version)
+ if (next_min_version == data->rollback_min_version)
return EC_SUCCESS;
}
@@ -243,19 +254,19 @@ static int rollback_update(int32_t next_min_version,
offset = get_rollback_offset(region);
- data.id = data.id + 1;
- data.rollback_min_version = next_min_version;
+ data->id = data->id + 1;
+ data->rollback_min_version = next_min_version;
#ifdef CONFIG_ROLLBACK_SECRET_SIZE
/*
* If we are provided with some entropy, add it to secret. Otherwise,
* data.secret is left untouched and written back to the other region.
*/
if (entropy) {
- if (!add_entropy(data.secret, data.secret, entropy, length))
+ if (!add_entropy(data->secret, data->secret, entropy, length))
return EC_ERROR_UNCHANGED;
}
#endif
- data.cookie = CROS_EC_ROLLBACK_COOKIE;
+ data->cookie = CROS_EC_ROLLBACK_COOKIE;
/* Offset should never be part of active image. */
if (system_unsafe_to_overwrite(offset, CONFIG_FLASH_ERASE_SIZE))
@@ -264,7 +275,7 @@ static int rollback_update(int32_t next_min_version,
if (flash_erase(offset, CONFIG_FLASH_ERASE_SIZE))
return EC_ERROR_UNKNOWN;
- if (flash_write(offset, sizeof(data), (char *)&data))
+ if (flash_write(offset, sizeof(block), block))
return EC_ERROR_UNKNOWN;
return EC_SUCCESS;