mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-07 13:12:41 +00:00
refactor(core): enclose monotonic counter to platform specific module
[no changelog]
This commit is contained in:
parent
d334b92073
commit
c1864a2a91
@ -149,6 +149,7 @@ SOURCE_TREZORHAL = [
|
|||||||
'embed/trezorhal/unix/fault_handlers.c',
|
'embed/trezorhal/unix/fault_handlers.c',
|
||||||
'embed/trezorhal/unix/flash.c',
|
'embed/trezorhal/unix/flash.c',
|
||||||
'embed/trezorhal/unix/flash_otp.c',
|
'embed/trezorhal/unix/flash_otp.c',
|
||||||
|
'embed/trezorhal/unix/monoctr.c',
|
||||||
'embed/trezorhal/unix/random_delays.c',
|
'embed/trezorhal/unix/random_delays.c',
|
||||||
'embed/trezorhal/unix/rng.c',
|
'embed/trezorhal/unix/rng.c',
|
||||||
'embed/trezorhal/unix/secret.c',
|
'embed/trezorhal/unix/secret.c',
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
#include "lowlevel.h"
|
#include "lowlevel.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "monoctr.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "memzero.h"
|
#include "memzero.h"
|
||||||
@ -76,45 +77,17 @@ static const uint8_t * const BOARDLOADER_KEYS[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef STM32U5
|
static uint8_t get_bootloader_min_version(void) {
|
||||||
uint8_t get_bootloader_min_version(void) {
|
uint8_t version = 0;
|
||||||
const uint8_t *counter_addr =
|
ensure(monoctr_read(MONOCTR_BOOTLOADER_VERSION, &version), "monoctr read");
|
||||||
flash_area_get_address(&SECRET_AREA, SECRET_MONOTONIC_COUNTER_OFFSET,
|
return version;
|
||||||
SECRET_MONOTONIC_COUNTER_LEN);
|
|
||||||
|
|
||||||
ensure((counter_addr != NULL) * sectrue, "counter_addr is NULL");
|
|
||||||
|
|
||||||
int counter = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < SECRET_MONOTONIC_COUNTER_LEN / 16; i++) {
|
|
||||||
secbool not_cleared = sectrue;
|
|
||||||
for (int j = 0; j < 16; j++) {
|
|
||||||
if (counter_addr[i * 16 + j] != 0xFF) {
|
|
||||||
not_cleared = secfalse;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not_cleared != sectrue) {
|
|
||||||
counter++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_bootloader_min_version(uint8_t version) {
|
static void write_bootloader_min_version(uint8_t version) {
|
||||||
if (version > get_bootloader_min_version()) {
|
if (version > get_bootloader_min_version()) {
|
||||||
for (int i = 0; i < version; i++) {
|
ensure(monoctr_write(MONOCTR_BOOTLOADER_VERSION, version), "monoctr write");
|
||||||
uint32_t data[4] = {0};
|
|
||||||
secret_write((uint8_t *)data, SECRET_MONOTONIC_COUNTER_OFFSET + i * 16,
|
|
||||||
16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
struct BoardCapabilities capabilities
|
struct BoardCapabilities capabilities
|
||||||
__attribute__((section(".capabilities_section"))) = {
|
__attribute__((section(".capabilities_section"))) = {
|
||||||
@ -197,11 +170,9 @@ static uint32_t check_sdcard(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STM32U5
|
|
||||||
if (hdr->monotonic < get_bootloader_min_version()) {
|
if (hdr->monotonic < get_bootloader_min_version()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return hdr->codelen;
|
return hdr->codelen;
|
||||||
}
|
}
|
||||||
@ -310,7 +281,6 @@ int main(void) {
|
|||||||
#if defined USE_SD_CARD
|
#if defined USE_SD_CARD
|
||||||
sdcard_init();
|
sdcard_init();
|
||||||
|
|
||||||
#ifdef STM32U5
|
|
||||||
// If the bootloader is being updated from SD card, we need to preserve the
|
// If the bootloader is being updated from SD card, we need to preserve the
|
||||||
// monotonic counter from the old bootloader. This is in case that the old
|
// monotonic counter from the old bootloader. This is in case that the old
|
||||||
// bootloader did not have the chance yet to write its monotonic counter to
|
// bootloader did not have the chance yet to write its monotonic counter to
|
||||||
@ -327,7 +297,6 @@ int main(void) {
|
|||||||
check_image_contents(old_hdr, IMAGE_HEADER_SIZE, &BOOTLOADER_AREA))) {
|
check_image_contents(old_hdr, IMAGE_HEADER_SIZE, &BOOTLOADER_AREA))) {
|
||||||
write_bootloader_min_version(old_hdr->monotonic);
|
write_bootloader_min_version(old_hdr->monotonic);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (check_sdcard()) {
|
if (check_sdcard()) {
|
||||||
return copy_sdcard() == sectrue ? 0 : 3;
|
return copy_sdcard() == sectrue ? 0 : 3;
|
||||||
@ -348,14 +317,12 @@ int main(void) {
|
|||||||
ensure(check_image_contents(hdr, IMAGE_HEADER_SIZE, &BOOTLOADER_AREA),
|
ensure(check_image_contents(hdr, IMAGE_HEADER_SIZE, &BOOTLOADER_AREA),
|
||||||
"invalid bootloader hash");
|
"invalid bootloader hash");
|
||||||
|
|
||||||
#ifdef STM32U5
|
|
||||||
uint8_t bld_min_version = get_bootloader_min_version();
|
uint8_t bld_min_version = get_bootloader_min_version();
|
||||||
ensure((hdr->monotonic >= bld_min_version) * sectrue,
|
ensure((hdr->monotonic >= bld_min_version) * sectrue,
|
||||||
"BOOTLOADER DOWNGRADED");
|
"BOOTLOADER DOWNGRADED");
|
||||||
// Write the bootloader version to the secret area.
|
// Write the bootloader version to the secret area.
|
||||||
// This includes the version of bootloader potentially updated from SD card.
|
// This includes the version of bootloader potentially updated from SD card.
|
||||||
write_bootloader_min_version(hdr->monotonic);
|
write_bootloader_min_version(hdr->monotonic);
|
||||||
#endif
|
|
||||||
|
|
||||||
ensure_compatible_settings();
|
ensure_compatible_settings();
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
|
|
||||||
#include "bootui.h"
|
#include "bootui.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
#include "monoctr.h"
|
||||||
#include "rust_ui.h"
|
#include "rust_ui.h"
|
||||||
#include "unit_variant.h"
|
#include "unit_variant.h"
|
||||||
|
|
||||||
@ -265,24 +266,10 @@ static secbool check_vendor_header_lock(const vendor_header *const vhdr) {
|
|||||||
#if PRODUCTION && !defined STM32U5
|
#if PRODUCTION && !defined STM32U5
|
||||||
|
|
||||||
static void check_bootloader_version(void) {
|
static void check_bootloader_version(void) {
|
||||||
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
ensure(monoctr_write(MONOCTR_BOOTLOADER_VERSION, VERSION_MONOTONIC), NULL);
|
||||||
for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
uint8_t val = 0;
|
||||||
if (i < VERSION_MONOTONIC) {
|
ensure(monoctr_read(MONOCTR_BOOTLOADER_VERSION, &val), NULL);
|
||||||
bits[i / 8] &= ~(1 << (7 - (i % 8)));
|
ensure(sectrue * (val == VERSION_MONOTONIC),
|
||||||
} else {
|
|
||||||
bits[i / 8] |= (1 << (7 - (i % 8)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ensure(flash_otp_write(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits,
|
|
||||||
FLASH_OTP_BLOCK_SIZE),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
uint8_t bits2[FLASH_OTP_BLOCK_SIZE];
|
|
||||||
ensure(flash_otp_read(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits2,
|
|
||||||
FLASH_OTP_BLOCK_SIZE),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
ensure(sectrue * (0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE)),
|
|
||||||
"Bootloader downgrade protection");
|
"Bootloader downgrade protection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define FLASH_OTP_BLOCK_VENDOR_HEADER_LOCK 2
|
#define FLASH_OTP_BLOCK_VENDOR_HEADER_LOCK 2
|
||||||
#define FLASH_OTP_BLOCK_RANDOMNESS 3
|
#define FLASH_OTP_BLOCK_RANDOMNESS 3
|
||||||
#define FLASH_OTP_BLOCK_DEVICE_VARIANT 4
|
#define FLASH_OTP_BLOCK_DEVICE_VARIANT 4
|
||||||
|
#define FLASH_OTP_BLOCK_FIRMWARE_VERSION 5
|
||||||
|
|
||||||
#define STORAGE_AREAS_COUNT (2)
|
#define STORAGE_AREAS_COUNT (2)
|
||||||
|
|
||||||
|
39
core/embed/trezorhal/monoctr.h
Normal file
39
core/embed/trezorhal/monoctr.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TREZORHAL_MONOCTR
|
||||||
|
#define TREZORHAL_MONOCTR
|
||||||
|
|
||||||
|
// Monoctr module provides monotonic counter functionality
|
||||||
|
|
||||||
|
#define MONOCTR_MAX_VALUE 63
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "secbool.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MONOCTR_BOOTLOADER_VERSION = 0,
|
||||||
|
MONOCTR_FIRMWARE_VERSION = 1,
|
||||||
|
} monoctr_type_t;
|
||||||
|
|
||||||
|
secbool monoctr_write(monoctr_type_t type, uint8_t value);
|
||||||
|
|
||||||
|
secbool monoctr_read(monoctr_type_t type, uint8_t* value);
|
||||||
|
|
||||||
|
#endif
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#define SECRET_MONOTONIC_COUNTER_OFFSET 48
|
#define SECRET_MONOTONIC_COUNTER_OFFSET 48
|
||||||
#define SECRET_MONOTONIC_COUNTER_LEN 1024
|
#define SECRET_MONOTONIC_COUNTER_LEN 1024
|
||||||
|
#define SECRET_MONOTONIC_COUNTER2_OFFSET (SECRET_MONOTONIC_COUNTER_LEN + 48)
|
||||||
|
|
||||||
#define SECRET_BHK_OFFSET (1024 * 8)
|
#define SECRET_BHK_OFFSET (1024 * 8)
|
||||||
#define SECRET_BHK_LEN 32
|
#define SECRET_BHK_LEN 32
|
||||||
|
119
core/embed/trezorhal/stm32f4/monoctr.c
Normal file
119
core/embed/trezorhal/stm32f4/monoctr.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "monoctr.h"
|
||||||
|
#include "flash_otp.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#if PRODUCTION
|
||||||
|
static int get_otp_block(monoctr_type_t type) {
|
||||||
|
switch (type) {
|
||||||
|
case MONOCTR_BOOTLOADER_VERSION:
|
||||||
|
return FLASH_OTP_BLOCK_BOOTLOADER_VERSION;
|
||||||
|
case MONOCTR_FIRMWARE_VERSION:
|
||||||
|
return FLASH_OTP_BLOCK_FIRMWARE_VERSION;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
secbool monoctr_write(monoctr_type_t type, uint8_t value) {
|
||||||
|
#if PRODUCTION
|
||||||
|
if (value > MONOCTR_MAX_VALUE) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
||||||
|
for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
|
if (i < value) {
|
||||||
|
bits[i / 8] &= ~(1 << (7 - (i % 8)));
|
||||||
|
} else {
|
||||||
|
bits[i / 8] |= (1 << (7 - (i % 8)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int block = get_otp_block(type);
|
||||||
|
|
||||||
|
if (block < 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure(flash_otp_write(block, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return sectrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
secbool monoctr_read(monoctr_type_t type, uint8_t* value) {
|
||||||
|
#if PRODUCTION
|
||||||
|
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
||||||
|
|
||||||
|
int block = get_otp_block(type);
|
||||||
|
|
||||||
|
if (block < 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure(flash_otp_read(block, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Iterate through each bit position in the bit field
|
||||||
|
for (i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
|
// Calculate the byte and bit index within the byte
|
||||||
|
int byteIndex = i / 8;
|
||||||
|
int bitIndex = 7 - (i % 8);
|
||||||
|
|
||||||
|
// Check if the current bit is 0
|
||||||
|
if ((bits[byteIndex] & (1 << bitIndex)) == 0) {
|
||||||
|
// If the bit is 0, increment the value
|
||||||
|
result++;
|
||||||
|
} else {
|
||||||
|
// Stop when we find the first 1 bit
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
|
// Calculate the byte and bit index within the byte
|
||||||
|
int byteIndex = i / 8;
|
||||||
|
int bitIndex = 7 - (i % 8);
|
||||||
|
if ((bits[byteIndex] & (1 << bitIndex)) == 0) {
|
||||||
|
// If the bit is 0, return false - the monotonic counter is not valid
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != NULL) {
|
||||||
|
*value = result;
|
||||||
|
} else {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
*value = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return sectrue;
|
||||||
|
}
|
111
core/embed/trezorhal/stm32u5/monoctr.c
Normal file
111
core/embed/trezorhal/stm32u5/monoctr.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "monoctr.h"
|
||||||
|
#include "flash_area.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "secret.h"
|
||||||
|
|
||||||
|
static int32_t get_offset(monoctr_type_t type) {
|
||||||
|
switch (type) {
|
||||||
|
case MONOCTR_BOOTLOADER_VERSION:
|
||||||
|
return SECRET_MONOTONIC_COUNTER_OFFSET;
|
||||||
|
case MONOCTR_FIRMWARE_VERSION:
|
||||||
|
return SECRET_MONOTONIC_COUNTER2_OFFSET;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
secbool monoctr_write(monoctr_type_t type, uint8_t value) {
|
||||||
|
if (value > MONOCTR_MAX_VALUE) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t offset = get_offset(type);
|
||||||
|
|
||||||
|
if (offset < 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < value; i++) {
|
||||||
|
uint32_t data[4] = {0};
|
||||||
|
secret_write((uint8_t *)data, offset + i * 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sectrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
secbool monoctr_read(monoctr_type_t type, uint8_t *value) {
|
||||||
|
int32_t offset = get_offset(type);
|
||||||
|
|
||||||
|
if (offset < 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *counter_addr = flash_area_get_address(
|
||||||
|
&SECRET_AREA, offset, SECRET_MONOTONIC_COUNTER_LEN);
|
||||||
|
|
||||||
|
if (counter_addr == NULL) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < SECRET_MONOTONIC_COUNTER_LEN / 16; i++) {
|
||||||
|
secbool not_cleared = sectrue;
|
||||||
|
for (int j = 0; j < 16; j++) {
|
||||||
|
if (counter_addr[i * 16 + j] != 0xFF) {
|
||||||
|
not_cleared = secfalse;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_cleared != sectrue) {
|
||||||
|
counter++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < SECRET_MONOTONIC_COUNTER_LEN / 16; i++) {
|
||||||
|
secbool not_cleared = sectrue;
|
||||||
|
for (int j = 0; j < 16; j++) {
|
||||||
|
if (counter_addr[i * 16 + j] != 0xFF) {
|
||||||
|
not_cleared = secfalse;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_cleared != sectrue) {
|
||||||
|
// monotonic counter is not valid
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != NULL) {
|
||||||
|
*value = counter;
|
||||||
|
} else {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sectrue;
|
||||||
|
}
|
109
core/embed/trezorhal/unix/monoctr.c
Normal file
109
core/embed/trezorhal/unix/monoctr.c
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "monoctr.h"
|
||||||
|
#include "flash_otp.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
static int get_otp_block(monoctr_type_t type) {
|
||||||
|
switch (type) {
|
||||||
|
case MONOCTR_BOOTLOADER_VERSION:
|
||||||
|
return FLASH_OTP_BLOCK_BOOTLOADER_VERSION;
|
||||||
|
case MONOCTR_FIRMWARE_VERSION:
|
||||||
|
return FLASH_OTP_BLOCK_FIRMWARE_VERSION;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
secbool monoctr_write(monoctr_type_t type, uint8_t value) {
|
||||||
|
if (value > MONOCTR_MAX_VALUE) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
||||||
|
for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
|
if (i < value) {
|
||||||
|
bits[i / 8] &= ~(1 << (7 - (i % 8)));
|
||||||
|
} else {
|
||||||
|
bits[i / 8] |= (1 << (7 - (i % 8)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int block = get_otp_block(type);
|
||||||
|
|
||||||
|
if (block < 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure(flash_otp_write(block, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
|
||||||
|
|
||||||
|
return sectrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
secbool monoctr_read(monoctr_type_t type, uint8_t* value) {
|
||||||
|
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
|
||||||
|
|
||||||
|
int block = get_otp_block(type);
|
||||||
|
|
||||||
|
if (block < 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure(flash_otp_read(block, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Iterate through each bit position in the bit field
|
||||||
|
for (i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
|
// Calculate the byte and bit index within the byte
|
||||||
|
int byteIndex = i / 8;
|
||||||
|
int bitIndex = 7 - (i % 8);
|
||||||
|
|
||||||
|
// Check if the current bit is 0
|
||||||
|
if ((bits[byteIndex] & (1 << bitIndex)) == 0) {
|
||||||
|
// If the bit is 0, increment the value
|
||||||
|
result++;
|
||||||
|
} else {
|
||||||
|
// Stop when we find the first 1 bit
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
|
||||||
|
// Calculate the byte and bit index within the byte
|
||||||
|
int byteIndex = i / 8;
|
||||||
|
int bitIndex = 7 - (i % 8);
|
||||||
|
if ((bits[byteIndex] & (1 << bitIndex)) == 0) {
|
||||||
|
// If the bit is 0, return false - the monotonic counter is not valid
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != NULL) {
|
||||||
|
*value = result;
|
||||||
|
} else {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sectrue;
|
||||||
|
}
|
@ -47,6 +47,7 @@ def stm32f4_common_files(env, defines, sources, paths):
|
|||||||
"embed/trezorhal/stm32f4/flash.c",
|
"embed/trezorhal/stm32f4/flash.c",
|
||||||
"embed/trezorhal/stm32f4/flash_otp.c",
|
"embed/trezorhal/stm32f4/flash_otp.c",
|
||||||
"embed/trezorhal/stm32f4/lowlevel.c",
|
"embed/trezorhal/stm32f4/lowlevel.c",
|
||||||
|
"embed/trezorhal/stm32f4/monoctr.c",
|
||||||
"embed/trezorhal/stm32f4/mpu.c",
|
"embed/trezorhal/stm32f4/mpu.c",
|
||||||
"embed/trezorhal/stm32f4/platform.c",
|
"embed/trezorhal/stm32f4/platform.c",
|
||||||
"embed/trezorhal/stm32f4/secret.c",
|
"embed/trezorhal/stm32f4/secret.c",
|
||||||
|
@ -57,6 +57,7 @@ def stm32u5_common_files(env, defines, sources, paths):
|
|||||||
"embed/trezorhal/stm32u5/flash_otp.c",
|
"embed/trezorhal/stm32u5/flash_otp.c",
|
||||||
"embed/trezorhal/stm32u5/lowlevel.c",
|
"embed/trezorhal/stm32u5/lowlevel.c",
|
||||||
"embed/trezorhal/stm32u5/hash_processor.c",
|
"embed/trezorhal/stm32u5/hash_processor.c",
|
||||||
|
"embed/trezorhal/stm32u5/monoctr.c",
|
||||||
"embed/trezorhal/stm32u5/mpu.c",
|
"embed/trezorhal/stm32u5/mpu.c",
|
||||||
"embed/trezorhal/stm32u5/platform.c",
|
"embed/trezorhal/stm32u5/platform.c",
|
||||||
"embed/trezorhal/stm32u5/secret.c",
|
"embed/trezorhal/stm32u5/secret.c",
|
||||||
|
Loading…
Reference in New Issue
Block a user