mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-20 13:28:10 +00:00
178 lines
4.3 KiB
Python
178 lines
4.3 KiB
Python
# ----- General ----- #
|
|
UINT32_MAX = 0xFFFF_FFFF
|
|
|
|
# ----- PIN and encryption related ----- #
|
|
|
|
# App ID where PIN log is stored.
|
|
PIN_APP_ID = 0x00
|
|
|
|
# Storage key of the combined salt, EDEK, ESEK and PIN verification code entry.
|
|
EDEK_ESEK_PVC_KEY = (PIN_APP_ID << 8) | 0x02
|
|
|
|
# Storage key of the PIN set flag.
|
|
PIN_NOT_SET_KEY = (PIN_APP_ID << 8) | 0x03
|
|
|
|
# Norcow storage key of the storage version.
|
|
VERSION_KEY = (PIN_APP_ID << 8) | 0x04
|
|
|
|
# Norcow storage key of the storage authentication tag.
|
|
SAT_KEY = (PIN_APP_ID << 8) | 0x05
|
|
|
|
# Norcow storage key of the wipe code data.
|
|
WIPE_CODE_DATA_KEY = (PIN_APP_ID << 8) | 0x06
|
|
|
|
# Norcow storage key of the storage upgrade flag.
|
|
STORAGE_UPGRADED_KEY = (PIN_APP_ID << 8) | 0x07
|
|
|
|
# Norcow storage key of the unauthenticated storage version.
|
|
UNAUTH_VERSION_KEY = (PIN_APP_ID << 8) | 0x08
|
|
|
|
# The PIN value corresponding to an empty PIN.
|
|
PIN_EMPTY = ""
|
|
|
|
# Maximum number of failed unlock attempts.
|
|
PIN_MAX_TRIES = 16
|
|
|
|
# The total number of iterations to use in PBKDF2.
|
|
PIN_ITER_COUNT = 20000
|
|
|
|
# The length of the data encryption key in bytes.
|
|
DEK_SIZE = 32
|
|
|
|
# The length of the storage authentication key in bytes.
|
|
SAK_SIZE = 16
|
|
|
|
# The length of the storage authentication tag in bytes.
|
|
SAT_SIZE = 16
|
|
|
|
# The length of the random salt in bytes.
|
|
PIN_SALT_SIZE = 4
|
|
PIN_HARDWARE_SALT_SIZE = 32
|
|
|
|
# The length of the PIN verification code in bytes.
|
|
PVC_SIZE = 8
|
|
|
|
# The length of KEK in bytes.
|
|
KEK_SIZE = 32
|
|
|
|
# The length of KEIV in bytes.
|
|
KEIV_SIZE = 12
|
|
|
|
# The byte length of the salt used in checking the wipe code.
|
|
WIPE_CODE_SALT_SIZE = 8
|
|
|
|
# The byte length of the tag used in checking the wipe code.
|
|
WIPE_CODE_TAG_SIZE = 8
|
|
|
|
# The value corresponding to an unconfigured wipe code.
|
|
# NOTE: This is intentionally different from PIN_EMPTY so that we don't need
|
|
# special handling when both the PIN and wipe code are not set.
|
|
WIPE_CODE_EMPTY = "\0\0\0\0"
|
|
|
|
# Size of counter. 4B integer and 8B tail.
|
|
COUNTER_TAIL = 12
|
|
COUNTER_TAIL_SIZE = 8
|
|
COUNTER_MAX_TAIL = 64
|
|
|
|
# ----- PIN logs ----- #
|
|
|
|
# Storage key of the PIN entry log and PIN success log.
|
|
PIN_LOG_KEY = (PIN_APP_ID << 8) | 0x01
|
|
|
|
# Length of items in the PIN entry log
|
|
PIN_LOG_GUARD_KEY_SIZE = 4
|
|
|
|
# Values used for the guard key integrity check.
|
|
GUARD_KEY_MODULUS = 6311
|
|
GUARD_KEY_REMAINDER = 15
|
|
GUARD_KEY_RANDOM_MAX = (0xFFFFFFFF // GUARD_KEY_MODULUS) + 1
|
|
|
|
# Length of both success log and entry log
|
|
PIN_LOG_SIZE = 64
|
|
|
|
# Used for in guard bits operations.
|
|
LOW_MASK = 0x55555555
|
|
|
|
# Log initialized to all FFs.
|
|
ALL_FF_LOG = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
|
|
|
# ----- Bytes -----
|
|
|
|
# If the top bit of APP is set, then the value is not encrypted.
|
|
FLAG_PUBLIC = 0x80
|
|
|
|
# If the top two bits of APP are set, then the value is not encrypted and it
|
|
# can be written even when the storage is locked.
|
|
FLAGS_WRITE = 0xC0
|
|
|
|
# Length of word in bytes.
|
|
WORD_SIZE = 4
|
|
|
|
# Boolean values are stored as a simple 0/1 int.
|
|
TRUE_BYTE = b"\x01"
|
|
FALSE_BYTE = b"\x00"
|
|
TRUE_WORD = b"\xA5\x69\x5A\xC3"
|
|
FALSE_WORD = b"\x5A\x96\xA5\x3C"
|
|
|
|
# ----- Crypto ----- #
|
|
|
|
# The length of the Poly1305 MAC in bytes.
|
|
POLY1305_MAC_SIZE = 16
|
|
|
|
# The length of the ChaCha20 IV (aka nonce) in bytes as per RFC 7539.
|
|
CHACHA_IV_SIZE = 12
|
|
|
|
# ----- Norcow ----- #
|
|
|
|
NORCOW_SECTOR_COUNT = 2
|
|
NORCOW_SECTOR_SIZE = 64 * 1024
|
|
|
|
# Magic flag at the beggining of an active sector.
|
|
NORCOW_MAGIC = b"NRC2"
|
|
|
|
# Norcow version, set in the storage header, but also as an encrypted item.
|
|
NORCOW_VERSION = b"\x03\x00\x00\x00"
|
|
|
|
# Norcow magic combined with the version, which is stored as its negation.
|
|
NORCOW_MAGIC_AND_VERSION = NORCOW_MAGIC + bytes(
|
|
[
|
|
~NORCOW_VERSION[0] & 0xFF,
|
|
~NORCOW_VERSION[1] & 0xFF,
|
|
~NORCOW_VERSION[2] & 0xFF,
|
|
~NORCOW_VERSION[3] & 0xFF,
|
|
]
|
|
)
|
|
|
|
# Signalizes free storage.
|
|
NORCOW_KEY_FREE = 0xFFFF
|
|
|
|
|
|
# |-----------|-------------------|
|
|
# | Private | APP = 0 |
|
|
# | Protected | 1 <= APP <= 127 |
|
|
# | Public | 128 <= APP <= 255 |
|
|
|
|
|
|
def is_app_public(app: int):
|
|
if app & FLAG_PUBLIC:
|
|
return True
|
|
return False
|
|
|
|
|
|
def is_app_protected(app: int):
|
|
if is_app_public(app):
|
|
return False
|
|
if is_app_private(app):
|
|
return False
|
|
return True
|
|
|
|
|
|
def is_app_private(app: int):
|
|
return app == PIN_APP_ID
|
|
|
|
|
|
def is_app_lock_writable(app: int):
|
|
if app & FLAGS_WRITE == FLAGS_WRITE:
|
|
return True
|
|
return False
|