diff --git a/core/.clang-format b/.clang-format similarity index 100% rename from core/.clang-format rename to .clang-format diff --git a/.gitmodules b/.gitmodules index fe3282149..d4e39156f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,6 +23,7 @@ [submodule "legacy/vendor/nanopb"] path = legacy/vendor/nanopb url = https://github.com/nanopb/nanopb.git + ignore = untracked [submodule "legacy/vendor/QR-Code-generator"] path = legacy/vendor/QR-Code-generator url = https://github.com/nayuki/QR-Code-generator.git diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..d4aa18166 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +## help commands: + +help: ## show this help + @awk -f ./tools/help.awk $(MAKEFILE_LIST) + +## style commands: + +style_check: ## run code style check on application sources and tests + flake8 --version + isort --version | awk '/VERSION/{print $$2}' + black --version + flake8 $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude ) + isort --check-only $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude ) + black --check $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude ) + +style: ## apply code style on application sources and tests + isort $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude ) + black $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude ) + +cstyle_check: ## run code style check on low-level C code + ./tools/clang-format-check $(shell find -type f -name '*.c' -o -name '*.h' | grep -f ./tools/style.c.include | grep -v -f ./tools/style.c.exclude ) + +cstyle: ## apply code style on low-level C code + clang-format -i $(shell find -type f -name '*.c' -o -name '*.h' | grep -f ./tools/style.c.include | grep -v -f ./tools/style.c.exclude ) diff --git a/common/defs/webauthn/gen.py b/common/defs/webauthn/gen.py index e7b094439..420cd6602 100755 --- a/common/defs/webauthn/gen.py +++ b/common/defs/webauthn/gen.py @@ -1,13 +1,12 @@ #!/usr/bin/env python3 +import json import sys from glob import glob -import json from hashlib import sha256 - try: opt = sys.argv[1] -except: +except IndexError: print("Usage: gen.py [core|mcu|check])") sys.exit(1) @@ -22,12 +21,12 @@ def gen_core(data): for d in data: if "u2f" in d: url, label = d["u2f"], d["label"] - print(" \"%s\": \"%s\"," % (url, label)) + print(' "%s": "%s",' % (url, label)) print(" # WebAuthn") for d in data: if "webauthn" in d: origin, label = d["webauthn"], d["label"] - print(" \"%s\": \"%s\"," % (origin, label)) + print(' "%s": "%s",' % (origin, label)) print("}") @@ -36,12 +35,17 @@ def gen_mcu(data): if "u2f" in d: url, label = d["u2f"], d["label"] h = sha256(url.encode()).digest() - print("\t{\n\t\t// U2F: %s\n\t\t%s,\n\t\t\"%s\"\n\t}," % (url, c_bytes(h), label)) + print( + '\t{\n\t\t// U2F: %s\n\t\t%s,\n\t\t"%s"\n\t},' + % (url, c_bytes(h), label) + ) if "webauthn" in d: origin, label = d["webauthn"], d["label"] h = sha256(origin.encode()).digest() - print("\t{\n\t\t// WebAuthn: %s\n\t\t%s,\n\t\t\"%s\"\n\t}," % (origin, c_bytes(h), label)) - + print( + '\t{\n\t\t// WebAuthn: %s\n\t\t%s,\n\t\t"%s"\n\t},' + % (origin, c_bytes(h), label) + ) data = [] diff --git a/common/keys/public_trezor1.h b/common/keys/public_trezor1.h index ebd7d5b3e..f4e1d8373 100644 --- a/common/keys/public_trezor1.h +++ b/common/keys/public_trezor1.h @@ -1,3 +1,4 @@ +// clang-format off // TREZORv1 production public keys "\x04\xd5\x71\xb7\xf1\x48\xc5\xe4\x23\x2c\x38\x14\xf7\x77\xd8\xfa\xea\xf1\xa8\x42\x16\xc7\x8d\x56\x9b\x71\x04\x1f\xfc\x76\x8a\x5b\x2d\x81\x0f\xc3\xbb\x13\x4d\xd0\x26\xb5\x7e\x65\x00\x52\x75\xae\xde\xf4\x3e\x15\x5f\x48\xfc\x11\xa3\x2e\xc7\x90\xa9\x33\x12\xbd\x58", "\x04\x63\x27\x9c\x0c\x08\x66\xe5\x0c\x05\xc7\x99\xd3\x2b\xd6\xba\xb0\x18\x8b\x6d\xe0\x65\x36\xd1\x10\x9d\x2e\xd9\xce\x76\xcb\x33\x5c\x49\x0e\x55\xae\xe1\x0c\xc9\x01\x21\x51\x32\xe8\x53\x09\x7d\x54\x32\xed\xa0\x6b\x79\x20\x73\xbd\x77\x40\xc9\x4c\xe4\x51\x6c\xb1", diff --git a/common/keys/sample.h b/common/keys/sample.h index 1518d4f3b..ce9f2d417 100644 --- a/common/keys/sample.h +++ b/common/keys/sample.h @@ -1,2 +1,3 @@ +// clang-format off // sample public key "correct horse battery staple" "\x04\x78\xd4\x30\x27\x4f\x8c\x5e\xc1\x32\x13\x38\x15\x1e\x9f\x27\xf4\xc6\x76\xa0\x08\xbd\xf8\x63\x8d\x07\xc0\xb6\xbe\x9a\xb3\x5c\x71\xa1\x51\x80\x63\x24\x3a\xcd\x4d\xfe\x96\xb6\x6e\x3f\x2e\xc8\x01\x3c\x8e\x07\x2c\xd0\x9b\x38\x34\xa1\x9f\x81\xf6\x59\xcc\x34\x55" diff --git a/common/protob/check.py b/common/protob/check.py index 0b612d4e8..9c6468216 100755 --- a/common/protob/check.py +++ b/common/protob/check.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -from glob import glob import os import re import sys +from glob import glob error = False @@ -21,7 +21,9 @@ for fn in sorted(glob(os.path.join(MYDIR, "messages-*.proto"))): line = line.strip().split(" ") if line[0] not in ["enum", "message"]: continue - if not line[1].startswith(prefix) and not line[1].startswith("Debug" + prefix): + if not line[1].startswith(prefix) and not line[1].startswith( + "Debug" + prefix + ): print("ERROR:", fn, line[1]) error = True diff --git a/common/tools/coin_info.py b/common/tools/coin_info.py index 9ca8026af..df0880ebf 100755 --- a/common/tools/coin_info.py +++ b/common/tools/coin_info.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 -from collections import defaultdict, OrderedDict -import re -import os -import json import glob +import json import logging +import os +import re +from collections import OrderedDict, defaultdict try: import requests diff --git a/common/tools/coindef.py b/common/tools/coindef.py index e96246054..50eb50c79 100644 --- a/common/tools/coindef.py +++ b/common/tools/coindef.py @@ -3,38 +3,38 @@ from trezorlib import protobuf as p class CoinDef(p.MessageType): FIELDS = { - 1: ('coin_name', p.UnicodeType, 0), - 2: ('coin_shortcut', p.UnicodeType, 0), - 3: ('coin_label', p.UnicodeType, 0), - 4: ('curve_name', p.UnicodeType, 0), - 5: ('address_type', p.UVarintType, 0), - 6: ('address_type_p2sh', p.UVarintType, 0), - 7: ('maxfee_kb', p.UVarintType, 0), - 8: ('minfee_kb', p.UVarintType, 0), - 9: ('signed_message_header', p.BytesType, 0), - 10: ('hash_genesis_block', p.BytesType, 0), - 11: ('xprv_magic', p.UVarintType, 0), - 12: ('xpub_magic', p.UVarintType, 0), - 13: ('xpub_magic_segwit_p2sh', p.UVarintType, 0), - 14: ('xpub_magic_segwit_native', p.UVarintType, 0), - 15: ('bech32_prefix', p.UnicodeType, 0), - 16: ('cashaddr_prefix', p.UnicodeType, 0), - 17: ('slip44', p.UVarintType, 0), - 18: ('segwit', p.BoolType, 0), - 19: ('decred', p.BoolType, 0), - 20: ('fork_id', p.UVarintType, 0), - 21: ('force_bip143', p.BoolType, 0), - 22: ('dust_limit', p.UVarintType, 0), - 23: ('uri_prefix', p.UnicodeType, 0), - 24: ('min_address_length', p.UVarintType, 0), - 25: ('max_address_length', p.UVarintType, 0), - 26: ('icon', p.BytesType, 0), - 28: ('website', p.UnicodeType, 0), - 29: ('github', p.UnicodeType, 0), - 30: ('maintainer', p.UnicodeType, 0), - 31: ('blocktime_seconds', p.UVarintType, 0), - 32: ('bip115', p.BoolType, 0), - 33: ('cooldown', p.UVarintType, 0), + 1: ("coin_name", p.UnicodeType, 0), + 2: ("coin_shortcut", p.UnicodeType, 0), + 3: ("coin_label", p.UnicodeType, 0), + 4: ("curve_name", p.UnicodeType, 0), + 5: ("address_type", p.UVarintType, 0), + 6: ("address_type_p2sh", p.UVarintType, 0), + 7: ("maxfee_kb", p.UVarintType, 0), + 8: ("minfee_kb", p.UVarintType, 0), + 9: ("signed_message_header", p.BytesType, 0), + 10: ("hash_genesis_block", p.BytesType, 0), + 11: ("xprv_magic", p.UVarintType, 0), + 12: ("xpub_magic", p.UVarintType, 0), + 13: ("xpub_magic_segwit_p2sh", p.UVarintType, 0), + 14: ("xpub_magic_segwit_native", p.UVarintType, 0), + 15: ("bech32_prefix", p.UnicodeType, 0), + 16: ("cashaddr_prefix", p.UnicodeType, 0), + 17: ("slip44", p.UVarintType, 0), + 18: ("segwit", p.BoolType, 0), + 19: ("decred", p.BoolType, 0), + 20: ("fork_id", p.UVarintType, 0), + 21: ("force_bip143", p.BoolType, 0), + 22: ("dust_limit", p.UVarintType, 0), + 23: ("uri_prefix", p.UnicodeType, 0), + 24: ("min_address_length", p.UVarintType, 0), + 25: ("max_address_length", p.UVarintType, 0), + 26: ("icon", p.BytesType, 0), + 28: ("website", p.UnicodeType, 0), + 29: ("github", p.UnicodeType, 0), + 30: ("maintainer", p.UnicodeType, 0), + 31: ("blocktime_seconds", p.UVarintType, 0), + 32: ("bip115", p.BoolType, 0), + 33: ("cooldown", p.UVarintType, 0), } def __init__( @@ -73,7 +73,7 @@ class CoinDef(p.MessageType): default_fee_b: dict = None, bitcore: dict = None, blockbook: dict = None, - cooldown: int = None + cooldown: int = None, ): self.coin_name = coin_name self.coin_shortcut = coin_shortcut diff --git a/common/tools/coins_details.py b/common/tools/coins_details.py index a637fc2d5..e9bcd986b 100755 --- a/common/tools/coins_details.py +++ b/common/tools/coins_details.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 """Fetch information about coins and tokens supported by Trezor and update it in coins_details.json.""" -import os -import time import json import logging -import requests +import os import sys -import coin_info +import time import click +import requests + +import coin_info LOG = logging.getLogger(__name__) @@ -149,7 +150,7 @@ def summary(coins, api_key): try: ret = coinmarketcap_call("global-metrics/quotes/latest", api_key) total_marketcap = int(ret["data"]["quote"]["USD"]["total_market_cap"]) - except: + except Exception: pass return dict( diff --git a/common/tools/cointool.py b/common/tools/cointool.py index d9ad5526f..98ba22076 100755 --- a/common/tools/cointool.py +++ b/common/tools/cointool.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 import fnmatch +import glob import io import json import logging -import re -import sys import os -import glob +import re import struct +import sys import zlib from collections import defaultdict from hashlib import sha256 @@ -524,8 +524,7 @@ def cli(colors): # fmt: off @click.option("--backend/--no-backend", "-b", default=False, help="Check blockbook/bitcore responses") @click.option("--icons/--no-icons", default=True, help="Check icon files") -@click.option("-d", "--show-duplicates", type=click.Choice(("all", "nontoken", "errors")), - default="errors", help="How much information about duplicate shortcuts should be shown.") +@click.option("-d", "--show-duplicates", type=click.Choice(("all", "nontoken", "errors")), default="errors", help="How much information about duplicate shortcuts should be shown.") # fmt: on def check(backend, icons, show_duplicates): """Validate coin definitions. diff --git a/common/tools/diffize_coins_details.py b/common/tools/diffize_coins_details.py index 1e1a69796..2ad579a8f 100755 --- a/common/tools/diffize_coins_details.py +++ b/common/tools/diffize_coins_details.py @@ -1,13 +1,12 @@ #!/usr/bin/env python3 -import click import json import os -import requests -import tempfile import subprocess -import sys +import tempfile +import click +import requests LIVE_URL = "https://trezor.io/static/json/coins_details.json" COINS_DETAILS = os.path.join( diff --git a/common/tools/support.py b/common/tools/support.py index 593387eb5..57bf24d2b 100755 --- a/common/tools/support.py +++ b/common/tools/support.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 -import re +import json import os +import re import subprocess import sys + import click + import coin_info -import json SUPPORT_INFO = coin_info.get_support_data() diff --git a/core/Makefile b/core/Makefile index fb945738f..c684a6eb3 100644 --- a/core/Makefile +++ b/core/Makefile @@ -39,7 +39,7 @@ CFLAGS += -DGITREV=$(GITREV) ## help commands: help: ## show this help - @awk -f help.awk $(MAKEFILE_LIST) + @awk -f ../tools/help.awk $(MAKEFILE_LIST) ## dependencies commands: @@ -71,27 +71,6 @@ test_emu_monero: ## run selected monero device tests from monero-agent pylint: ## run pylint on application sources and tests pylint -E $(shell find src tests -name *.py) -## style commands: - -style_check: ## run code style check on application sources and tests - flake8 --version - isort --version | grep "VERSION" - black --version - flake8 $(shell find src -name *.py) - isort --check-only $(shell find src -name *.py ! -path 'src/trezor/messages/*') - black --check $(shell find src -name *.py ! -path 'src/trezor/messages/*') - -style: ## apply code style on application sources and tests - isort $(shell find src -name *.py ! -path 'src/trezor/messages/*') - black $(shell find src -name *.py ! -path 'src/trezor/messages/*') - -cstyle_check: ## run code style check on low-level C code - ./tools/clang-format-check embed/*/*.{c,h} embed/extmod/modtrezor*/*.{c,h} - - -cstyle: ## apply code style on low-level C code - clang-format -i embed/*/*.{c,h} embed/extmod/modtrezor*/*.{c,h} - ## code generation: templates: ## render Mako templates (for lists of coins, tokens, etc.) diff --git a/core/embed/extmod/modtrezorui/display-stm32_1.h b/core/embed/extmod/modtrezorui/display-stm32_1.h index cf3c82f2e..7b0593868 100644 --- a/core/embed/extmod/modtrezorui/display-stm32_1.h +++ b/core/embed/extmod/modtrezorui/display-stm32_1.h @@ -241,6 +241,4 @@ void display_refresh(void) { HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD } -const char *display_save(const char *prefix) { - return NULL; -} +const char *display_save(const char *prefix) { return NULL; } diff --git a/core/embed/extmod/modtrezorui/display-stm32_t.h b/core/embed/extmod/modtrezorui/display-stm32_t.h index 653c83da9..bedd24aa9 100644 --- a/core/embed/extmod/modtrezorui/display-stm32_t.h +++ b/core/embed/extmod/modtrezorui/display-stm32_t.h @@ -498,6 +498,4 @@ void display_refresh(void) { } } -const char *display_save(const char *prefix) { - return NULL; -} +const char *display_save(const char *prefix) { return NULL; } diff --git a/core/embed/unix/mpconfigport.h b/core/embed/unix/mpconfigport.h index 8619bf1a5..6f618d2b7 100644 --- a/core/embed/unix/mpconfigport.h +++ b/core/embed/unix/mpconfigport.h @@ -1,3 +1,5 @@ +// clang-format off + /* * This file is part of the MicroPython project, http://micropython.org/ * diff --git a/core/src/trezor/messages/__init__.py b/core/src/trezor/messages/__init__.py index 9e4ecb13a..95c9b6fa6 100644 --- a/core/src/trezor/messages/__init__.py +++ b/core/src/trezor/messages/__init__.py @@ -31,6 +31,6 @@ def get_type(wire_type): for msg_name in dir(MessageType): # Modules contain internal variables that may cause exception here. # No Message begins with underscore so it's safe to skip those. - if (msg_name[0] == '_'): + if msg_name[0] == "_": continue type_to_name[getattr(MessageType, msg_name)] = msg_name diff --git a/crypto/.clang-format b/crypto/.clang-format deleted file mode 100644 index 58d4b3b68..000000000 --- a/crypto/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ ---- -BasedOnStyle: Google diff --git a/crypto/tests/test_check_cardano.h b/crypto/tests/test_check_cardano.h index 434ea96b9..5fd830f24 100644 --- a/crypto/tests/test_check_cardano.h +++ b/crypto/tests/test_check_cardano.h @@ -5,82 +5,80 @@ START_TEST(test_ed25519_cardano_sign_vectors) { ed25519_secret_key secret_key_extension; ed25519_signature signature; - static const char - *vectors[] = - { - "6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5" - "3", // private key - "60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8" - "e", // private key extension - "64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe" - "1", // public key - "45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7" - "9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10" - "d", // signature - - "e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830" - "c", // private key - "794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a" - "4", // private key extension - "95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d" - "f", // public key - "f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1" - "9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560" - "f", // signature - - "9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0" - "c", // private key - "b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb" - "b", // private key extension - "79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19" - "f", // public key - "2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a" - "88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800" - "f", // signature - - "52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40" - "c", // private key - "6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580" - "3", // private key extension - "dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d" - "6", // public key - "0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6" - "2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160" - "2", // signature - - "11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0" - "4", // private key - "c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235" - "2", // private key extension - "839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7" - "8", // public key - "e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f" - "9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490" - "5", // signature - - "5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50" - "5", // private key - "ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c" - "d", // private key extension - "75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7" - "6", // public key - "631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb" - "c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890" - "6", // signature - - "624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50" - "d", // private key - "097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0" - "2", // private key extension - "0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0" - "0", // public key - "1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a" - "57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90" - "1", // signature - - 0, - 0, - }; + static const char *vectors[] = { + "6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5" + "3", // private key + "60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8" + "e", // private key extension + "64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe" + "1", // public key + "45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7" + "9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10" + "d", // signature + + "e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830" + "c", // private key + "794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a" + "4", // private key extension + "95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d" + "f", // public key + "f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1" + "9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560" + "f", // signature + + "9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0" + "c", // private key + "b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb" + "b", // private key extension + "79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19" + "f", // public key + "2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a" + "88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800" + "f", // signature + + "52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40" + "c", // private key + "6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580" + "3", // private key extension + "dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d" + "6", // public key + "0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6" + "2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160" + "2", // signature + + "11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0" + "4", // private key + "c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235" + "2", // private key extension + "839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7" + "8", // public key + "e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f" + "9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490" + "5", // signature + + "5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50" + "5", // private key + "ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c" + "d", // private key extension + "75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7" + "6", // public key + "631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb" + "c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890" + "6", // signature + + "624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50" + "d", // private key + "097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0" + "2", // private key extension + "0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0" + "0", // public key + "1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a" + "57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90" + "1", // signature + + 0, + 0, + }; const char **test_data; test_data = vectors; diff --git a/crypto/tests/test_curves.py b/crypto/tests/test_curves.py index 7056cb636..093f95ab0 100755 --- a/crypto/tests/test_curves.py +++ b/crypto/tests/test_curves.py @@ -5,10 +5,11 @@ import hashlib import os import random -import curve25519 import ecdsa import pytest +import curve25519 + def bytes2num(s): res = 0 @@ -30,48 +31,48 @@ class Point: points = [ Point( "secp256k1", - 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, - 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8, + 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, + 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8, ), Point( "secp256k1", 0x1, - 0x4218f20ae6c646b363db68605822fb14264ca8d2587fdd6fbc750d587e76a7ee, + 0x4218F20AE6C646B363DB68605822FB14264CA8D2587FDD6FBC750D587E76A7EE, ), Point( "secp256k1", 0x2, - 0x66fbe727b2ba09e09f5a98d70a5efce8424c5fa425bbda1c511f860657b8535e, + 0x66FBE727B2BA09E09F5A98D70A5EFCE8424C5FA425BBDA1C511F860657B8535E, ), Point( "secp256k1", - 0x1b, - 0x1adcea1cf831b0ad1653e769d1a229091d0cc68d4b0328691b9caacc76e37c90, + 0x1B, + 0x1ADCEA1CF831B0AD1653E769D1A229091D0CC68D4B0328691B9CAACC76E37C90, ), Point( "nist256p1", - 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, - 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, + 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296, + 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5, ), Point( "nist256p1", 0x0, - 0x66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4, + 0x66485C780E2F83D72433BD5D84A06BB6541C2AF31DAE871728BF856A174F93F4, ), Point( "nist256p1", 0x0, - 0x99b7a386f1d07c29dbcc42a27b5f9449abe3d50de25178e8d7407a95e8b06c0b, + 0x99B7A386F1D07C29DBCC42A27B5F9449ABE3D50DE25178E8D7407A95E8B06C0B, ), Point( "nist256p1", - 0xaf8bbdfe8cdd5577acbf345b543d28cf402f4e94d3865b97ea0787f2d3aa5d22, - 0x35802b8b376b995265918b078bc109c21a535176585c40f519aca52d6afc147c, + 0xAF8BBDFE8CDD5577ACBF345B543D28CF402F4E94D3865B97EA0787F2D3AA5D22, + 0x35802B8B376B995265918B078BC109C21A535176585C40F519ACA52D6AFC147C, ), Point( "nist256p1", 0x80000, - 0x580610071f440f0dcc14a22e2d5d5afc1224c0cd11a3b4b51b8ecd2224ee1ce2, + 0x580610071F440F0DCC14A22E2D5D5AFC1224C0CD11A3B4B51B8ECD2224EE1CE2, ), ] diff --git a/crypto/tests/test_wycheproof.py b/crypto/tests/test_wycheproof.py index 3bdedbfac..c449b29c8 100755 --- a/crypto/tests/test_wycheproof.py +++ b/crypto/tests/test_wycheproof.py @@ -102,7 +102,7 @@ def is_valid_der(data): try: structure, _ = der_decode(data) return data == der_encode(structure) - except: + except Exception: return False @@ -140,7 +140,7 @@ def parse_ec_pubkey(public_key): try: public_key = bytes(public_key["public_key"].asOctets()) - except: + except Exception: raise ParseError("Not a BER encoded named elliptic curve public key") return curve_name, public_key @@ -152,13 +152,13 @@ def parse_ecdsa256_signature(signature): raise ParseError("Not a valid DER") try: signature, _ = der_decode(signature, asn1Spec=EcSignature()) - except: + except Exception: raise ParseError("Not a valid DER encoded ECDSA signature") try: r = int(signature["r"]).to_bytes(32, byteorder="big") s = int(signature["s"]).to_bytes(32, byteorder="big") signature = r + s - except: + except Exception: raise ParseError("Not a valid DER encoded 256 bit ECDSA signature") return signature @@ -281,7 +281,7 @@ def aes_cbc_decrypt(key, iv, ciphertext): def load_json_testvectors(filename): try: result = json.loads(open(os.path.join(testvectors_directory, filename)).read()) - except: + except Exception: raise DataError() return result @@ -310,7 +310,7 @@ def generate_aes(filename): plaintext = unhexlify(test["msg"]) ciphertext = unhexlify(test["ct"]) result = parse_result(test["result"]) - except: + except Exception: raise DataError() if len(key) not in [128 / 8, 192 / 8, 256 / 8]: @@ -359,7 +359,7 @@ def generate_chacha_poly(filename): ciphertext = unhexlify(test["ct"]) tag = unhexlify(test["tag"]) result = parse_result(test["result"]) - except: + except Exception: raise DataError() if result is None: @@ -406,7 +406,7 @@ def generate_curve25519_dh(filename): private_key = unhexlify(test["private"]) shared = unhexlify(test["shared"]) result = parse_result(test["result"]) - except: + except Exception: raise DataError() if curve_name != "curve25519": @@ -448,7 +448,7 @@ def generate_ecdh(filename): private_key = parse_signed_hex(test["private"]) shared = unhexlify(test["shared"]) result = parse_result(test["result"]) - except: + except Exception: raise DataError() try: @@ -498,7 +498,7 @@ def generate_ecdsa(filename): try: public_key = unhexlify(test_group["keyDer"]) - except: + except Exception: raise DataError() try: @@ -521,7 +521,7 @@ def generate_ecdsa(filename): signature = unhexlify(test["sig"]) message = unhexlify(test["msg"]) result = parse_result(test["result"]) - except: + except Exception: raise DataError() if result is None: @@ -563,7 +563,7 @@ def generate_eddsa(filename): try: public_key = unhexlify(test_group["keyDer"]) - except: + except Exception: raise DataError() try: @@ -579,7 +579,7 @@ def generate_eddsa(filename): signature = unhexlify(test["sig"]) message = unhexlify(test["msg"]) result = parse_result(test["result"]) - except: + except Exception: raise DataError() if result is None: diff --git a/legacy/.clang-format b/legacy/.clang-format deleted file mode 100644 index 58d4b3b68..000000000 --- a/legacy/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ ---- -BasedOnStyle: Google diff --git a/legacy/bootloader/combine/prepare.py b/legacy/bootloader/combine/prepare.py index eb073e982..7918e063e 100755 --- a/legacy/bootloader/combine/prepare.py +++ b/legacy/bootloader/combine/prepare.py @@ -1,12 +1,12 @@ #!/usr/bin/env python from __future__ import print_function -bl = open('bl.bin').read() -fw = open('fw.bin').read() -combined = bl + fw[:256] + (32768-256)*'\x00' + fw[256:] +bl = open("bl.bin").read() +fw = open("fw.bin").read() +combined = bl + fw[:256] + (32768 - 256) * "\x00" + fw[256:] -open('combined.bin', 'w').write(combined) +open("combined.bin", "w").write(combined) -print('bootloader : %d bytes' % len(bl)) -print('firmware : %d bytes' % len(fw)) -print('combined : %d bytes' % len(combined)) +print("bootloader : %d bytes" % len(bl)) +print("firmware : %d bytes" % len(fw)) +print("combined : %d bytes" % len(combined)) diff --git a/legacy/bootloader/firmware_align.py b/legacy/bootloader/firmware_align.py index 3c1434987..0866593f5 100755 --- a/legacy/bootloader/firmware_align.py +++ b/legacy/bootloader/firmware_align.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import sys import os +import sys TOTALSIZE = 32768 MAXSIZE = TOTALSIZE - 32 @@ -8,7 +8,10 @@ MAXSIZE = TOTALSIZE - 32 fn = sys.argv[1] fs = os.stat(fn).st_size if fs > MAXSIZE: - raise Exception('bootloader has to be smaller than %d bytes (current size is %d)' % (MAXSIZE, fs)) -with open(fn, 'ab') as f: - f.write(b'\x00' * (TOTALSIZE - fs)) - f.close() + raise Exception( + "bootloader has to be smaller than %d bytes (current size is %d)" + % (MAXSIZE, fs) + ) +with open(fn, "ab") as f: + f.write(b"\x00" * (TOTALSIZE - fs)) + f.close() diff --git a/legacy/bootloader/firmware_sign.py b/legacy/bootloader/firmware_sign.py index a7b8e13cf..948a08f99 100755 --- a/legacy/bootloader/firmware_sign.py +++ b/legacy/bootloader/firmware_sign.py @@ -7,7 +7,6 @@ import struct import ecdsa - SLOTS = 3 pubkeys = { @@ -94,7 +93,7 @@ def update_hashes_in_header(data): data = bytearray(data) o = 0 for h in prepare_hashes(data[FWHEADER_SIZE:]): - data[0x20 + o:0x20 + o + 32] = h + data[0x20 + o : 0x20 + o + 32] = h o += 32 return bytes(data) @@ -112,6 +111,7 @@ def check_size(data): size = struct.unpack(" 32768: - raise Exception('bootloader has to be smaller than 32768 bytes') + raise Exception("bootloader has to be smaller than 32768 bytes") -data += b'\x00' * (32768 - len(data)) +data += b"\x00" * (32768 - len(data)) h = sha256(sha256(data).digest()).digest() -bl_hash = ', '.join('0x%02x' % x for x in bytearray(h)) -bl_data = ', '.join('0x%02x' % x for x in bytearray(data)) +bl_hash = ", ".join("0x%02x" % x for x in bytearray(h)) +bl_data = ", ".join("0x%02x" % x for x in bytearray(data)) -with open('bl_data.h', 'wt') as f: - f.write('static const uint8_t bl_hash[32] = {%s};\n' % bl_hash) - f.write('static const uint8_t bl_data[32768] = {%s};\n' % bl_data) +with open("bl_data.h", "wt") as f: + f.write("static const uint8_t bl_hash[32] = {%s};\n" % bl_hash) + f.write("static const uint8_t bl_data[32768] = {%s};\n" % bl_data) diff --git a/legacy/firmware/fsm_msg_common.h b/legacy/firmware/fsm_msg_common.h index 265b629d4..e8c4c447d 100644 --- a/legacy/firmware/fsm_msg_common.h +++ b/legacy/firmware/fsm_msg_common.h @@ -256,12 +256,12 @@ void fsm_msgEntropyAck(const EntropyAck *msg) { } void fsm_msgBackupDevice(const BackupDevice *msg) { + (void)msg; + CHECK_INITIALIZED CHECK_PIN_UNCACHED - (void) - msg; char mnemonic[MAX_MNEMONIC_LEN + 1]; if (config_getMnemonic(mnemonic, sizeof(mnemonic))) { reset_backup(true, mnemonic); diff --git a/legacy/firmware/protob/messages_map.py b/legacy/firmware/protob/messages_map.py index c8c763047..3bb9d4a5e 100755 --- a/legacy/firmware/protob/messages_map.py +++ b/legacy/firmware/protob/messages_map.py @@ -1,11 +1,16 @@ #!/usr/bin/env python import sys - from collections import defaultdict -from messages_pb2 import MessageType -from messages_pb2 import wire_in, wire_out -from messages_pb2 import wire_debug_in, wire_debug_out -from messages_pb2 import wire_bootloader, wire_no_fsm + +from messages_pb2 import ( + MessageType, + wire_bootloader, + wire_debug_in, + wire_debug_out, + wire_in, + wire_no_fsm, + wire_out, +) fh = open("messages_map.h", "wt") fl = open("messages_map_limits.h", "wt") @@ -24,7 +29,7 @@ LABELS = { def handle_message(fh, fl, skipped, message, extension): name = message.name short_name = name.split("MessageType_", 1).pop() - assert(short_name != name) + assert short_name != name for s in skipped: if short_name.startswith(s): @@ -37,14 +42,14 @@ def handle_message(fh, fl, skipped, message, extension): bootloader = options.Extensions[wire_bootloader] no_fsm = options.Extensions[wire_no_fsm] - if getattr(options, 'deprecated', None): - fh.write('\t// Message %s is deprecated\n' % short_name) + if getattr(options, "deprecated", None): + fh.write("\t// Message %s is deprecated\n" % short_name) return if bootloader: - fh.write('\t// Message %s is used in bootloader mode only\n' % short_name) + fh.write("\t// Message %s is used in bootloader mode only\n" % short_name) return if no_fsm: - fh.write('\t// Message %s is not used in FSM\n' % short_name) + fh.write("\t// Message %s is not used in FSM\n" % short_name) return if direction == "i": @@ -52,13 +57,15 @@ def handle_message(fh, fl, skipped, message, extension): else: process_func = "0" - fh.write(TEMPLATE.format( - type="'%c'," % interface, - dir="'%c'," % direction, - msg_id="MessageType_%s," % name, - fields="%s_fields," % short_name, - process_func=process_func, - )) + fh.write( + TEMPLATE.format( + type="'%c'," % interface, + dir="'%c'," % direction, + msg_id="MessageType_%s," % name, + fields="%s_fields," % short_name, + process_func=process_func, + ) + ) bufsize = None t = interface + direction @@ -69,13 +76,20 @@ def handle_message(fh, fl, skipped, message, extension): elif t == "do": bufsize = "MSG_DEBUG_OUT_SIZE" if bufsize: - fl.write("_Static_assert(%s >= sizeof(%s), \"msg buffer too small\");\n" % (bufsize, short_name)) + fl.write( + '_Static_assert(%s >= sizeof(%s), "msg buffer too small");\n' + % (bufsize, short_name) + ) skipped = sys.argv[1:] -fh.write("\t// This file is automatically generated by messages_map.py -- DO NOT EDIT!\n") -fl.write("// This file is automatically generated by messages_map.py -- DO NOT EDIT!\n\n") +fh.write( + "\t// This file is automatically generated by messages_map.py -- DO NOT EDIT!\n" +) +fl.write( + "// This file is automatically generated by messages_map.py -- DO NOT EDIT!\n\n" +) messages = defaultdict(list) diff --git a/legacy/firmware/u2f/u2f.h b/legacy/firmware/u2f/u2f.h index b06771396..865778d33 100644 --- a/legacy/firmware/u2f/u2f.h +++ b/legacy/firmware/u2f/u2f.h @@ -1,3 +1,4 @@ +// clang-format off /** * Copyright FIDO Alliance, 2017 * diff --git a/legacy/firmware/u2f/u2f_hid.h b/legacy/firmware/u2f/u2f_hid.h index f29059da2..39586cdd6 100644 --- a/legacy/firmware/u2f/u2f_hid.h +++ b/legacy/firmware/u2f/u2f_hid.h @@ -1,3 +1,4 @@ +// clang-format off /** * Copyright FIDO Alliance, 2017 * diff --git a/legacy/gen/bitmaps.c b/legacy/gen/bitmaps.c index 5d60730d1..c47c1a0bd 100644 --- a/legacy/gen/bitmaps.c +++ b/legacy/gen/bitmaps.c @@ -1,3 +1,4 @@ +// clang-format off #include "bitmaps.h" const uint8_t bmp_digit0_data[] = { 0xff, 0xff, 0xf8, 0x1f, 0xf0, 0x0f, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xe1, 0x87, 0xf0, 0x0f, 0xf8, 0x1f, 0xff, 0xff, }; diff --git a/legacy/gen/bitmaps.h b/legacy/gen/bitmaps.h index c06351db0..41bc1507d 100644 --- a/legacy/gen/bitmaps.h +++ b/legacy/gen/bitmaps.h @@ -4,8 +4,8 @@ #include typedef struct { - uint8_t width, height; - const uint8_t *data; + uint8_t width, height; + const uint8_t *data; } BITMAP; extern const BITMAP bmp_digit0; diff --git a/legacy/gen/bitmaps/generate.py b/legacy/gen/bitmaps/generate.py index d0005427c..0e23ae435 100755 --- a/legacy/gen/bitmaps/generate.py +++ b/legacy/gen/bitmaps/generate.py @@ -1,58 +1,64 @@ #!/usr/bin/env python3 import glob import os + from PIL import Image hdrs = [] data = [] imgs = [] + def encode_pixels(img): - r = '' - img = [ (x[0] + x[1] + x[2] > 384 and '1' or '0') for x in img] - for i in range(len(img) // 8): - c = ''.join(img[i * 8 : i * 8 + 8]) - r += '0x%02x, ' % int(c, 2) - return r + r = "" + img = [(x[0] + x[1] + x[2] > 384 and "1" or "0") for x in img] + for i in range(len(img) // 8): + c = "".join(img[i * 8 : i * 8 + 8]) + r += "0x%02x, " % int(c, 2) + return r + cnt = 0 -for fn in sorted(glob.glob('*.png')): - print('Processing:', fn) - im = Image.open(fn) - name = os.path.splitext(fn)[0] - w, h = im.size - if w % 8 != 0: - raise Exception('Width must be divisable by 8! (%s is %dx%d)' % (fn, w, h)) - img = list(im.getdata()) - hdrs.append('extern const BITMAP bmp_%s;\n' % name) - imgs.append('const BITMAP bmp_%s = {%d, %d, bmp_%s_data};\n' % (name, w, h, name)) - data.append('const uint8_t bmp_%s_data[] = { %s};\n' % (name, encode_pixels(img))) - cnt += 1 - -with open('../bitmaps.c', 'wt') as f: - f.write('#include "bitmaps.h"\n\n') - for i in range(cnt): - f.write(data[i]) - f.write('\n') - for i in range(cnt): - f.write(imgs[i]) - f.close() - -with open('../bitmaps.h', 'wt') as f: - f.write('''#ifndef __BITMAPS_H__ +for fn in sorted(glob.glob("*.png")): + print("Processing:", fn) + im = Image.open(fn) + name = os.path.splitext(fn)[0] + w, h = im.size + if w % 8 != 0: + raise Exception("Width must be divisable by 8! (%s is %dx%d)" % (fn, w, h)) + img = list(im.getdata()) + hdrs.append("extern const BITMAP bmp_%s;\n" % name) + imgs.append("const BITMAP bmp_%s = {%d, %d, bmp_%s_data};\n" % (name, w, h, name)) + data.append("const uint8_t bmp_%s_data[] = { %s};\n" % (name, encode_pixels(img))) + cnt += 1 + +with open("../bitmaps.c", "wt") as f: + f.write("// clang-format off\n") + f.write('#include "bitmaps.h"\n\n') + for i in range(cnt): + f.write(data[i]) + f.write("\n") + for i in range(cnt): + f.write(imgs[i]) + f.close() + +with open("../bitmaps.h", "wt") as f: + f.write( + """#ifndef __BITMAPS_H__ #define __BITMAPS_H__ #include typedef struct { - uint8_t width, height; - const uint8_t *data; + uint8_t width, height; + const uint8_t *data; } BITMAP; -''') +""" + ) - for i in range(cnt): - f.write(hdrs[i]) + for i in range(cnt): + f.write(hdrs[i]) - f.write('\n#endif\n') - f.close() + f.write("\n#endif\n") + f.close() diff --git a/legacy/gen/fonts.c b/legacy/gen/fonts.c index 68deb549b..5bcf305a4 100644 --- a/legacy/gen/fonts.c +++ b/legacy/gen/fonts.c @@ -1,18 +1,16 @@ #include "fonts.h" -const uint8_t * const font_data[2][128] = { - { -#include"font.inc" - }, - { -#include"fontfixed.inc" - }, +const uint8_t *const font_data[2][128] = { + { +#include "font.inc" + }, + { +#include "fontfixed.inc" + }, }; -int fontCharWidth(int font, char c) { - return font_data[font][c & 0x7f][0]; -} +int fontCharWidth(int font, char c) { return font_data[font][c & 0x7f][0]; } const uint8_t *fontCharData(int font, char c) { - return font_data[font][c & 0x7f] + 1; + return font_data[font][c & 0x7f] + 1; } diff --git a/legacy/gen/fonts.h b/legacy/gen/fonts.h index dbbbef130..2c1a9b2a5 100644 --- a/legacy/gen/fonts.h +++ b/legacy/gen/fonts.h @@ -5,10 +5,10 @@ #define FONT_HEIGHT 8 #define FONT_STANDARD 0 -#define FONT_FIXED 1 -#define FONT_DOUBLE 0x80 +#define FONT_FIXED 1 +#define FONT_DOUBLE 0x80 -extern const uint8_t * const font_data[2][128]; +extern const uint8_t *const font_data[2][128]; int fontCharWidth(int font, char c); const uint8_t *fontCharData(int font, char c); diff --git a/legacy/gen/fonts/generate.py b/legacy/gen/fonts/generate.py index 3299138c7..463d73e63 100755 --- a/legacy/gen/fonts/generate.py +++ b/legacy/gen/fonts/generate.py @@ -1,39 +1,40 @@ #!/usr/bin/env python3 from PIL import Image -class Img(object): +class Img(object): def __init__(self, fn): im = Image.open(fn) self.w, self.h = im.size self.data = list(im.getdata()) def pixel(self, r, c): - p = self.data[ r + c * self.w ] + p = self.data[r + c * self.w] if p == (255, 255, 255): - return '0' + return "0" if p == (0, 0, 0): - return '1' + return "1" if p == (255, 0, 255): return None - raise Exception('Unknown color', p) + raise Exception("Unknown color", p) def convert(imgfile, outfile): img = Img(imgfile) - cur = '' - with open(outfile, 'w') as f: + cur = "" + with open(outfile, "w") as f: for i in range(128): x = (i % 16) * 10 y = (i // 16) * 10 - cur = '' - while img.pixel(x, y) != None: - val = ''.join(img.pixel(x, y + j) for j in range(8)) + cur = "" + while img.pixel(x, y) is not None: + val = "".join(img.pixel(x, y + j) for j in range(8)) x += 1 - cur += '\\x%02x' % int(val, 2) - cur = '\\x%02x' % (len(cur) // 4) + cur - ch = chr(i) if i >= 32 and i <= 126 else '_' - f.write('\t/* 0x%02x %c */ (uint8_t *)"%s",\n' % (i, ch , cur)) + cur += "\\x%02x" % int(val, 2) + cur = "\\x%02x" % (len(cur) // 4) + cur + ch = chr(i) if i >= 32 and i <= 126 else "_" + f.write('\t/* 0x%02x %c */ (uint8_t *)"%s",\n' % (i, ch, cur)) + -convert('fonts/fontfixed.png', 'fontfixed.inc') -convert('fonts/font.png', 'font.inc') +convert("fonts/fontfixed.png", "fontfixed.inc") +convert("fonts/font.png", "font.inc") diff --git a/legacy/gen/handlers/handlers.py b/legacy/gen/handlers/handlers.py index 5e7961067..7d5802af0 100755 --- a/legacy/gen/handlers/handlers.py +++ b/legacy/gen/handlers/handlers.py @@ -2,99 +2,102 @@ from __future__ import print_function handlers = [ - 'hard_fault_handler', - 'mem_manage_handler', - 'bus_fault_handler', - 'usage_fault_handler', - 'nvic_wwdg_isr', - 'pvd_isr', - 'tamp_stamp_isr', - 'rtc_wkup_isr', - 'flash_isr', - 'rcc_isr', - 'exti0_isr', - 'exti1_isr', - 'exti2_isr', - 'exti3_isr', - 'exti4_isr', - 'dma1_stream0_isr', - 'dma1_stream1_isr', - 'dma1_stream2_isr', - 'dma1_stream3_isr', - 'dma1_stream4_isr', - 'dma1_stream5_isr', - 'dma1_stream6_isr', - 'adc_isr', - 'can1_tx_isr', - 'can1_rx0_isr', - 'can1_rx1_isr', - 'can1_sce_isr', - 'exti9_5_isr', - 'tim1_brk_tim9_isr', - 'tim1_up_tim10_isr', - 'tim1_trg_com_tim11_isr', - 'tim1_cc_isr', - 'tim2_isr', - 'tim3_isr', - 'tim4_isr', - 'i2c1_ev_isr', - 'i2c1_er_isr', - 'i2c2_ev_isr', - 'i2c2_er_isr', - 'spi1_isr', - 'spi2_isr', - 'usart1_isr', - 'usart2_isr', - 'usart3_isr', - 'exti15_10_isr', - 'rtc_alarm_isr', - 'usb_fs_wkup_isr', - 'tim8_brk_tim12_isr', - 'tim8_up_tim13_isr', - 'tim8_trg_com_tim14_isr', - 'tim8_cc_isr', - 'dma1_stream7_isr', - 'fsmc_isr', - 'sdio_isr', - 'tim5_isr', - 'spi3_isr', - 'uart4_isr', - 'uart5_isr', - 'tim6_dac_isr', - 'tim7_isr', - 'dma2_stream0_isr', - 'dma2_stream1_isr', - 'dma2_stream2_isr', - 'dma2_stream3_isr', - 'dma2_stream4_isr', - 'eth_isr', - 'eth_wkup_isr', - 'can2_tx_isr', - 'can2_rx0_isr', - 'can2_rx1_isr', - 'can2_sce_isr', - 'otg_fs_isr', - 'dma2_stream5_isr', - 'dma2_stream6_isr', - 'dma2_stream7_isr', - 'usart6_isr', - 'i2c3_ev_isr', - 'i2c3_er_isr', - 'otg_hs_ep1_out_isr', - 'otg_hs_ep1_in_isr', - 'otg_hs_wkup_isr', - 'otg_hs_isr', - 'dcmi_isr', - 'cryp_isr', - 'hash_rng_isr', + "hard_fault_handler", + "mem_manage_handler", + "bus_fault_handler", + "usage_fault_handler", + "nvic_wwdg_isr", + "pvd_isr", + "tamp_stamp_isr", + "rtc_wkup_isr", + "flash_isr", + "rcc_isr", + "exti0_isr", + "exti1_isr", + "exti2_isr", + "exti3_isr", + "exti4_isr", + "dma1_stream0_isr", + "dma1_stream1_isr", + "dma1_stream2_isr", + "dma1_stream3_isr", + "dma1_stream4_isr", + "dma1_stream5_isr", + "dma1_stream6_isr", + "adc_isr", + "can1_tx_isr", + "can1_rx0_isr", + "can1_rx1_isr", + "can1_sce_isr", + "exti9_5_isr", + "tim1_brk_tim9_isr", + "tim1_up_tim10_isr", + "tim1_trg_com_tim11_isr", + "tim1_cc_isr", + "tim2_isr", + "tim3_isr", + "tim4_isr", + "i2c1_ev_isr", + "i2c1_er_isr", + "i2c2_ev_isr", + "i2c2_er_isr", + "spi1_isr", + "spi2_isr", + "usart1_isr", + "usart2_isr", + "usart3_isr", + "exti15_10_isr", + "rtc_alarm_isr", + "usb_fs_wkup_isr", + "tim8_brk_tim12_isr", + "tim8_up_tim13_isr", + "tim8_trg_com_tim14_isr", + "tim8_cc_isr", + "dma1_stream7_isr", + "fsmc_isr", + "sdio_isr", + "tim5_isr", + "spi3_isr", + "uart4_isr", + "uart5_isr", + "tim6_dac_isr", + "tim7_isr", + "dma2_stream0_isr", + "dma2_stream1_isr", + "dma2_stream2_isr", + "dma2_stream3_isr", + "dma2_stream4_isr", + "eth_isr", + "eth_wkup_isr", + "can2_tx_isr", + "can2_rx0_isr", + "can2_rx1_isr", + "can2_sce_isr", + "otg_fs_isr", + "dma2_stream5_isr", + "dma2_stream6_isr", + "dma2_stream7_isr", + "usart6_isr", + "i2c3_ev_isr", + "i2c3_er_isr", + "otg_hs_ep1_out_isr", + "otg_hs_ep1_in_isr", + "otg_hs_wkup_isr", + "otg_hs_isr", + "dcmi_isr", + "cryp_isr", + "hash_rng_isr", ] -with open('handlers.c', 'wt') as f: - f.write('#include "layout.h"\n') - f.write('#include "oled.h"\n\n') - for i in handlers: - f.write('void __attribute__((noreturn)) %s(void)\n' % i) - f.write('{\n') - f.write('\tlayoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Encountered", NULL, "%s", NULL, "Please restart", "the device.");\n' % i.upper()) - f.write('\tfor (;;) {} // loop forever\n') - f.write('}\n\n') +with open("handlers.c", "wt") as f: + f.write('#include "layout.h"\n') + f.write('#include "oled.h"\n\n') + for i in handlers: + f.write("void __attribute__((noreturn)) %s(void)\n" % i) + f.write("{\n") + f.write( + '\tlayoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Encountered", NULL, "%s", NULL, "Please restart", "the device.");\n' + % i.upper() + ) + f.write("\tfor (;;) {} // loop forever\n") + f.write("}\n\n") diff --git a/legacy/gen/strwidth.c b/legacy/gen/strwidth.c index 8ba3f1c36..c7c012594 100644 --- a/legacy/gen/strwidth.c +++ b/legacy/gen/strwidth.c @@ -1,35 +1,35 @@ +#include +#include #include #include -#include -#include #include "fonts.h" static inline char convert(char c) { - if (c < 0x80) { - return c; - } else if (c >= 0xC0) { - return '_'; - } else { - return '\0'; - } + if (c < 0x80) { + return c; + } else if (c >= 0xC0) { + return '_'; + } else { + return '\0'; + } } int main(int argc, char **argv) { - char *line; - int font = FONT_STANDARD; - while ((line = readline(NULL)) != NULL) { - size_t length = strlen(line); - if (length) { - add_history(line); - } + char *line; + int font = FONT_STANDARD; + while ((line = readline(NULL)) != NULL) { + size_t length = strlen(line); + if (length) { + add_history(line); + } - size_t width = 0; - for (size_t i = 0; i < length; i++) { - width += fontCharWidth(font, convert(line[i])) + 1; - } + size_t width = 0; + for (size_t i = 0; i < length; i++) { + width += fontCharWidth(font, convert(line[i])) + 1; + } - printf("%zu\n", width); - free(line); - } + printf("%zu\n", width); + free(line); + } } diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 000000000..60d212f45 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,35 @@ +[flake8] +ignore = + # E203 whitespace before ':' + E203, + # E221: multiple spaces before operator + E221, + # E241: multiple spaces after ':' + E241, + # E402: module level import not at top of file + E402, + # E501: line too long + E501, + # E741 ambiguous variable name + E741, + # F403: star import used, unable to detect undefined names + F403, + # F405: name may be undefined, or defined from star imports + F405, + # W503: line break before binary operator + W503 + +[isort] +multi_line_output = 3 +include_trailing_comma = True +force_grid_wrap = 0 +combine_as_imports = True +line_length = 88 +not_skip=__init__.py +forced_separate = apps +known_standard_library = micropython,ubinascii,ustruct,uctypes,utime,utimeq,trezorio,trezorui,trezorutils,trezorconfig + +[tool:pytest] +addopts = --pyargs trezorlib.tests.device_tests +xfail_strict = true +run_xfail = diff --git a/storage/norcow.c b/storage/norcow.c index 3ef5d6f9c..d0a845c52 100644 --- a/storage/norcow.c +++ b/storage/norcow.c @@ -19,33 +19,35 @@ #include -#include "norcow.h" -#include "flash.h" #include "common.h" +#include "flash.h" +#include "norcow.h" // NRC2 = 4e524332 -#define NORCOW_MAGIC ((uint32_t)0x3243524e) +#define NORCOW_MAGIC ((uint32_t)0x3243524e) // NRCW = 4e524357 -#define NORCOW_MAGIC_V0 ((uint32_t)0x5743524e) +#define NORCOW_MAGIC_V0 ((uint32_t)0x5743524e) -#define NORCOW_WORD_SIZE (sizeof(uint32_t)) +#define NORCOW_WORD_SIZE (sizeof(uint32_t)) #define NORCOW_PREFIX_LEN NORCOW_WORD_SIZE -#define NORCOW_MAGIC_LEN NORCOW_WORD_SIZE +#define NORCOW_MAGIC_LEN NORCOW_WORD_SIZE #define NORCOW_VERSION_LEN NORCOW_WORD_SIZE // The key value which is used to indicate that the entry is not set. -#define NORCOW_KEY_FREE (0xFFFF) +#define NORCOW_KEY_FREE (0xFFFF) // The key value which is used to indicate that the entry has been deleted. #define NORCOW_KEY_DELETED (0x0000) // The offset from the beginning of the sector where stored items start. -#define NORCOW_STORAGE_START (NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN + NORCOW_VERSION_LEN) +#define NORCOW_STORAGE_START \ + (NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN + NORCOW_VERSION_LEN) // Map from sector index to sector number. static const uint8_t norcow_sectors[NORCOW_SECTOR_COUNT] = NORCOW_SECTORS; -// The index of the active reading sector and writing sector. These should be equal except when storage version upgrade or compaction is in progress. +// The index of the active reading sector and writing sector. These should be +// equal except when storage version upgrade or compaction is in progress. static uint8_t norcow_active_sector = 0; static uint8_t norcow_write_sector = 0; @@ -59,76 +61,79 @@ static uint32_t norcow_free_offset = 0; * Returns pointer to sector, starting with offset * Fails when there is not enough space for data of given size */ -static const void *norcow_ptr(uint8_t sector, uint32_t offset, uint32_t size) -{ - ensure(sectrue * (sector <= NORCOW_SECTOR_COUNT), "invalid sector"); - return flash_get_address(norcow_sectors[sector], offset, size); +static const void *norcow_ptr(uint8_t sector, uint32_t offset, uint32_t size) { + ensure(sectrue * (sector <= NORCOW_SECTOR_COUNT), "invalid sector"); + return flash_get_address(norcow_sectors[sector], offset, size); } /* * Writes data to given sector, starting from offset */ -static secbool norcow_write(uint8_t sector, uint32_t offset, uint32_t prefix, const uint8_t *data, uint16_t len) -{ - if (sector >= NORCOW_SECTOR_COUNT) { - return secfalse; - } +static secbool norcow_write(uint8_t sector, uint32_t offset, uint32_t prefix, + const uint8_t *data, uint16_t len) { + if (sector >= NORCOW_SECTOR_COUNT) { + return secfalse; + } - if (offset + NORCOW_PREFIX_LEN + len > NORCOW_SECTOR_SIZE) { - return secfalse; - } + if (offset + NORCOW_PREFIX_LEN + len > NORCOW_SECTOR_SIZE) { + return secfalse; + } - ensure(flash_unlock_write(), NULL); + ensure(flash_unlock_write(), NULL); - // write prefix - ensure(flash_write_word(norcow_sectors[sector], offset, prefix), NULL); - offset += NORCOW_PREFIX_LEN; + // write prefix + ensure(flash_write_word(norcow_sectors[sector], offset, prefix), NULL); + offset += NORCOW_PREFIX_LEN; - if (data != NULL) { - // write data - for (uint16_t i = 0; i < len; i++, offset++) { - ensure(flash_write_byte(norcow_sectors[sector], offset, data[i]), NULL); - } - } else { - offset += len; + if (data != NULL) { + // write data + for (uint16_t i = 0; i < len; i++, offset++) { + ensure(flash_write_byte(norcow_sectors[sector], offset, data[i]), NULL); } + } else { + offset += len; + } - // pad with zeroes - for (; offset % NORCOW_WORD_SIZE; offset++) { - ensure(flash_write_byte(norcow_sectors[sector], offset, 0x00), NULL); - } + // pad with zeroes + for (; offset % NORCOW_WORD_SIZE; offset++) { + ensure(flash_write_byte(norcow_sectors[sector], offset, 0x00), NULL); + } - ensure(flash_lock_write(), NULL); - return sectrue; + ensure(flash_lock_write(), NULL); + return sectrue; } /* * Erases sector (and sets a magic) */ -static void erase_sector(uint8_t sector, secbool set_magic) -{ +static void erase_sector(uint8_t sector, secbool set_magic) { #if NORCOW_HEADER_LEN > 0 - // Backup the sector header. - uint32_t header_backup[NORCOW_HEADER_LEN/sizeof(uint32_t)]; - const void *sector_start = norcow_ptr(sector, 0, NORCOW_HEADER_LEN); - memcpy(header_backup, sector_start, sizeof(header_backup)); + // Backup the sector header. + uint32_t header_backup[NORCOW_HEADER_LEN / sizeof(uint32_t)]; + const void *sector_start = norcow_ptr(sector, 0, NORCOW_HEADER_LEN); + memcpy(header_backup, sector_start, sizeof(header_backup)); #endif - ensure(flash_erase(norcow_sectors[sector]), "erase failed"); + ensure(flash_erase(norcow_sectors[sector]), "erase failed"); #if NORCOW_HEADER_LEN > 0 - // Copy the sector header back. - ensure(flash_unlock_write(), NULL); - for (uint32_t i = 0; i < NORCOW_HEADER_LEN/sizeof(uint32_t); ++i) { - ensure(flash_write_word(norcow_sectors[sector], i*sizeof(uint32_t), header_backup[i]), NULL); - } - ensure(flash_lock_write(), NULL); + // Copy the sector header back. + ensure(flash_unlock_write(), NULL); + for (uint32_t i = 0; i < NORCOW_HEADER_LEN / sizeof(uint32_t); ++i) { + ensure(flash_write_word(norcow_sectors[sector], i * sizeof(uint32_t), + header_backup[i]), + NULL); + } + ensure(flash_lock_write(), NULL); #endif - if (sectrue == set_magic) { - ensure(norcow_write(sector, NORCOW_HEADER_LEN, NORCOW_MAGIC, NULL, 0), "set magic failed"); - ensure(norcow_write(sector, NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN, ~NORCOW_VERSION, NULL, 0), "set version failed"); - } + if (sectrue == set_magic) { + ensure(norcow_write(sector, NORCOW_HEADER_LEN, NORCOW_MAGIC, NULL, 0), + "set magic failed"); + ensure(norcow_write(sector, NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN, + ~NORCOW_VERSION, NULL, 0), + "set version failed"); + } } #define ALIGN4(X) (X) = ((X) + 3) & ~3 @@ -136,263 +141,262 @@ static void erase_sector(uint8_t sector, secbool set_magic) /* * Reads one item starting from offset */ -static secbool read_item(uint8_t sector, uint32_t offset, uint16_t *key, const void **val, uint16_t *len, uint32_t *pos) -{ - *pos = offset; - - const void *k = norcow_ptr(sector, *pos, 2); - if (k == NULL) return secfalse; - *pos += 2; - memcpy(key, k, sizeof(uint16_t)); - if (*key == NORCOW_KEY_FREE) { - return secfalse; - } - - const void *l = norcow_ptr(sector, *pos, 2); - if (l == NULL) return secfalse; - *pos += 2; - memcpy(len, l, sizeof(uint16_t)); - - *val = norcow_ptr(sector, *pos, *len); - if (*val == NULL) return secfalse; - *pos += *len; - ALIGN4(*pos); - return sectrue; +static secbool read_item(uint8_t sector, uint32_t offset, uint16_t *key, + const void **val, uint16_t *len, uint32_t *pos) { + *pos = offset; + + const void *k = norcow_ptr(sector, *pos, 2); + if (k == NULL) return secfalse; + *pos += 2; + memcpy(key, k, sizeof(uint16_t)); + if (*key == NORCOW_KEY_FREE) { + return secfalse; + } + + const void *l = norcow_ptr(sector, *pos, 2); + if (l == NULL) return secfalse; + *pos += 2; + memcpy(len, l, sizeof(uint16_t)); + + *val = norcow_ptr(sector, *pos, *len); + if (*val == NULL) return secfalse; + *pos += *len; + ALIGN4(*pos); + return sectrue; } /* * Writes one item starting from offset */ -static secbool write_item(uint8_t sector, uint32_t offset, uint16_t key, const void *val, uint16_t len, uint32_t *pos) -{ - uint32_t prefix = ((uint32_t)len << 16) | key; - *pos = offset + NORCOW_PREFIX_LEN + len; - ALIGN4(*pos); - return norcow_write(sector, offset, prefix, val, len); +static secbool write_item(uint8_t sector, uint32_t offset, uint16_t key, + const void *val, uint16_t len, uint32_t *pos) { + uint32_t prefix = ((uint32_t)len << 16) | key; + *pos = offset + NORCOW_PREFIX_LEN + len; + ALIGN4(*pos); + return norcow_write(sector, offset, prefix, val, len); } /* * Finds the offset from the beginning of the sector where stored items start. */ -static secbool find_start_offset(uint8_t sector, uint32_t *offset, uint32_t *version) -{ - const uint32_t *magic = norcow_ptr(sector, NORCOW_HEADER_LEN, NORCOW_MAGIC_LEN + NORCOW_VERSION_LEN); - if (magic == NULL) { - return secfalse; - } - - if (*magic == NORCOW_MAGIC) { - *offset = NORCOW_STORAGE_START; - *version = ~(magic[1]); - } else if (*magic == NORCOW_MAGIC_V0) { - *offset = NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN; - *version = 0; - } else { - return secfalse; - } +static secbool find_start_offset(uint8_t sector, uint32_t *offset, + uint32_t *version) { + const uint32_t *magic = norcow_ptr(sector, NORCOW_HEADER_LEN, + NORCOW_MAGIC_LEN + NORCOW_VERSION_LEN); + if (magic == NULL) { + return secfalse; + } + + if (*magic == NORCOW_MAGIC) { + *offset = NORCOW_STORAGE_START; + *version = ~(magic[1]); + } else if (*magic == NORCOW_MAGIC_V0) { + *offset = NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN; + *version = 0; + } else { + return secfalse; + } - return sectrue; + return sectrue; } /* * Finds item in given sector */ -static secbool find_item(uint8_t sector, uint16_t key, const void **val, uint16_t *len) -{ - *val = NULL; - *len = 0; - - uint32_t offset; - uint32_t version; - if (sectrue != find_start_offset(sector, &offset, &version)) { - return secfalse; +static secbool find_item(uint8_t sector, uint16_t key, const void **val, + uint16_t *len) { + *val = NULL; + *len = 0; + + uint32_t offset; + uint32_t version; + if (sectrue != find_start_offset(sector, &offset, &version)) { + return secfalse; + } + + for (;;) { + uint16_t k, l; + const void *v; + uint32_t pos; + if (sectrue != read_item(sector, offset, &k, &v, &l, &pos)) { + break; } - - for (;;) { - uint16_t k, l; - const void *v; - uint32_t pos; - if (sectrue != read_item(sector, offset, &k, &v, &l, &pos)) { - break; - } - if (key == k) { - *val = v; - *len = l; - } - offset = pos; + if (key == k) { + *val = v; + *len = l; } - return sectrue * (*val != NULL); + offset = pos; + } + return sectrue * (*val != NULL); } /* * Finds first unused offset in given sector */ -static uint32_t find_free_offset(uint8_t sector) -{ - uint32_t offset; - uint32_t version; - if (sectrue != find_start_offset(sector, &offset, &version)) { - return secfalse; - } - - for (;;) { - uint16_t key, len; - const void *val; - uint32_t pos; - if (sectrue != read_item(sector, offset, &key, &val, &len, &pos)) { - break; - } - offset = pos; +static uint32_t find_free_offset(uint8_t sector) { + uint32_t offset; + uint32_t version; + if (sectrue != find_start_offset(sector, &offset, &version)) { + return secfalse; + } + + for (;;) { + uint16_t key, len; + const void *val; + uint32_t pos; + if (sectrue != read_item(sector, offset, &key, &val, &len, &pos)) { + break; } - return offset; + offset = pos; + } + return offset; } /* * Compacts active sector and sets new active sector */ -static void compact(void) -{ - uint32_t offsetr; - uint32_t version; - if (sectrue != find_start_offset(norcow_active_sector, &offsetr, &version)) { - return; +static void compact(void) { + uint32_t offsetr; + uint32_t version; + if (sectrue != find_start_offset(norcow_active_sector, &offsetr, &version)) { + return; + } + + norcow_write_sector = (norcow_active_sector + 1) % NORCOW_SECTOR_COUNT; + erase_sector(norcow_write_sector, sectrue); + uint32_t offsetw = NORCOW_STORAGE_START; + + for (;;) { + // read item + uint16_t k, l; + const void *v; + uint32_t posr; + secbool r = read_item(norcow_active_sector, offsetr, &k, &v, &l, &posr); + if (sectrue != r) { + break; } + offsetr = posr; - norcow_write_sector = (norcow_active_sector + 1) % NORCOW_SECTOR_COUNT; - erase_sector(norcow_write_sector, sectrue); - uint32_t offsetw = NORCOW_STORAGE_START; - - for (;;) { - // read item - uint16_t k, l; - const void *v; - uint32_t posr; - secbool r = read_item(norcow_active_sector, offsetr, &k, &v, &l, &posr); - if (sectrue != r) { - break; - } - offsetr = posr; - - // skip deleted items - if (k == NORCOW_KEY_DELETED) { - continue; - } - - // copy the item - uint32_t posw; - ensure(write_item(norcow_write_sector, offsetw, k, v, l, &posw), "compaction write failed"); - offsetw = posw; + // skip deleted items + if (k == NORCOW_KEY_DELETED) { + continue; } - erase_sector(norcow_active_sector, secfalse); - norcow_active_sector = norcow_write_sector; - norcow_active_version = NORCOW_VERSION; - norcow_free_offset = find_free_offset(norcow_write_sector); + // copy the item + uint32_t posw; + ensure(write_item(norcow_write_sector, offsetw, k, v, l, &posw), + "compaction write failed"); + offsetw = posw; + } + + erase_sector(norcow_active_sector, secfalse); + norcow_active_sector = norcow_write_sector; + norcow_active_version = NORCOW_VERSION; + norcow_free_offset = find_free_offset(norcow_write_sector); } /* * Initializes storage */ -void norcow_init(uint32_t *norcow_version) -{ - flash_init(); - secbool found = secfalse; - *norcow_version = 0; - // detect active sector - starts with magic and has highest version - for (uint8_t i = 0; i < NORCOW_SECTOR_COUNT; i++) { - uint32_t offset; - if (sectrue == find_start_offset(i, &offset, &norcow_active_version) && norcow_active_version >= *norcow_version) { - found = sectrue; - norcow_active_sector = i; - *norcow_version = norcow_active_version; - } - } - - // If no active sectors found or version downgrade, then erase. - if (sectrue != found || *norcow_version > NORCOW_VERSION) { - norcow_wipe(); - *norcow_version = NORCOW_VERSION; - } else if (*norcow_version < NORCOW_VERSION) { - // Prepare write sector for storage upgrade. - norcow_write_sector = (norcow_active_sector + 1) % NORCOW_SECTOR_COUNT; - erase_sector(norcow_write_sector, sectrue); - norcow_free_offset = find_free_offset(norcow_write_sector); - } else { - norcow_write_sector = norcow_active_sector; - norcow_free_offset = find_free_offset(norcow_write_sector); +void norcow_init(uint32_t *norcow_version) { + flash_init(); + secbool found = secfalse; + *norcow_version = 0; + // detect active sector - starts with magic and has highest version + for (uint8_t i = 0; i < NORCOW_SECTOR_COUNT; i++) { + uint32_t offset; + if (sectrue == find_start_offset(i, &offset, &norcow_active_version) && + norcow_active_version >= *norcow_version) { + found = sectrue; + norcow_active_sector = i; + *norcow_version = norcow_active_version; } + } + + // If no active sectors found or version downgrade, then erase. + if (sectrue != found || *norcow_version > NORCOW_VERSION) { + norcow_wipe(); + *norcow_version = NORCOW_VERSION; + } else if (*norcow_version < NORCOW_VERSION) { + // Prepare write sector for storage upgrade. + norcow_write_sector = (norcow_active_sector + 1) % NORCOW_SECTOR_COUNT; + erase_sector(norcow_write_sector, sectrue); + norcow_free_offset = find_free_offset(norcow_write_sector); + } else { + norcow_write_sector = norcow_active_sector; + norcow_free_offset = find_free_offset(norcow_write_sector); + } } /* * Wipe the storage */ -void norcow_wipe(void) -{ - erase_sector(0, sectrue); - for (uint8_t i = 1; i < NORCOW_SECTOR_COUNT; i++) { - erase_sector(i, secfalse); - } - norcow_active_sector = 0; - norcow_active_version = NORCOW_VERSION; - norcow_write_sector = 0; - norcow_free_offset = NORCOW_STORAGE_START; +void norcow_wipe(void) { + erase_sector(0, sectrue); + for (uint8_t i = 1; i < NORCOW_SECTOR_COUNT; i++) { + erase_sector(i, secfalse); + } + norcow_active_sector = 0; + norcow_active_version = NORCOW_VERSION; + norcow_write_sector = 0; + norcow_free_offset = NORCOW_STORAGE_START; } /* * Looks for the given key, returns status of the operation */ -secbool norcow_get(uint16_t key, const void **val, uint16_t *len) -{ - return find_item(norcow_active_sector, key, val, len); +secbool norcow_get(uint16_t key, const void **val, uint16_t *len) { + return find_item(norcow_active_sector, key, val, len); } /* - * Reads the next entry in the storage starting at offset. Returns secfalse if there is none. + * Reads the next entry in the storage starting at offset. Returns secfalse if + * there is none. */ -secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val, uint16_t *len) -{ - if (*offset == 0) { - uint32_t version; - if (sectrue != find_start_offset(norcow_active_sector, offset, &version)) { - return secfalse; - } +secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val, + uint16_t *len) { + if (*offset == 0) { + uint32_t version; + if (sectrue != find_start_offset(norcow_active_sector, offset, &version)) { + return secfalse; } + } - for (;;) { - uint32_t pos = 0; - secbool ret = read_item(norcow_active_sector, *offset, key, val, len, &pos); - if (sectrue != ret) { - break; - } - *offset = pos; + for (;;) { + uint32_t pos = 0; + secbool ret = read_item(norcow_active_sector, *offset, key, val, len, &pos); + if (sectrue != ret) { + break; + } + *offset = pos; - // Skip deleted items. - if (*key == NORCOW_KEY_DELETED) { - continue; - } + // Skip deleted items. + if (*key == NORCOW_KEY_DELETED) { + continue; + } - if (norcow_active_version == 0) { - // Check whether the item is the latest instance. - uint32_t offsetr = *offset; - for (;;) { - uint16_t k; - uint16_t l; - const void *v; - ret = read_item(norcow_active_sector, offsetr, &k, &v, &l, &offsetr); - if (sectrue != ret) { - // There is no newer instance of the item. - return sectrue; - } - if (*key == k) { - // There exists a newer instance of the item. - break; - } - } - } else { - return sectrue; + if (norcow_active_version == 0) { + // Check whether the item is the latest instance. + uint32_t offsetr = *offset; + for (;;) { + uint16_t k; + uint16_t l; + const void *v; + ret = read_item(norcow_active_sector, offsetr, &k, &v, &l, &offsetr); + if (sectrue != ret) { + // There is no newer instance of the item. + return sectrue; + } + if (*key == k) { + // There exists a newer instance of the item. + break; } + } + } else { + return sectrue; } - return secfalse; + } + return secfalse; } /* @@ -400,163 +404,175 @@ secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val, uint1 * as val, then norcow_set allocates a new key of size len. The value should * then be written using norcow_update_bytes(). */ -secbool norcow_set(uint16_t key, const void *val, uint16_t len) -{ - secbool found; - return norcow_set_ex(key, val, len, &found); +secbool norcow_set(uint16_t key, const void *val, uint16_t len) { + secbool found; + return norcow_set_ex(key, val, len, &found); } -secbool norcow_set_ex(uint16_t key, const void *val, uint16_t len, secbool *found) -{ - // Key 0xffff is used as a marker to indicate that the entry is not set. - if (key == NORCOW_KEY_FREE) { - return secfalse; - } - - const uint8_t sector_num = norcow_sectors[norcow_write_sector]; - secbool ret = secfalse; - const void *ptr = NULL; - uint16_t len_old = 0; - *found = find_item(norcow_write_sector, key, &ptr, &len_old); - - // Try to update the entry if it already exists. - uint32_t offset = 0; - if (sectrue == *found) { - offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE); - if (val != NULL && len_old == len) { - ret = sectrue; - ensure(flash_unlock_write(), NULL); - for (uint16_t i = 0; i < len; i++) { - if (sectrue != flash_write_byte(sector_num, offset + i, ((const uint8_t*)val)[i])) { - ret = secfalse; - break; - } - } - ensure(flash_lock_write(), NULL); +secbool norcow_set_ex(uint16_t key, const void *val, uint16_t len, + secbool *found) { + // Key 0xffff is used as a marker to indicate that the entry is not set. + if (key == NORCOW_KEY_FREE) { + return secfalse; + } + + const uint8_t sector_num = norcow_sectors[norcow_write_sector]; + secbool ret = secfalse; + const void *ptr = NULL; + uint16_t len_old = 0; + *found = find_item(norcow_write_sector, key, &ptr, &len_old); + + // Try to update the entry if it already exists. + uint32_t offset = 0; + if (sectrue == *found) { + offset = + (const uint8_t *)ptr - + (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE); + if (val != NULL && len_old == len) { + ret = sectrue; + ensure(flash_unlock_write(), NULL); + for (uint16_t i = 0; i < len; i++) { + if (sectrue != flash_write_byte(sector_num, offset + i, + ((const uint8_t *)val)[i])) { + ret = secfalse; + break; } + } + ensure(flash_lock_write(), NULL); } + } - // If the update was not possible then write the entry as a new item. - if (secfalse == ret) { - // Delete the old item. - if (sectrue == *found) { - ensure(flash_unlock_write(), NULL); + // If the update was not possible then write the entry as a new item. + if (secfalse == ret) { + // Delete the old item. + if (sectrue == *found) { + ensure(flash_unlock_write(), NULL); - // Update the prefix to indicate that the old item has been deleted. - uint32_t prefix = (uint32_t)len_old << 16; - ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix), NULL); + // Update the prefix to indicate that the old item has been deleted. + uint32_t prefix = (uint32_t)len_old << 16; + ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix), + NULL); - // Delete the old item data. - uint32_t end = offset + len_old; - while (offset < end) { - ensure(flash_write_word(sector_num, offset, 0x00000000), NULL); - offset += NORCOW_WORD_SIZE; - } + // Delete the old item data. + uint32_t end = offset + len_old; + while (offset < end) { + ensure(flash_write_word(sector_num, offset, 0x00000000), NULL); + offset += NORCOW_WORD_SIZE; + } - ensure(flash_lock_write(), NULL); - } - // Check whether there is enough free space and compact if full. - if (norcow_free_offset + NORCOW_PREFIX_LEN + len > NORCOW_SECTOR_SIZE) { - compact(); - } - // Write new item. - uint32_t pos; - ret = write_item(norcow_write_sector, norcow_free_offset, key, val, len, &pos); - if (sectrue == ret) { - norcow_free_offset = pos; - } + ensure(flash_lock_write(), NULL); } - return ret; + // Check whether there is enough free space and compact if full. + if (norcow_free_offset + NORCOW_PREFIX_LEN + len > NORCOW_SECTOR_SIZE) { + compact(); + } + // Write new item. + uint32_t pos; + ret = write_item(norcow_write_sector, norcow_free_offset, key, val, len, + &pos); + if (sectrue == ret) { + norcow_free_offset = pos; + } + } + return ret; } /* * Deletes the given key, returns status of the operation. */ -secbool norcow_delete(uint16_t key) -{ - // Key 0xffff is used as a marker to indicate that the entry is not set. - if (key == NORCOW_KEY_FREE) { - return secfalse; - } +secbool norcow_delete(uint16_t key) { + // Key 0xffff is used as a marker to indicate that the entry is not set. + if (key == NORCOW_KEY_FREE) { + return secfalse; + } - const uint8_t sector_num = norcow_sectors[norcow_write_sector]; - const void *ptr = NULL; - uint16_t len = 0; - if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) { - return secfalse; - } + const uint8_t sector_num = norcow_sectors[norcow_write_sector]; + const void *ptr = NULL; + uint16_t len = 0; + if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) { + return secfalse; + } - uint32_t offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE); + uint32_t offset = + (const uint8_t *)ptr - + (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE); - ensure(flash_unlock_write(), NULL); + ensure(flash_unlock_write(), NULL); - // Update the prefix to indicate that the item has been deleted. - uint32_t prefix = (uint32_t)len << 16; - ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix), NULL); + // Update the prefix to indicate that the item has been deleted. + uint32_t prefix = (uint32_t)len << 16; + ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix), + NULL); - // Delete the item data. - uint32_t end = offset + len; - while (offset < end) { - ensure(flash_write_word(sector_num, offset, 0x00000000), NULL); - offset += NORCOW_WORD_SIZE; - } + // Delete the item data. + uint32_t end = offset + len; + while (offset < end) { + ensure(flash_write_word(sector_num, offset, 0x00000000), NULL); + offset += NORCOW_WORD_SIZE; + } - ensure(flash_lock_write(), NULL); + ensure(flash_lock_write(), NULL); - return sectrue; + return sectrue; } /* * Update a word in flash at the given pointer. The pointer must point * into the NORCOW area. */ -secbool norcow_update_word(uint16_t key, uint16_t offset, uint32_t value) -{ - const void *ptr; - uint16_t len; - if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) { - return secfalse; - } - if ((offset & 3) != 0 || offset >= len) { - return secfalse; - } - uint32_t sector_offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) + offset; - ensure(flash_unlock_write(), NULL); - ensure(flash_write_word(norcow_sectors[norcow_write_sector], sector_offset, value), NULL); - ensure(flash_lock_write(), NULL); - return sectrue; +secbool norcow_update_word(uint16_t key, uint16_t offset, uint32_t value) { + const void *ptr; + uint16_t len; + if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) { + return secfalse; + } + if ((offset & 3) != 0 || offset >= len) { + return secfalse; + } + uint32_t sector_offset = + (const uint8_t *)ptr - + (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) + + offset; + ensure(flash_unlock_write(), NULL); + ensure(flash_write_word(norcow_sectors[norcow_write_sector], sector_offset, + value), + NULL); + ensure(flash_lock_write(), NULL); + return sectrue; } /* * Update the value of the given key starting at the given offset. */ -secbool norcow_update_bytes(const uint16_t key, const uint16_t offset, const uint8_t *data, const uint16_t len) -{ - const void *ptr; - uint16_t allocated_len; - if (sectrue != find_item(norcow_write_sector, key, &ptr, &allocated_len)) { - return secfalse; - } - if (offset + len > allocated_len) { - return secfalse; - } - uint32_t sector_offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) + offset; - uint8_t sector = norcow_sectors[norcow_write_sector]; - ensure(flash_unlock_write(), NULL); - for (uint16_t i = 0; i < len; i++, sector_offset++) { - ensure(flash_write_byte(sector, sector_offset, data[i]), NULL); - } - ensure(flash_lock_write(), NULL); - return sectrue; +secbool norcow_update_bytes(const uint16_t key, const uint16_t offset, + const uint8_t *data, const uint16_t len) { + const void *ptr; + uint16_t allocated_len; + if (sectrue != find_item(norcow_write_sector, key, &ptr, &allocated_len)) { + return secfalse; + } + if (offset + len > allocated_len) { + return secfalse; + } + uint32_t sector_offset = + (const uint8_t *)ptr - + (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) + + offset; + uint8_t sector = norcow_sectors[norcow_write_sector]; + ensure(flash_unlock_write(), NULL); + for (uint16_t i = 0; i < len; i++, sector_offset++) { + ensure(flash_write_byte(sector, sector_offset, data[i]), NULL); + } + ensure(flash_lock_write(), NULL); + return sectrue; } /* * Complete storage version upgrade */ -secbool norcow_upgrade_finish(void) -{ - erase_sector(norcow_active_sector, secfalse); - norcow_active_sector = norcow_write_sector; - norcow_active_version = NORCOW_VERSION; - return sectrue; +secbool norcow_upgrade_finish(void) { + erase_sector(norcow_active_sector, secfalse); + norcow_active_sector = norcow_write_sector; + norcow_active_version = NORCOW_VERSION; + return sectrue; } diff --git a/storage/norcow.h b/storage/norcow.h index 953f6f1d0..c078c992a 100644 --- a/storage/norcow.h +++ b/storage/norcow.h @@ -45,9 +45,11 @@ void norcow_wipe(void); secbool norcow_get(uint16_t key, const void **val, uint16_t *len); /* - * Reads the next entry in the storage starting at offset. Returns secfalse if there is none. + * Reads the next entry in the storage starting at offset. Returns secfalse if + * there is none. */ -secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val, uint16_t *len); +secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val, + uint16_t *len); /* * Sets the given key, returns status of the operation. If NULL is passed @@ -55,7 +57,8 @@ secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val, uint1 * then be written using norcow_update_bytes(). */ secbool norcow_set(uint16_t key, const void *val, uint16_t len); -secbool norcow_set_ex(uint16_t key, const void *val, uint16_t len, secbool *found); +secbool norcow_set_ex(uint16_t key, const void *val, uint16_t len, + secbool *found); /* * Deletes the given key, returns status of the operation. @@ -72,7 +75,8 @@ secbool norcow_update_word(uint16_t key, uint16_t offset, uint32_t value); * Update the value of the given key starting at the given offset. * Note that you can only change bits from 1 to 0. */ -secbool norcow_update_bytes(const uint16_t key, const uint16_t offset, const uint8_t *data, const uint16_t len); +secbool norcow_update_bytes(const uint16_t key, const uint16_t offset, + const uint8_t *data, const uint16_t len); /* * Complete storage version upgrade diff --git a/storage/storage.c b/storage/storage.c index 655e85c31..fa6e90ca3 100644 --- a/storage/storage.c +++ b/storage/storage.c @@ -19,105 +19,108 @@ #include +#include "chacha20poly1305/rfc7539.h" #include "common.h" +#include "hmac.h" +#include "memzero.h" #include "norcow.h" -#include "storage.h" #include "pbkdf2.h" -#include "sha2.h" -#include "hmac.h" #include "rand.h" -#include "memzero.h" -#include "chacha20poly1305/rfc7539.h" +#include "sha2.h" +#include "storage.h" -#define LOW_MASK 0x55555555 +#define LOW_MASK 0x55555555 // The APP namespace which is reserved for storage related values. -#define APP_STORAGE 0x00 +#define APP_STORAGE 0x00 // Norcow storage key of the PIN entry log and PIN success log. -#define PIN_LOGS_KEY ((APP_STORAGE << 8) | 0x01) +#define PIN_LOGS_KEY ((APP_STORAGE << 8) | 0x01) -// Norcow storage key of the combined salt, EDEK, ESAK and PIN verification code entry. -#define EDEK_PVC_KEY ((APP_STORAGE << 8) | 0x02) +// Norcow storage key of the combined salt, EDEK, ESAK and PIN verification code +// entry. +#define EDEK_PVC_KEY ((APP_STORAGE << 8) | 0x02) // Norcow storage key of the PIN set flag. -#define PIN_NOT_SET_KEY ((APP_STORAGE << 8) | 0x03) +#define PIN_NOT_SET_KEY ((APP_STORAGE << 8) | 0x03) // Norcow storage key of the storage version. -#define VERSION_KEY ((APP_STORAGE << 8) | 0x04) +#define VERSION_KEY ((APP_STORAGE << 8) | 0x04) // Norcow storage key of the storage authentication tag. -#define STORAGE_TAG_KEY ((APP_STORAGE << 8) | 0x05) +#define STORAGE_TAG_KEY ((APP_STORAGE << 8) | 0x05) // The PIN value corresponding to an empty PIN. -#define PIN_EMPTY 1 +#define PIN_EMPTY 1 // Maximum number of failed unlock attempts. -// NOTE: The PIN counter logic relies on this constant being less than or equal to 16. -#define PIN_MAX_TRIES 16 +// NOTE: The PIN counter logic relies on this constant being less than or equal +// to 16. +#define PIN_MAX_TRIES 16 // The total number of iterations to use in PBKDF2. -#define PIN_ITER_COUNT 20000 +#define PIN_ITER_COUNT 20000 // The number of seconds required to derive the KEK and KEIV. -#define DERIVE_SECS 1 +#define DERIVE_SECS 1 // If the top bit of APP is set, then the value is not encrypted. -#define FLAG_PUBLIC 0x80 +#define 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. -#define FLAGS_WRITE 0xC0 +#define FLAGS_WRITE 0xC0 // The length of the guard key in words. -#define GUARD_KEY_WORDS 1 +#define GUARD_KEY_WORDS 1 // The length of the PIN entry log or the PIN success log in words. -#define PIN_LOG_WORDS 16 +#define PIN_LOG_WORDS 16 // The length of a word in bytes. -#define WORD_SIZE (sizeof(uint32_t)) +#define WORD_SIZE (sizeof(uint32_t)) // The length of the hashed hardware salt in bytes. -#define HARDWARE_SALT_SIZE SHA256_DIGEST_LENGTH +#define HARDWARE_SALT_SIZE SHA256_DIGEST_LENGTH // The length of the random salt in bytes. -#define RANDOM_SALT_SIZE 4 +#define RANDOM_SALT_SIZE 4 // The length of the data encryption key in bytes. -#define DEK_SIZE 32 +#define DEK_SIZE 32 // The length of the storage authentication key in bytes. -#define SAK_SIZE 16 +#define SAK_SIZE 16 -// The combined length of the data encryption key and the storage authentication key in bytes. -#define KEYS_SIZE (DEK_SIZE + SAK_SIZE) +// The combined length of the data encryption key and the storage authentication +// key in bytes. +#define KEYS_SIZE (DEK_SIZE + SAK_SIZE) // The length of the PIN verification code in bytes. -#define PVC_SIZE 8 +#define PVC_SIZE 8 // The length of the storage authentication tag in bytes. -#define STORAGE_TAG_SIZE 16 +#define STORAGE_TAG_SIZE 16 // The length of the Poly1305 authentication tag in bytes. -#define POLY1305_TAG_SIZE 16 +#define POLY1305_TAG_SIZE 16 // The length of the ChaCha20 IV (aka nonce) in bytes as per RFC 7539. -#define CHACHA20_IV_SIZE 12 +#define CHACHA20_IV_SIZE 12 // The length of the ChaCha20 block in bytes. #define CHACHA20_BLOCK_SIZE 64 // The length of the counter tail in words. -#define COUNTER_TAIL_WORDS 2 +#define COUNTER_TAIL_WORDS 2 // Values used in the guard key integrity check. -#define GUARD_KEY_MODULUS 6311 +#define GUARD_KEY_MODULUS 6311 #define GUARD_KEY_REMAINDER 15 -const char* const VERIFYING_PIN_MSG = "Verifying PIN"; -const char* const PROCESSING_MSG = "Processing"; -const char* const STARTING_MSG = "Starting up"; +const char *const VERIFYING_PIN_MSG = "Verifying PIN"; +const char *const PROCESSING_MSG = "Processing"; +const char *const STARTING_MSG = "Starting up"; static secbool initialized = secfalse; static secbool unlocked = secfalse; @@ -134,742 +137,781 @@ static uint32_t norcow_active_version = 0; static const uint8_t TRUE_BYTE = 0x01; static const uint8_t FALSE_BYTE = 0x00; -static void __handle_fault(const char *msg, const char *file, int line, const char *func); +static void __handle_fault(const char *msg, const char *file, int line, + const char *func); #define handle_fault(msg) (__handle_fault(msg, __FILE__, __LINE__, __func__)) static secbool storage_upgrade(void); -static secbool storage_set_encrypted(const uint16_t key, const void *val, const uint16_t len); -static secbool storage_get_encrypted(const uint16_t key, void *val_dest, const uint16_t max_len, uint16_t *len); - -static secbool secequal(const void* ptr1, const void* ptr2, size_t n) { - const uint8_t* p1 = ptr1; - const uint8_t* p2 = ptr2; - uint8_t diff = 0; - size_t i; - for (i = 0; i < n; ++i) { - diff |= *p1 ^ *p2; - ++p1; - ++p2; - } - - // Check loop completion in case of a fault injection attack. - if (i != n) { - handle_fault("loop completion check"); - } - - return diff ? secfalse : sectrue; +static secbool storage_set_encrypted(const uint16_t key, const void *val, + const uint16_t len); +static secbool storage_get_encrypted(const uint16_t key, void *val_dest, + const uint16_t max_len, uint16_t *len); + +static secbool secequal(const void *ptr1, const void *ptr2, size_t n) { + const uint8_t *p1 = ptr1; + const uint8_t *p2 = ptr2; + uint8_t diff = 0; + size_t i; + for (i = 0; i < n; ++i) { + diff |= *p1 ^ *p2; + ++p1; + ++p2; + } + + // Check loop completion in case of a fault injection attack. + if (i != n) { + handle_fault("loop completion check"); + } + + return diff ? secfalse : sectrue; } -static secbool secequal32(const uint32_t* ptr1, const uint32_t* ptr2, size_t n) { - uint32_t diff = 0; - size_t i; - for (i = 0; i < n; ++i) { - uint32_t mask = random32(); - diff |= (*ptr1 + mask - *ptr2) ^ mask; - ++ptr1; - ++ptr2; - } - - // Check loop completion in case of a fault injection attack. - if (i != n) { - handle_fault("loop completion check"); - } - - return diff ? secfalse : sectrue; +static secbool secequal32(const uint32_t *ptr1, const uint32_t *ptr2, + size_t n) { + uint32_t diff = 0; + size_t i; + for (i = 0; i < n; ++i) { + uint32_t mask = random32(); + diff |= (*ptr1 + mask - *ptr2) ^ mask; + ++ptr1; + ++ptr2; + } + + // Check loop completion in case of a fault injection attack. + if (i != n) { + handle_fault("loop completion check"); + } + + return diff ? secfalse : sectrue; } static secbool is_protected(uint16_t key) { - const uint8_t app = key >> 8; - return ((app & FLAG_PUBLIC) == 0 && app != APP_STORAGE) ? sectrue : secfalse; + const uint8_t app = key >> 8; + return ((app & FLAG_PUBLIC) == 0 && app != APP_STORAGE) ? sectrue : secfalse; } /* * Initialize the storage authentication tag for freshly wiped storage. */ static secbool auth_init(void) { - uint8_t tag[SHA256_DIGEST_LENGTH]; - memzero(authentication_sum, sizeof(authentication_sum)); - hmac_sha256(cached_sak, SAK_SIZE, authentication_sum, sizeof(authentication_sum), tag); - return norcow_set(STORAGE_TAG_KEY, tag, STORAGE_TAG_SIZE); + uint8_t tag[SHA256_DIGEST_LENGTH]; + memzero(authentication_sum, sizeof(authentication_sum)); + hmac_sha256(cached_sak, SAK_SIZE, authentication_sum, + sizeof(authentication_sum), tag); + return norcow_set(STORAGE_TAG_KEY, tag, STORAGE_TAG_SIZE); } /* * Update the storage authentication tag with the given key. */ static secbool auth_update(uint16_t key) { - if (sectrue != is_protected(key)) { - return sectrue; - } - - uint8_t tag[SHA256_DIGEST_LENGTH]; - hmac_sha256(cached_sak, SAK_SIZE, (uint8_t*)&key, sizeof(key), tag); - for (uint32_t i = 0; i < SHA256_DIGEST_LENGTH; i++) { - authentication_sum[i] ^= tag[i]; - } - hmac_sha256(cached_sak, SAK_SIZE, authentication_sum, sizeof(authentication_sum), tag); - return norcow_set(STORAGE_TAG_KEY, tag, STORAGE_TAG_SIZE); + if (sectrue != is_protected(key)) { + return sectrue; + } + + uint8_t tag[SHA256_DIGEST_LENGTH]; + hmac_sha256(cached_sak, SAK_SIZE, (uint8_t *)&key, sizeof(key), tag); + for (uint32_t i = 0; i < SHA256_DIGEST_LENGTH; i++) { + authentication_sum[i] ^= tag[i]; + } + hmac_sha256(cached_sak, SAK_SIZE, authentication_sum, + sizeof(authentication_sum), tag); + return norcow_set(STORAGE_TAG_KEY, tag, STORAGE_TAG_SIZE); } /* - * A secure version of norcow_set(), which updates the storage authentication tag. + * A secure version of norcow_set(), which updates the storage authentication + * tag. */ static secbool auth_set(uint16_t key, const void *val, uint16_t len) { - secbool found; - secbool ret = norcow_set_ex(key, val, len, &found); - if (sectrue == ret && secfalse == found) { - ret = auth_update(key); - if (sectrue != ret) { - norcow_delete(key); - } - } - return ret; + secbool found; + secbool ret = norcow_set_ex(key, val, len, &found); + if (sectrue == ret && secfalse == found) { + ret = auth_update(key); + if (sectrue != ret) { + norcow_delete(key); + } + } + return ret; } /* - * A secure version of norcow_get(), which checks the storage authentication tag. + * A secure version of norcow_get(), which checks the storage authentication + * tag. */ -static secbool auth_get(uint16_t key, const void **val, uint16_t *len) -{ - *val = NULL; - *len = 0; - uint32_t sum[SHA256_DIGEST_LENGTH/sizeof(uint32_t)] = {0}; - - // Prepare inner and outer digest. - uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; - hmac_sha256_prepare(cached_sak, SAK_SIZE, odig, idig); - - // Prepare SHA-256 message padding. - uint32_t g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; - uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; - g[15] = (SHA256_BLOCK_LENGTH + 2) * 8; - h[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; - h[8] = 0x80000000; - - uint32_t offset = 0; - uint16_t k = 0; - uint16_t l = 0; - uint16_t tag_len = 0; - uint16_t entry_count = 0; // Mitigation against fault injection. - uint16_t other_count = 0; // Mitigation against fault injection. - const void *v = NULL; - const void *tag_val = NULL; - while (sectrue == norcow_get_next(&offset, &k, &v, &l)) { - ++entry_count; - if (k == key) { - *val = v; - *len = l; - } else { - ++other_count; - } - if (sectrue != is_protected(k)) { - if (k == STORAGE_TAG_KEY) { - tag_val = v; - tag_len = l; - } - continue; - } - g[0] = (((uint32_t)k & 0xff) << 24) | (((uint32_t)k & 0xff00) << 8) | 0x8000; // Add SHA message padding. - sha256_Transform(idig, g, h); - sha256_Transform(odig, h, h); - for (uint32_t i = 0; i < SHA256_DIGEST_LENGTH/sizeof(uint32_t); i++) { - sum[i] ^= h[i]; - } +static secbool auth_get(uint16_t key, const void **val, uint16_t *len) { + *val = NULL; + *len = 0; + uint32_t sum[SHA256_DIGEST_LENGTH / sizeof(uint32_t)] = {0}; + + // Prepare inner and outer digest. + uint32_t odig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + uint32_t idig[SHA256_DIGEST_LENGTH / sizeof(uint32_t)]; + hmac_sha256_prepare(cached_sak, SAK_SIZE, odig, idig); + + // Prepare SHA-256 message padding. + uint32_t g[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; + uint32_t h[SHA256_BLOCK_LENGTH / sizeof(uint32_t)] = {0}; + g[15] = (SHA256_BLOCK_LENGTH + 2) * 8; + h[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8; + h[8] = 0x80000000; + + uint32_t offset = 0; + uint16_t k = 0; + uint16_t l = 0; + uint16_t tag_len = 0; + uint16_t entry_count = 0; // Mitigation against fault injection. + uint16_t other_count = 0; // Mitigation against fault injection. + const void *v = NULL; + const void *tag_val = NULL; + while (sectrue == norcow_get_next(&offset, &k, &v, &l)) { + ++entry_count; + if (k == key) { + *val = v; + *len = l; + } else { + ++other_count; + } + if (sectrue != is_protected(k)) { + if (k == STORAGE_TAG_KEY) { + tag_val = v; + tag_len = l; + } + continue; + } + g[0] = (((uint32_t)k & 0xff) << 24) | (((uint32_t)k & 0xff00) << 8) | + 0x8000; // Add SHA message padding. + sha256_Transform(idig, g, h); + sha256_Transform(odig, h, h); + for (uint32_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) { + sum[i] ^= h[i]; } - memcpy(h, sum, sizeof(sum)); + } + memcpy(h, sum, sizeof(sum)); - sha256_Transform(idig, h, h); - sha256_Transform(odig, h, h); + sha256_Transform(idig, h, h); + sha256_Transform(odig, h, h); - memzero(odig, sizeof(odig)); - memzero(idig, sizeof(idig)); + memzero(odig, sizeof(odig)); + memzero(idig, sizeof(idig)); - // Cache the authentication sum. - for (size_t i = 0; i < SHA256_DIGEST_LENGTH/sizeof(uint32_t); i++) { + // Cache the authentication sum. + for (size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) { #if BYTE_ORDER == LITTLE_ENDIAN - REVERSE32(sum[i], ((uint32_t*)authentication_sum)[i]); + REVERSE32(sum[i], ((uint32_t *)authentication_sum)[i]); #else - ((uint32_t*)authentication_sum)[i] = sum[i]; + ((uint32_t *)authentication_sum)[i] = sum[i]; #endif - } + } - // Check loop completion in case of a fault injection attack. - if (secfalse != norcow_get_next(&offset, &k, &v, &l)) { - handle_fault("loop completion check"); - } + // Check loop completion in case of a fault injection attack. + if (secfalse != norcow_get_next(&offset, &k, &v, &l)) { + handle_fault("loop completion check"); + } - // Check storage authentication tag. + // Check storage authentication tag. #if BYTE_ORDER == LITTLE_ENDIAN - for (size_t i = 0; i < SHA256_DIGEST_LENGTH/sizeof(uint32_t); i++) { - REVERSE32(h[i], h[i]); - } + for (size_t i = 0; i < SHA256_DIGEST_LENGTH / sizeof(uint32_t); i++) { + REVERSE32(h[i], h[i]); + } #endif - if (tag_val == NULL || tag_len != STORAGE_TAG_SIZE || sectrue != secequal(h, tag_val, STORAGE_TAG_SIZE)) { - handle_fault("storage tag check"); - } + if (tag_val == NULL || tag_len != STORAGE_TAG_SIZE || + sectrue != secequal(h, tag_val, STORAGE_TAG_SIZE)) { + handle_fault("storage tag check"); + } - if (*val == NULL) { - // Check for fault injection. - if (other_count != entry_count) { - handle_fault("sanity check"); - } - return secfalse; + if (*val == NULL) { + // Check for fault injection. + if (other_count != entry_count) { + handle_fault("sanity check"); } - return sectrue; + return secfalse; + } + return sectrue; } /* - * Generates a delay of random length. Use this to protect sensitive code against fault injection. + * Generates a delay of random length. Use this to protect sensitive code + * against fault injection. */ -static void wait_random(void) -{ +static void wait_random(void) { #ifndef TREZOR_STORAGE_TEST - int wait = random32() & 0xff; - volatile int i = 0; - volatile int j = wait; - while (i < wait) { - if (i + j != wait) { - handle_fault("sanity check"); - } - ++i; - --j; - } - - // Double-check loop completion. - if (i != wait) { - handle_fault("loop completion check"); - } + int wait = random32() & 0xff; + volatile int i = 0; + volatile int j = wait; + while (i < wait) { + if (i + j != wait) { + handle_fault("sanity check"); + } + ++i; + --j; + } + + // Double-check loop completion. + if (i != wait) { + handle_fault("loop completion check"); + } #endif } -static void derive_kek(uint32_t pin, const uint8_t *random_salt, uint8_t kek[SHA256_DIGEST_LENGTH], uint8_t keiv[SHA256_DIGEST_LENGTH]) -{ +static void derive_kek(uint32_t pin, const uint8_t *random_salt, + uint8_t kek[SHA256_DIGEST_LENGTH], + uint8_t keiv[SHA256_DIGEST_LENGTH]) { #if BYTE_ORDER == BIG_ENDIAN - REVERSE32(pin, pin); + REVERSE32(pin, pin); #endif - uint8_t salt[HARDWARE_SALT_SIZE + RANDOM_SALT_SIZE]; - memcpy(salt, hardware_salt, HARDWARE_SALT_SIZE); - memcpy(salt + HARDWARE_SALT_SIZE, random_salt, RANDOM_SALT_SIZE); + uint8_t salt[HARDWARE_SALT_SIZE + RANDOM_SALT_SIZE]; + memcpy(salt, hardware_salt, HARDWARE_SALT_SIZE); + memcpy(salt + HARDWARE_SALT_SIZE, random_salt, RANDOM_SALT_SIZE); - uint32_t progress = (ui_total - ui_rem) * 1000 / ui_total; + uint32_t progress = (ui_total - ui_rem) * 1000 / ui_total; + if (ui_callback && ui_message) { + ui_callback(ui_rem, progress, ui_message); + } + + PBKDF2_HMAC_SHA256_CTX ctx; + pbkdf2_hmac_sha256_Init(&ctx, (const uint8_t *)&pin, sizeof(pin), salt, + sizeof(salt), 1); + for (int i = 1; i <= 5; i++) { + pbkdf2_hmac_sha256_Update(&ctx, PIN_ITER_COUNT / 10); if (ui_callback && ui_message) { - ui_callback(ui_rem, progress, ui_message); + progress = + ((ui_total - ui_rem) * 1000 + i * DERIVE_SECS * 100) / ui_total; + ui_callback(ui_rem - i * DERIVE_SECS / 10, progress, ui_message); } + } + pbkdf2_hmac_sha256_Final(&ctx, kek); - PBKDF2_HMAC_SHA256_CTX ctx; - pbkdf2_hmac_sha256_Init(&ctx, (const uint8_t*) &pin, sizeof(pin), salt, sizeof(salt), 1); - for (int i = 1; i <= 5; i++) { - pbkdf2_hmac_sha256_Update(&ctx, PIN_ITER_COUNT / 10); - if (ui_callback && ui_message) { - progress = ((ui_total - ui_rem) * 1000 + i * DERIVE_SECS * 100) / ui_total; - ui_callback(ui_rem - i * DERIVE_SECS / 10, progress, ui_message); - } - } - pbkdf2_hmac_sha256_Final(&ctx, kek); - - pbkdf2_hmac_sha256_Init(&ctx, (const uint8_t*) &pin, sizeof(pin), salt, sizeof(salt), 2); - for (int i = 6; i <= 10; i++) { - pbkdf2_hmac_sha256_Update(&ctx, PIN_ITER_COUNT / 10); - if (ui_callback && ui_message) { - progress = ((ui_total - ui_rem) * 1000 + i * DERIVE_SECS * 100) / ui_total; - ui_callback(ui_rem - i * DERIVE_SECS / 10, progress, ui_message); - } + pbkdf2_hmac_sha256_Init(&ctx, (const uint8_t *)&pin, sizeof(pin), salt, + sizeof(salt), 2); + for (int i = 6; i <= 10; i++) { + pbkdf2_hmac_sha256_Update(&ctx, PIN_ITER_COUNT / 10); + if (ui_callback && ui_message) { + progress = + ((ui_total - ui_rem) * 1000 + i * DERIVE_SECS * 100) / ui_total; + ui_callback(ui_rem - i * DERIVE_SECS / 10, progress, ui_message); } - pbkdf2_hmac_sha256_Final(&ctx, keiv); + } + pbkdf2_hmac_sha256_Final(&ctx, keiv); - ui_rem -= DERIVE_SECS; - memzero(&ctx, sizeof(PBKDF2_HMAC_SHA256_CTX)); - memzero(&pin, sizeof(pin)); - memzero(&salt, sizeof(salt)); + ui_rem -= DERIVE_SECS; + memzero(&ctx, sizeof(PBKDF2_HMAC_SHA256_CTX)); + memzero(&pin, sizeof(pin)); + memzero(&salt, sizeof(salt)); } -static secbool set_pin(uint32_t pin) -{ - uint8_t buffer[RANDOM_SALT_SIZE + KEYS_SIZE + POLY1305_TAG_SIZE]; - uint8_t *salt = buffer; - uint8_t *ekeys = buffer + RANDOM_SALT_SIZE; - uint8_t *pvc = buffer + RANDOM_SALT_SIZE + KEYS_SIZE; - - uint8_t kek[SHA256_DIGEST_LENGTH]; - uint8_t keiv[SHA256_DIGEST_LENGTH]; - chacha20poly1305_ctx ctx; - random_buffer(salt, RANDOM_SALT_SIZE); - derive_kek(pin, salt, kek, keiv); - rfc7539_init(&ctx, kek, keiv); - memzero(kek, sizeof(kek)); - memzero(keiv, sizeof(keiv)); - chacha20poly1305_encrypt(&ctx, cached_keys, ekeys, KEYS_SIZE); - rfc7539_finish(&ctx, 0, KEYS_SIZE, pvc); - memzero(&ctx, sizeof(ctx)); - secbool ret = norcow_set(EDEK_PVC_KEY, buffer, RANDOM_SALT_SIZE + KEYS_SIZE + PVC_SIZE); - memzero(buffer, sizeof(buffer)); - - if (ret == sectrue) - { - if (pin == PIN_EMPTY) { - ret = norcow_set(PIN_NOT_SET_KEY, &TRUE_BYTE, sizeof(TRUE_BYTE)); - } else { - ret = norcow_set(PIN_NOT_SET_KEY, &FALSE_BYTE, sizeof(FALSE_BYTE)); - } +static secbool set_pin(uint32_t pin) { + uint8_t buffer[RANDOM_SALT_SIZE + KEYS_SIZE + POLY1305_TAG_SIZE]; + uint8_t *salt = buffer; + uint8_t *ekeys = buffer + RANDOM_SALT_SIZE; + uint8_t *pvc = buffer + RANDOM_SALT_SIZE + KEYS_SIZE; + + uint8_t kek[SHA256_DIGEST_LENGTH]; + uint8_t keiv[SHA256_DIGEST_LENGTH]; + chacha20poly1305_ctx ctx; + random_buffer(salt, RANDOM_SALT_SIZE); + derive_kek(pin, salt, kek, keiv); + rfc7539_init(&ctx, kek, keiv); + memzero(kek, sizeof(kek)); + memzero(keiv, sizeof(keiv)); + chacha20poly1305_encrypt(&ctx, cached_keys, ekeys, KEYS_SIZE); + rfc7539_finish(&ctx, 0, KEYS_SIZE, pvc); + memzero(&ctx, sizeof(ctx)); + secbool ret = + norcow_set(EDEK_PVC_KEY, buffer, RANDOM_SALT_SIZE + KEYS_SIZE + PVC_SIZE); + memzero(buffer, sizeof(buffer)); + + if (ret == sectrue) { + if (pin == PIN_EMPTY) { + ret = norcow_set(PIN_NOT_SET_KEY, &TRUE_BYTE, sizeof(TRUE_BYTE)); + } else { + ret = norcow_set(PIN_NOT_SET_KEY, &FALSE_BYTE, sizeof(FALSE_BYTE)); } + } - memzero(&pin, sizeof(pin)); - return ret; + memzero(&pin, sizeof(pin)); + return ret; } -static secbool check_guard_key(const uint32_t guard_key) -{ - if (guard_key % GUARD_KEY_MODULUS != GUARD_KEY_REMAINDER) { - return secfalse; - } +static secbool check_guard_key(const uint32_t guard_key) { + if (guard_key % GUARD_KEY_MODULUS != GUARD_KEY_REMAINDER) { + return secfalse; + } - // Check that each byte of (guard_key & 0xAAAAAAAA) has exactly two bits set. - uint32_t count = (guard_key & 0x22222222) + ((guard_key >> 2) & 0x22222222); - count = count + (count >> 4); - if ((count & 0x0e0e0e0e) != 0x04040404) { - return secfalse; - } + // Check that each byte of (guard_key & 0xAAAAAAAA) has exactly two bits set. + uint32_t count = (guard_key & 0x22222222) + ((guard_key >> 2) & 0x22222222); + count = count + (count >> 4); + if ((count & 0x0e0e0e0e) != 0x04040404) { + return secfalse; + } - // Check that the guard_key does not contain a run of 5 (or more) zeros or ones. - uint32_t zero_runs = ~guard_key; - zero_runs = zero_runs & (zero_runs >> 2); - zero_runs = zero_runs & (zero_runs >> 1); - zero_runs = zero_runs & (zero_runs >> 1); + // Check that the guard_key does not contain a run of 5 (or more) zeros or + // ones. + uint32_t zero_runs = ~guard_key; + zero_runs = zero_runs & (zero_runs >> 2); + zero_runs = zero_runs & (zero_runs >> 1); + zero_runs = zero_runs & (zero_runs >> 1); - uint32_t one_runs = guard_key; - one_runs = one_runs & (one_runs >> 2); - one_runs = one_runs & (one_runs >> 1); - one_runs = one_runs & (one_runs >> 1); + uint32_t one_runs = guard_key; + one_runs = one_runs & (one_runs >> 2); + one_runs = one_runs & (one_runs >> 1); + one_runs = one_runs & (one_runs >> 1); - if ((one_runs != 0) || (zero_runs != 0)) { - return secfalse; - } + if ((one_runs != 0) || (zero_runs != 0)) { + return secfalse; + } - return sectrue; + return sectrue; } -static uint32_t generate_guard_key(void) -{ - uint32_t guard_key = 0; - do { - guard_key = random_uniform((UINT32_MAX/GUARD_KEY_MODULUS) + 1) * GUARD_KEY_MODULUS + GUARD_KEY_REMAINDER; - } while (sectrue != check_guard_key(guard_key)); - return guard_key; +static uint32_t generate_guard_key(void) { + uint32_t guard_key = 0; + do { + guard_key = random_uniform((UINT32_MAX / GUARD_KEY_MODULUS) + 1) * + GUARD_KEY_MODULUS + + GUARD_KEY_REMAINDER; + } while (sectrue != check_guard_key(guard_key)); + return guard_key; } -static secbool expand_guard_key(const uint32_t guard_key, uint32_t *guard_mask, uint32_t *guard) -{ - if (sectrue != check_guard_key(guard_key)) { - handle_fault("guard key check"); - return secfalse; - } - *guard_mask = ((guard_key & LOW_MASK) << 1) | ((~guard_key) & LOW_MASK); - *guard = (((guard_key & LOW_MASK) << 1) & guard_key) | (((~guard_key) & LOW_MASK) & (guard_key >> 1)); - return sectrue; +static secbool expand_guard_key(const uint32_t guard_key, uint32_t *guard_mask, + uint32_t *guard) { + if (sectrue != check_guard_key(guard_key)) { + handle_fault("guard key check"); + return secfalse; + } + *guard_mask = ((guard_key & LOW_MASK) << 1) | ((~guard_key) & LOW_MASK); + *guard = (((guard_key & LOW_MASK) << 1) & guard_key) | + (((~guard_key) & LOW_MASK) & (guard_key >> 1)); + return sectrue; } -static secbool pin_logs_init(uint32_t fails) -{ - if (fails >= PIN_MAX_TRIES) { - return secfalse; - } +static secbool pin_logs_init(uint32_t fails) { + if (fails >= PIN_MAX_TRIES) { + return secfalse; + } - // The format of the PIN_LOGS_KEY entry is: - // guard_key (1 word), pin_success_log (PIN_LOG_WORDS), pin_entry_log (PIN_LOG_WORDS) - uint32_t logs[GUARD_KEY_WORDS + 2*PIN_LOG_WORDS]; + // The format of the PIN_LOGS_KEY entry is: + // guard_key (1 word), pin_success_log (PIN_LOG_WORDS), pin_entry_log + // (PIN_LOG_WORDS) + uint32_t logs[GUARD_KEY_WORDS + 2 * PIN_LOG_WORDS]; - logs[0] = generate_guard_key(); + logs[0] = generate_guard_key(); - uint32_t guard_mask; - uint32_t guard; - wait_random(); - if (sectrue != expand_guard_key(logs[0], &guard_mask, &guard)) { - return secfalse; - } + uint32_t guard_mask; + uint32_t guard; + wait_random(); + if (sectrue != expand_guard_key(logs[0], &guard_mask, &guard)) { + return secfalse; + } - uint32_t unused = guard | ~guard_mask; - for (size_t i = 0; i < 2*PIN_LOG_WORDS; ++i) { - logs[GUARD_KEY_WORDS + i] = unused; - } + uint32_t unused = guard | ~guard_mask; + for (size_t i = 0; i < 2 * PIN_LOG_WORDS; ++i) { + logs[GUARD_KEY_WORDS + i] = unused; + } - // Set the first word of the PIN entry log to indicate the requested number of fails. - logs[GUARD_KEY_WORDS + PIN_LOG_WORDS] = ((((uint32_t)0xFFFFFFFF) >> (2*fails)) & ~guard_mask) | guard; + // Set the first word of the PIN entry log to indicate the requested number of + // fails. + logs[GUARD_KEY_WORDS + PIN_LOG_WORDS] = + ((((uint32_t)0xFFFFFFFF) >> (2 * fails)) & ~guard_mask) | guard; - return norcow_set(PIN_LOGS_KEY, logs, sizeof(logs)); + return norcow_set(PIN_LOGS_KEY, logs, sizeof(logs)); } /* - * Initializes the values of VERSION_KEY, EDEK_PVC_KEY, PIN_NOT_SET_KEY and PIN_LOGS_KEY using an empty PIN. - * This function should be called to initialize freshly wiped storage. + * Initializes the values of VERSION_KEY, EDEK_PVC_KEY, PIN_NOT_SET_KEY and + * PIN_LOGS_KEY using an empty PIN. This function should be called to initialize + * freshly wiped storage. */ -static void init_wiped_storage(void) -{ - if (sectrue != initialized) { - // We cannot initialize the storage contents if the hardware_salt is not set. - return; - } - random_buffer(cached_keys, sizeof(cached_keys)); - uint32_t version = NORCOW_VERSION; - ensure(auth_init(), "set_storage_auth_tag failed"); - ensure(storage_set_encrypted(VERSION_KEY, &version, sizeof(version)), "set_storage_version failed"); - ensure(pin_logs_init(0), "init_pin_logs failed"); - ui_total = DERIVE_SECS; - ui_rem = ui_total; - ui_message = PROCESSING_MSG; - ensure(set_pin(PIN_EMPTY), "init_pin failed"); - if (unlocked != sectrue) { - memzero(cached_keys, sizeof(cached_keys)); - } +static void init_wiped_storage(void) { + if (sectrue != initialized) { + // We cannot initialize the storage contents if the hardware_salt is not + // set. + return; + } + random_buffer(cached_keys, sizeof(cached_keys)); + uint32_t version = NORCOW_VERSION; + ensure(auth_init(), "set_storage_auth_tag failed"); + ensure(storage_set_encrypted(VERSION_KEY, &version, sizeof(version)), + "set_storage_version failed"); + ensure(pin_logs_init(0), "init_pin_logs failed"); + ui_total = DERIVE_SECS; + ui_rem = ui_total; + ui_message = PROCESSING_MSG; + ensure(set_pin(PIN_EMPTY), "init_pin failed"); + if (unlocked != sectrue) { + memzero(cached_keys, sizeof(cached_keys)); + } } -void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt, const uint16_t salt_len) -{ - initialized = secfalse; - unlocked = secfalse; - norcow_init(&norcow_active_version); - initialized = sectrue; - ui_callback = callback; +void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt, + const uint16_t salt_len) { + initialized = secfalse; + unlocked = secfalse; + norcow_init(&norcow_active_version); + initialized = sectrue; + ui_callback = callback; - sha256_Raw(salt, salt_len, hardware_salt); + sha256_Raw(salt, salt_len, hardware_salt); - if (norcow_active_version < NORCOW_VERSION) { - if (sectrue != storage_upgrade()) { - storage_wipe(); - ensure(secfalse, "storage_upgrade failed"); - } + if (norcow_active_version < NORCOW_VERSION) { + if (sectrue != storage_upgrade()) { + storage_wipe(); + ensure(secfalse, "storage_upgrade failed"); } + } - // If there is no EDEK, then generate a random DEK and SAK and store them. - const void *val; - uint16_t len; - if (secfalse == norcow_get(EDEK_PVC_KEY, &val, &len)) { - init_wiped_storage(); - } - memzero(cached_keys, sizeof(cached_keys)); + // If there is no EDEK, then generate a random DEK and SAK and store them. + const void *val; + uint16_t len; + if (secfalse == norcow_get(EDEK_PVC_KEY, &val, &len)) { + init_wiped_storage(); + } + memzero(cached_keys, sizeof(cached_keys)); } -static secbool pin_fails_reset(void) -{ - const void *logs = NULL; - uint16_t len = 0; +static secbool pin_fails_reset(void) { + const void *logs = NULL; + uint16_t len = 0; - if (sectrue != norcow_get(PIN_LOGS_KEY, &logs, &len) || len != WORD_SIZE*(GUARD_KEY_WORDS + 2*PIN_LOG_WORDS)) { - return secfalse; - } + if (sectrue != norcow_get(PIN_LOGS_KEY, &logs, &len) || + len != WORD_SIZE * (GUARD_KEY_WORDS + 2 * PIN_LOG_WORDS)) { + return secfalse; + } - uint32_t guard_mask; - uint32_t guard; - wait_random(); - if (sectrue != expand_guard_key(*(const uint32_t*)logs, &guard_mask, &guard)) { + uint32_t guard_mask; + uint32_t guard; + wait_random(); + if (sectrue != + expand_guard_key(*(const uint32_t *)logs, &guard_mask, &guard)) { + return secfalse; + } + + uint32_t unused = guard | ~guard_mask; + const uint32_t *success_log = ((const uint32_t *)logs) + GUARD_KEY_WORDS; + const uint32_t *entry_log = success_log + PIN_LOG_WORDS; + for (size_t i = 0; i < PIN_LOG_WORDS; ++i) { + if (entry_log[i] == unused) { + return sectrue; + } + if (success_log[i] != guard) { + if (sectrue != norcow_update_word( + PIN_LOGS_KEY, sizeof(uint32_t) * (i + GUARD_KEY_WORDS), + entry_log[i])) { return secfalse; + } } - - uint32_t unused = guard | ~guard_mask; - const uint32_t *success_log = ((const uint32_t*)logs) + GUARD_KEY_WORDS; - const uint32_t *entry_log = success_log + PIN_LOG_WORDS; - for (size_t i = 0; i < PIN_LOG_WORDS; ++i) { - if (entry_log[i] == unused) { - return sectrue; - } - if (success_log[i] != guard) { - if (sectrue != norcow_update_word(PIN_LOGS_KEY, sizeof(uint32_t)*(i + GUARD_KEY_WORDS), entry_log[i])) { - return secfalse; - } - } - } - return pin_logs_init(0); + } + return pin_logs_init(0); } -secbool storage_pin_fails_increase(void) -{ - if (sectrue != initialized) { - return secfalse; - } +secbool storage_pin_fails_increase(void) { + if (sectrue != initialized) { + return secfalse; + } - const void *logs = NULL; - uint16_t len = 0; + const void *logs = NULL; + uint16_t len = 0; - wait_random(); - if (sectrue != norcow_get(PIN_LOGS_KEY, &logs, &len) || len != WORD_SIZE*(GUARD_KEY_WORDS + 2*PIN_LOG_WORDS)) { - handle_fault("no PIN logs"); - return secfalse; - } + wait_random(); + if (sectrue != norcow_get(PIN_LOGS_KEY, &logs, &len) || + len != WORD_SIZE * (GUARD_KEY_WORDS + 2 * PIN_LOG_WORDS)) { + handle_fault("no PIN logs"); + return secfalse; + } + + uint32_t guard_mask; + uint32_t guard; + wait_random(); + if (sectrue != + expand_guard_key(*(const uint32_t *)logs, &guard_mask, &guard)) { + handle_fault("guard key expansion"); + return secfalse; + } - uint32_t guard_mask; - uint32_t guard; + const uint32_t *entry_log = + ((const uint32_t *)logs) + GUARD_KEY_WORDS + PIN_LOG_WORDS; + for (size_t i = 0; i < PIN_LOG_WORDS; ++i) { wait_random(); - if (sectrue != expand_guard_key(*(const uint32_t*)logs, &guard_mask, &guard)) { - handle_fault("guard key expansion"); + if ((entry_log[i] & guard_mask) != guard) { + handle_fault("guard bits check"); + return secfalse; + } + if (entry_log[i] != guard) { + wait_random(); + uint32_t word = entry_log[i] & ~guard_mask; + word = ((word >> 1) | word) & LOW_MASK; + word = (word >> 2) | (word >> 1); + + wait_random(); + if (sectrue != + norcow_update_word( + PIN_LOGS_KEY, + sizeof(uint32_t) * (i + GUARD_KEY_WORDS + PIN_LOG_WORDS), + (word & ~guard_mask) | guard)) { + handle_fault("PIN logs update"); return secfalse; + } + return sectrue; } - - const uint32_t *entry_log = ((const uint32_t*)logs) + GUARD_KEY_WORDS + PIN_LOG_WORDS; - for (size_t i = 0; i < PIN_LOG_WORDS; ++i) { - wait_random(); - if ((entry_log[i] & guard_mask) != guard) { - handle_fault("guard bits check"); - return secfalse; - } - if (entry_log[i] != guard) { - wait_random(); - uint32_t word = entry_log[i] & ~guard_mask; - word = ((word >> 1) | word) & LOW_MASK; - word = (word >> 2) | (word >> 1); - - wait_random(); - if (sectrue != norcow_update_word(PIN_LOGS_KEY, sizeof(uint32_t)*(i + GUARD_KEY_WORDS + PIN_LOG_WORDS), (word & ~guard_mask) | guard)) { - handle_fault("PIN logs update"); - return secfalse; - } - return sectrue; - } - - } - handle_fault("PIN log exhausted"); - return secfalse; + } + handle_fault("PIN log exhausted"); + return secfalse; } -static uint32_t hamming_weight(uint32_t value) -{ - value = value - ((value >> 1) & 0x55555555); - value = (value & 0x33333333) + ((value >> 2) & 0x33333333); - value = (value + (value >> 4)) & 0x0F0F0F0F; - value = value + (value >> 8); - value = value + (value >> 16); - return value & 0x3F; +static uint32_t hamming_weight(uint32_t value) { + value = value - ((value >> 1) & 0x55555555); + value = (value & 0x33333333) + ((value >> 2) & 0x33333333); + value = (value + (value >> 4)) & 0x0F0F0F0F; + value = value + (value >> 8); + value = value + (value >> 16); + return value & 0x3F; } -static secbool pin_get_fails(uint32_t *ctr) -{ - *ctr = PIN_MAX_TRIES; +static secbool pin_get_fails(uint32_t *ctr) { + *ctr = PIN_MAX_TRIES; - const void *logs = NULL; - uint16_t len = 0; - wait_random(); - if (sectrue != norcow_get(PIN_LOGS_KEY, &logs, &len) || len != WORD_SIZE*(GUARD_KEY_WORDS + 2*PIN_LOG_WORDS)) { - handle_fault("no PIN logs"); - return secfalse; - } - - uint32_t guard_mask; - uint32_t guard; - wait_random(); - if (sectrue != expand_guard_key(*(const uint32_t*)logs, &guard_mask, &guard)) { - handle_fault("guard key expansion"); - return secfalse; - } - const uint32_t unused = guard | ~guard_mask; - - const uint32_t *success_log = ((const uint32_t*)logs) + GUARD_KEY_WORDS; - const uint32_t *entry_log = success_log + PIN_LOG_WORDS; - volatile int current = -1; - volatile size_t i; - for (i = 0; i < PIN_LOG_WORDS; ++i) { - if ((entry_log[i] & guard_mask) != guard || (success_log[i] & guard_mask) != guard || (entry_log[i] & success_log[i]) != entry_log[i]) { - handle_fault("PIN logs format check"); - return secfalse; - } - - if (current == -1) { - if (entry_log[i] != guard) { - current = i; - } - } else { - if (entry_log[i] != unused) { - handle_fault("PIN entry log format check"); - return secfalse; - } - } - } - - if (current < 0 || current >= PIN_LOG_WORDS || i != PIN_LOG_WORDS) { - handle_fault("PIN log exhausted"); - return secfalse; - } - - // Strip the guard bits from the current entry word and duplicate each data bit. - wait_random(); - uint32_t word = entry_log[current] & ~guard_mask; - word = ((word >> 1) | word ) & LOW_MASK; - word = word | (word << 1); - // Verify that the entry word has form 0*1*. - if ((word & (word + 1)) != 0) { + const void *logs = NULL; + uint16_t len = 0; + wait_random(); + if (sectrue != norcow_get(PIN_LOGS_KEY, &logs, &len) || + len != WORD_SIZE * (GUARD_KEY_WORDS + 2 * PIN_LOG_WORDS)) { + handle_fault("no PIN logs"); + return secfalse; + } + + uint32_t guard_mask; + uint32_t guard; + wait_random(); + if (sectrue != + expand_guard_key(*(const uint32_t *)logs, &guard_mask, &guard)) { + handle_fault("guard key expansion"); + return secfalse; + } + const uint32_t unused = guard | ~guard_mask; + + const uint32_t *success_log = ((const uint32_t *)logs) + GUARD_KEY_WORDS; + const uint32_t *entry_log = success_log + PIN_LOG_WORDS; + volatile int current = -1; + volatile size_t i; + for (i = 0; i < PIN_LOG_WORDS; ++i) { + if ((entry_log[i] & guard_mask) != guard || + (success_log[i] & guard_mask) != guard || + (entry_log[i] & success_log[i]) != entry_log[i]) { + handle_fault("PIN logs format check"); + return secfalse; + } + + if (current == -1) { + if (entry_log[i] != guard) { + current = i; + } + } else { + if (entry_log[i] != unused) { handle_fault("PIN entry log format check"); return secfalse; + } } + } - if (current == 0) { - ++current; - } + if (current < 0 || current >= PIN_LOG_WORDS || i != PIN_LOG_WORDS) { + handle_fault("PIN log exhausted"); + return secfalse; + } + + // Strip the guard bits from the current entry word and duplicate each data + // bit. + wait_random(); + uint32_t word = entry_log[current] & ~guard_mask; + word = ((word >> 1) | word) & LOW_MASK; + word = word | (word << 1); + // Verify that the entry word has form 0*1*. + if ((word & (word + 1)) != 0) { + handle_fault("PIN entry log format check"); + return secfalse; + } - // Count the number of set bits in the two current words of the success log. - wait_random(); - *ctr = hamming_weight(success_log[current-1] ^ entry_log[current-1]) + hamming_weight(success_log[current] ^ entry_log[current]); - return sectrue; + if (current == 0) { + ++current; + } + + // Count the number of set bits in the two current words of the success log. + wait_random(); + *ctr = hamming_weight(success_log[current - 1] ^ entry_log[current - 1]) + + hamming_weight(success_log[current] ^ entry_log[current]); + return sectrue; } -secbool storage_is_unlocked(void) -{ - if (sectrue != initialized) { - return secfalse; - } +secbool storage_is_unlocked(void) { + if (sectrue != initialized) { + return secfalse; + } - return unlocked; + return unlocked; } -void storage_lock(void) -{ - unlocked = secfalse; - memzero(cached_keys, sizeof(cached_keys)); - memzero(authentication_sum, sizeof(authentication_sum)); +void storage_lock(void) { + unlocked = secfalse; + memzero(cached_keys, sizeof(cached_keys)); + memzero(authentication_sum, sizeof(authentication_sum)); } -static secbool decrypt_dek(const uint8_t *kek, const uint8_t *keiv) -{ - const void *buffer = NULL; - uint16_t len = 0; - if (sectrue != initialized || sectrue != norcow_get(EDEK_PVC_KEY, &buffer, &len) || len != RANDOM_SALT_SIZE + KEYS_SIZE + PVC_SIZE) { - handle_fault("no EDEK"); - return secfalse; - } - - const uint8_t *ekeys = (const uint8_t*) buffer + RANDOM_SALT_SIZE; - const uint32_t *pvc = (const uint32_t*) buffer + (RANDOM_SALT_SIZE + KEYS_SIZE)/sizeof(uint32_t); - _Static_assert(((RANDOM_SALT_SIZE + KEYS_SIZE) & 3) == 0, "PVC unaligned"); - _Static_assert((PVC_SIZE & 3) == 0, "PVC size unaligned"); - - uint8_t keys[KEYS_SIZE]; - uint8_t tag[POLY1305_TAG_SIZE] __attribute__((aligned(sizeof(uint32_t)))); - chacha20poly1305_ctx ctx; - - // Decrypt the data encryption key and the storage authentication key and check the PIN verification code. - rfc7539_init(&ctx, kek, keiv); - chacha20poly1305_decrypt(&ctx, ekeys, keys, KEYS_SIZE); - rfc7539_finish(&ctx, 0, KEYS_SIZE, tag); - memzero(&ctx, sizeof(ctx)); - wait_random(); - if (secequal32((const uint32_t*) tag, pvc, PVC_SIZE/sizeof(uint32_t)) != sectrue) { - memzero(keys, sizeof(keys)); - memzero(tag, sizeof(tag)); - return secfalse; - } - memcpy(cached_keys, keys, sizeof(keys)); +static secbool decrypt_dek(const uint8_t *kek, const uint8_t *keiv) { + const void *buffer = NULL; + uint16_t len = 0; + if (sectrue != initialized || + sectrue != norcow_get(EDEK_PVC_KEY, &buffer, &len) || + len != RANDOM_SALT_SIZE + KEYS_SIZE + PVC_SIZE) { + handle_fault("no EDEK"); + return secfalse; + } + + const uint8_t *ekeys = (const uint8_t *)buffer + RANDOM_SALT_SIZE; + const uint32_t *pvc = (const uint32_t *)buffer + + (RANDOM_SALT_SIZE + KEYS_SIZE) / sizeof(uint32_t); + _Static_assert(((RANDOM_SALT_SIZE + KEYS_SIZE) & 3) == 0, "PVC unaligned"); + _Static_assert((PVC_SIZE & 3) == 0, "PVC size unaligned"); + + uint8_t keys[KEYS_SIZE]; + uint8_t tag[POLY1305_TAG_SIZE] __attribute__((aligned(sizeof(uint32_t)))); + chacha20poly1305_ctx ctx; + + // Decrypt the data encryption key and the storage authentication key and + // check the PIN verification code. + rfc7539_init(&ctx, kek, keiv); + chacha20poly1305_decrypt(&ctx, ekeys, keys, KEYS_SIZE); + rfc7539_finish(&ctx, 0, KEYS_SIZE, tag); + memzero(&ctx, sizeof(ctx)); + wait_random(); + if (secequal32((const uint32_t *)tag, pvc, PVC_SIZE / sizeof(uint32_t)) != + sectrue) { memzero(keys, sizeof(keys)); memzero(tag, sizeof(tag)); + return secfalse; + } + memcpy(cached_keys, keys, sizeof(keys)); + memzero(keys, sizeof(keys)); + memzero(tag, sizeof(tag)); + + // Check that the authenticated version number matches the norcow version. + // NOTE: storage_get_encrypted() calls auth_get(), which initializes the + // authentication_sum. + uint32_t version; + if (sectrue != + storage_get_encrypted(VERSION_KEY, &version, sizeof(version), &len) || + len != sizeof(version) || version != norcow_active_version) { + handle_fault("storage version check"); + return secfalse; + } - // Check that the authenticated version number matches the norcow version. - // NOTE: storage_get_encrypted() calls auth_get(), which initializes the authentication_sum. - uint32_t version; - if (sectrue != storage_get_encrypted(VERSION_KEY, &version, sizeof(version), &len) || len != sizeof(version) || version != norcow_active_version) { - handle_fault("storage version check"); - return secfalse; - } - - return sectrue; + return sectrue; } -static secbool unlock(uint32_t pin) -{ - if (sectrue != initialized) { - return secfalse; - } - - // Get the pin failure counter - uint32_t ctr; - if (sectrue != pin_get_fails(&ctr)) { - memzero(&pin, sizeof(pin)); - return secfalse; - } - - // Wipe storage if too many failures - wait_random(); - if (ctr >= PIN_MAX_TRIES) { - storage_wipe(); - error_shutdown("Too many wrong PIN", "attempts. Storage has", "been wiped.", NULL); - return secfalse; - } +static secbool unlock(uint32_t pin) { + if (sectrue != initialized) { + return secfalse; + } - // Sleep for 2^ctr - 1 seconds before checking the PIN. - uint32_t wait = (1 << ctr) - 1; - ui_total += wait; - uint32_t progress = 0; - for (ui_rem = ui_total; ui_rem > ui_total - wait; ui_rem--) { - for (int i = 0; i < 10; i++) { - if (ui_callback && ui_message) { - if (ui_total > 1000000) { // precise enough - progress = (ui_total - ui_rem) / (ui_total / 1000); - } else { - progress = ((ui_total - ui_rem) * 10 + i) * 100 / ui_total; - } - if (sectrue == ui_callback(ui_rem, progress, ui_message)) { - return secfalse; - } - } - hal_delay(100); + // Get the pin failure counter + uint32_t ctr; + if (sectrue != pin_get_fails(&ctr)) { + memzero(&pin, sizeof(pin)); + return secfalse; + } + + // Wipe storage if too many failures + wait_random(); + if (ctr >= PIN_MAX_TRIES) { + storage_wipe(); + error_shutdown("Too many wrong PIN", "attempts. Storage has", "been wiped.", + NULL); + return secfalse; + } + + // Sleep for 2^ctr - 1 seconds before checking the PIN. + uint32_t wait = (1 << ctr) - 1; + ui_total += wait; + uint32_t progress = 0; + for (ui_rem = ui_total; ui_rem > ui_total - wait; ui_rem--) { + for (int i = 0; i < 10; i++) { + if (ui_callback && ui_message) { + if (ui_total > 1000000) { // precise enough + progress = (ui_total - ui_rem) / (ui_total / 1000); + } else { + progress = ((ui_total - ui_rem) * 10 + i) * 100 / ui_total; } - } - - // Read the random salt from EDEK_PVC_KEY and use it to derive the KEK and KEIV from the PIN. - const void *salt = NULL; - uint16_t len = 0; - if (sectrue != initialized || sectrue != norcow_get(EDEK_PVC_KEY, &salt, &len) || len != RANDOM_SALT_SIZE + KEYS_SIZE + PVC_SIZE) { - memzero(&pin, sizeof(pin)); - handle_fault("no EDEK"); - return secfalse; - } - uint8_t kek[SHA256_DIGEST_LENGTH]; - uint8_t keiv[SHA256_DIGEST_LENGTH]; - derive_kek(pin, (const uint8_t*) salt, kek, keiv); + if (sectrue == ui_callback(ui_rem, progress, ui_message)) { + return secfalse; + } + } + hal_delay(100); + } + } + + // Read the random salt from EDEK_PVC_KEY and use it to derive the KEK and + // KEIV from the PIN. + const void *salt = NULL; + uint16_t len = 0; + if (sectrue != initialized || + sectrue != norcow_get(EDEK_PVC_KEY, &salt, &len) || + len != RANDOM_SALT_SIZE + KEYS_SIZE + PVC_SIZE) { memzero(&pin, sizeof(pin)); + handle_fault("no EDEK"); + return secfalse; + } + uint8_t kek[SHA256_DIGEST_LENGTH]; + uint8_t keiv[SHA256_DIGEST_LENGTH]; + derive_kek(pin, (const uint8_t *)salt, kek, keiv); + memzero(&pin, sizeof(pin)); + + // First, we increase PIN fail counter in storage, even before checking the + // PIN. If the PIN is correct, we reset the counter afterwards. If not, we + // check if this is the last allowed attempt. + if (sectrue != storage_pin_fails_increase()) { + return secfalse; + } - // First, we increase PIN fail counter in storage, even before checking the - // PIN. If the PIN is correct, we reset the counter afterwards. If not, we - // check if this is the last allowed attempt. - if (sectrue != storage_pin_fails_increase()) { - return secfalse; - } - - // Check that the PIN fail counter was incremented. - uint32_t ctr_ck; - if (sectrue != pin_get_fails(&ctr_ck) || ctr + 1 != ctr_ck) { - handle_fault("PIN counter increment"); - return secfalse; - } + // Check that the PIN fail counter was incremented. + uint32_t ctr_ck; + if (sectrue != pin_get_fails(&ctr_ck) || ctr + 1 != ctr_ck) { + handle_fault("PIN counter increment"); + return secfalse; + } - // Check that the PIN was correct. - if (sectrue != decrypt_dek(kek, keiv)) { - // Wipe storage if too many failures - wait_random(); - if (ctr + 1 >= PIN_MAX_TRIES) { - storage_wipe(); - error_shutdown("Too many wrong PIN", "attempts. Storage has", "been wiped.", NULL); - } - return secfalse; + // Check that the PIN was correct. + if (sectrue != decrypt_dek(kek, keiv)) { + // Wipe storage if too many failures + wait_random(); + if (ctr + 1 >= PIN_MAX_TRIES) { + storage_wipe(); + error_shutdown("Too many wrong PIN", "attempts. Storage has", + "been wiped.", NULL); } - memzero(kek, sizeof(kek)); - memzero(keiv, sizeof(keiv)); + return secfalse; + } + memzero(kek, sizeof(kek)); + memzero(keiv, sizeof(keiv)); - unlocked = sectrue; + unlocked = sectrue; - // Finally set the counter to 0 to indicate success. - return pin_fails_reset(); + // Finally set the counter to 0 to indicate success. + return pin_fails_reset(); } -secbool storage_unlock(uint32_t pin) -{ - ui_total = DERIVE_SECS; - ui_rem = ui_total; - if (pin == PIN_EMPTY) { - if (ui_message == NULL) { - ui_message = STARTING_MSG; - } else { - ui_message = PROCESSING_MSG; - } +secbool storage_unlock(uint32_t pin) { + ui_total = DERIVE_SECS; + ui_rem = ui_total; + if (pin == PIN_EMPTY) { + if (ui_message == NULL) { + ui_message = STARTING_MSG; } else { - ui_message = VERIFYING_PIN_MSG; + ui_message = PROCESSING_MSG; } - return unlock(pin); + } else { + ui_message = VERIFYING_PIN_MSG; + } + return unlock(pin); } /* @@ -877,410 +919,414 @@ secbool storage_unlock(uint32_t pin) * If val_dest is not NULL and max_len >= len, then the data is decrypted * to val_dest using cached_dek as the decryption key. */ -static secbool storage_get_encrypted(const uint16_t key, void *val_dest, const uint16_t max_len, uint16_t *len) -{ - const void *val_stored = NULL; +static secbool storage_get_encrypted(const uint16_t key, void *val_dest, + const uint16_t max_len, uint16_t *len) { + const void *val_stored = NULL; - if (sectrue != auth_get(key, &val_stored, len)) { - return secfalse; - } - - if (*len < CHACHA20_IV_SIZE + POLY1305_TAG_SIZE) { - handle_fault("ciphertext length check"); - return secfalse; - } - *len -= CHACHA20_IV_SIZE + POLY1305_TAG_SIZE; - - if (val_dest == NULL) { - return sectrue; - } + if (sectrue != auth_get(key, &val_stored, len)) { + return secfalse; + } - if (*len > max_len) { - return secfalse; - } + if (*len < CHACHA20_IV_SIZE + POLY1305_TAG_SIZE) { + handle_fault("ciphertext length check"); + return secfalse; + } + *len -= CHACHA20_IV_SIZE + POLY1305_TAG_SIZE; - const uint8_t *iv = (const uint8_t*) val_stored; - const uint8_t *tag_stored = (const uint8_t*) val_stored + CHACHA20_IV_SIZE; - const uint8_t *ciphertext = (const uint8_t*) val_stored + CHACHA20_IV_SIZE + POLY1305_TAG_SIZE; - uint8_t tag_computed[POLY1305_TAG_SIZE]; - chacha20poly1305_ctx ctx; - rfc7539_init(&ctx, cached_dek, iv); - rfc7539_auth(&ctx, (const uint8_t*)&key, sizeof(key)); - chacha20poly1305_decrypt(&ctx, ciphertext, (uint8_t*) val_dest, *len); - rfc7539_finish(&ctx, sizeof(key), *len, tag_computed); - memzero(&ctx, sizeof(ctx)); - - // Verify authentication tag. - if (secequal(tag_computed, tag_stored, POLY1305_TAG_SIZE) != sectrue) { - memzero(val_dest, max_len); - memzero(tag_computed, sizeof(tag_computed)); - handle_fault("authentication tag check"); - return secfalse; - } + if (val_dest == NULL) { + return sectrue; + } + if (*len > max_len) { + return secfalse; + } + + const uint8_t *iv = (const uint8_t *)val_stored; + const uint8_t *tag_stored = (const uint8_t *)val_stored + CHACHA20_IV_SIZE; + const uint8_t *ciphertext = + (const uint8_t *)val_stored + CHACHA20_IV_SIZE + POLY1305_TAG_SIZE; + uint8_t tag_computed[POLY1305_TAG_SIZE]; + chacha20poly1305_ctx ctx; + rfc7539_init(&ctx, cached_dek, iv); + rfc7539_auth(&ctx, (const uint8_t *)&key, sizeof(key)); + chacha20poly1305_decrypt(&ctx, ciphertext, (uint8_t *)val_dest, *len); + rfc7539_finish(&ctx, sizeof(key), *len, tag_computed); + memzero(&ctx, sizeof(ctx)); + + // Verify authentication tag. + if (secequal(tag_computed, tag_stored, POLY1305_TAG_SIZE) != sectrue) { + memzero(val_dest, max_len); memzero(tag_computed, sizeof(tag_computed)); - return sectrue; + handle_fault("authentication tag check"); + return secfalse; + } + + memzero(tag_computed, sizeof(tag_computed)); + return sectrue; } /* * Finds the data stored under key and writes its length to len. If val_dest is * not NULL and max_len >= len, then the data is copied to val_dest. */ -secbool storage_get(const uint16_t key, void *val_dest, const uint16_t max_len, uint16_t *len) -{ - const uint8_t app = key >> 8; - // APP == 0 is reserved for PIN related values - if (sectrue != initialized || app == APP_STORAGE) { - return secfalse; - } +secbool storage_get(const uint16_t key, void *val_dest, const uint16_t max_len, + uint16_t *len) { + const uint8_t app = key >> 8; + // APP == 0 is reserved for PIN related values + if (sectrue != initialized || app == APP_STORAGE) { + return secfalse; + } - // If the top bit of APP is set, then the value is not encrypted and can be read from a locked device. - secbool ret = secfalse; - if ((app & FLAG_PUBLIC) != 0) { - const void *val_stored = NULL; - if (sectrue != norcow_get(key, &val_stored, len)) { - return secfalse; - } - if (val_dest == NULL) { - return sectrue; - } - if (*len > max_len) { - return secfalse; - } - memcpy(val_dest, val_stored, *len); - ret = sectrue; - } else { - if (sectrue != unlocked) { - return secfalse; - } - ret = storage_get_encrypted(key, val_dest, max_len, len); + // If the top bit of APP is set, then the value is not encrypted and can be + // read from a locked device. + secbool ret = secfalse; + if ((app & FLAG_PUBLIC) != 0) { + const void *val_stored = NULL; + if (sectrue != norcow_get(key, &val_stored, len)) { + return secfalse; + } + if (val_dest == NULL) { + return sectrue; } + if (*len > max_len) { + return secfalse; + } + memcpy(val_dest, val_stored, *len); + ret = sectrue; + } else { + if (sectrue != unlocked) { + return secfalse; + } + ret = storage_get_encrypted(key, val_dest, max_len, len); + } - return ret; + return ret; } /* - * Encrypts the data at val using cached_dek as the encryption key and stores the ciphertext under key. + * Encrypts the data at val using cached_dek as the encryption key and stores + * the ciphertext under key. */ -static secbool storage_set_encrypted(const uint16_t key, const void *val, const uint16_t len) -{ - if (len > UINT16_MAX - CHACHA20_IV_SIZE - POLY1305_TAG_SIZE) { - return secfalse; - } - - // Preallocate space on the flash storage. - if (sectrue != auth_set(key, NULL, CHACHA20_IV_SIZE + POLY1305_TAG_SIZE + len)) { - return secfalse; - } +static secbool storage_set_encrypted(const uint16_t key, const void *val, + const uint16_t len) { + if (len > UINT16_MAX - CHACHA20_IV_SIZE - POLY1305_TAG_SIZE) { + return secfalse; + } - // Write the IV to the flash. - uint8_t buffer[CHACHA20_BLOCK_SIZE]; - random_buffer(buffer, CHACHA20_IV_SIZE); - uint16_t offset = 0; - if (sectrue != norcow_update_bytes(key, offset, buffer, CHACHA20_IV_SIZE)) { - return secfalse; - } - offset += CHACHA20_IV_SIZE + POLY1305_TAG_SIZE; - - // Encrypt all blocks except for the last one. - chacha20poly1305_ctx ctx; - rfc7539_init(&ctx, cached_dek, buffer); - rfc7539_auth(&ctx, (const uint8_t*)&key, sizeof(key)); - size_t i; - for (i = 0; i + CHACHA20_BLOCK_SIZE < len; i += CHACHA20_BLOCK_SIZE, offset += CHACHA20_BLOCK_SIZE) { - chacha20poly1305_encrypt(&ctx, ((const uint8_t*) val) + i, buffer, CHACHA20_BLOCK_SIZE); - if (sectrue != norcow_update_bytes(key, offset, buffer, CHACHA20_BLOCK_SIZE)) { - memzero(&ctx, sizeof(ctx)); - memzero(buffer, sizeof(buffer)); - return secfalse; - } - } + // Preallocate space on the flash storage. + if (sectrue != + auth_set(key, NULL, CHACHA20_IV_SIZE + POLY1305_TAG_SIZE + len)) { + return secfalse; + } - // Encrypt final block and compute message authentication tag. - chacha20poly1305_encrypt(&ctx, ((const uint8_t*) val) + i, buffer, len - i); - secbool ret = norcow_update_bytes(key, offset, buffer, len - i); - if (sectrue == ret) { - rfc7539_finish(&ctx, sizeof(key), len, buffer); - ret = norcow_update_bytes(key, CHACHA20_IV_SIZE, buffer, POLY1305_TAG_SIZE); - } - memzero(&ctx, sizeof(ctx)); - memzero(buffer, sizeof(buffer)); - return ret; + // Write the IV to the flash. + uint8_t buffer[CHACHA20_BLOCK_SIZE]; + random_buffer(buffer, CHACHA20_IV_SIZE); + uint16_t offset = 0; + if (sectrue != norcow_update_bytes(key, offset, buffer, CHACHA20_IV_SIZE)) { + return secfalse; + } + offset += CHACHA20_IV_SIZE + POLY1305_TAG_SIZE; + + // Encrypt all blocks except for the last one. + chacha20poly1305_ctx ctx; + rfc7539_init(&ctx, cached_dek, buffer); + rfc7539_auth(&ctx, (const uint8_t *)&key, sizeof(key)); + size_t i; + for (i = 0; i + CHACHA20_BLOCK_SIZE < len; + i += CHACHA20_BLOCK_SIZE, offset += CHACHA20_BLOCK_SIZE) { + chacha20poly1305_encrypt(&ctx, ((const uint8_t *)val) + i, buffer, + CHACHA20_BLOCK_SIZE); + if (sectrue != + norcow_update_bytes(key, offset, buffer, CHACHA20_BLOCK_SIZE)) { + memzero(&ctx, sizeof(ctx)); + memzero(buffer, sizeof(buffer)); + return secfalse; + } + } + + // Encrypt final block and compute message authentication tag. + chacha20poly1305_encrypt(&ctx, ((const uint8_t *)val) + i, buffer, len - i); + secbool ret = norcow_update_bytes(key, offset, buffer, len - i); + if (sectrue == ret) { + rfc7539_finish(&ctx, sizeof(key), len, buffer); + ret = norcow_update_bytes(key, CHACHA20_IV_SIZE, buffer, POLY1305_TAG_SIZE); + } + memzero(&ctx, sizeof(ctx)); + memzero(buffer, sizeof(buffer)); + return ret; } -secbool storage_set(const uint16_t key, const void *val, const uint16_t len) -{ - const uint8_t app = key >> 8; +secbool storage_set(const uint16_t key, const void *val, const uint16_t len) { + const uint8_t app = key >> 8; - // APP == 0 is reserved for PIN related values - if (sectrue != initialized || app == APP_STORAGE) { - return secfalse; - } - - if (sectrue != unlocked && (app & FLAGS_WRITE) != FLAGS_WRITE) { - return secfalse; - } + // APP == 0 is reserved for PIN related values + if (sectrue != initialized || app == APP_STORAGE) { + return secfalse; + } - secbool ret = secfalse; - if ((app & FLAG_PUBLIC) != 0) { - ret = norcow_set(key, val, len); - } else { - ret = storage_set_encrypted(key, val, len); - } - return ret; + if (sectrue != unlocked && (app & FLAGS_WRITE) != FLAGS_WRITE) { + return secfalse; + } + + secbool ret = secfalse; + if ((app & FLAG_PUBLIC) != 0) { + ret = norcow_set(key, val, len); + } else { + ret = storage_set_encrypted(key, val, len); + } + return ret; } -secbool storage_delete(const uint16_t key) -{ - const uint8_t app = key >> 8; +secbool storage_delete(const uint16_t key) { + const uint8_t app = key >> 8; - // APP == 0 is reserved for storage related values - if (sectrue != initialized || app == APP_STORAGE) { - return secfalse; - } + // APP == 0 is reserved for storage related values + if (sectrue != initialized || app == APP_STORAGE) { + return secfalse; + } - if (sectrue != unlocked && (app & FLAGS_WRITE) != FLAGS_WRITE) { - return secfalse; - } + if (sectrue != unlocked && (app & FLAGS_WRITE) != FLAGS_WRITE) { + return secfalse; + } - secbool ret = norcow_delete(key); - if (sectrue == ret) { - ret = auth_update(key); - } - return ret; + secbool ret = norcow_delete(key); + if (sectrue == ret) { + ret = auth_update(key); + } + return ret; } -secbool storage_set_counter(const uint16_t key, const uint32_t count) -{ - const uint8_t app = key >> 8; - if ((app & FLAG_PUBLIC) == 0) { - return secfalse; - } - - // The count is stored as a 32-bit integer followed by a tail of "1" bits, - // which is used as a tally. - uint32_t value[1 + COUNTER_TAIL_WORDS]; - memset(value, 0xff, sizeof(value)); - value[0] = count; - return storage_set(key, value, sizeof(value)); +secbool storage_set_counter(const uint16_t key, const uint32_t count) { + const uint8_t app = key >> 8; + if ((app & FLAG_PUBLIC) == 0) { + return secfalse; + } + + // The count is stored as a 32-bit integer followed by a tail of "1" bits, + // which is used as a tally. + uint32_t value[1 + COUNTER_TAIL_WORDS]; + memset(value, 0xff, sizeof(value)); + value[0] = count; + return storage_set(key, value, sizeof(value)); } -secbool storage_next_counter(const uint16_t key, uint32_t *count) -{ - const uint8_t app = key >> 8; - // APP == 0 is reserved for PIN related values - if (sectrue != initialized || app == APP_STORAGE || (app & FLAG_PUBLIC) == 0) { - return secfalse; - } - - if (sectrue != unlocked && (app & FLAGS_WRITE) != FLAGS_WRITE) { - return secfalse; - } - - uint16_t len = 0; - const uint32_t *val_stored = NULL; - if (sectrue != norcow_get(key, (const void**)&val_stored, &len)) { - *count = 0; - return storage_set_counter(key, 0); - } - - if (len < sizeof(uint32_t) || len % sizeof(uint32_t) != 0) { - return secfalse; - } - uint16_t len_words = len / sizeof(uint32_t); +secbool storage_next_counter(const uint16_t key, uint32_t *count) { + const uint8_t app = key >> 8; + // APP == 0 is reserved for PIN related values + if (sectrue != initialized || app == APP_STORAGE || + (app & FLAG_PUBLIC) == 0) { + return secfalse; + } - uint16_t i = 1; - while (i < len_words && val_stored[i] == 0) { - ++i; - } + if (sectrue != unlocked && (app & FLAGS_WRITE) != FLAGS_WRITE) { + return secfalse; + } - *count = val_stored[0] + 1 + 32 * (i - 1); + uint16_t len = 0; + const uint32_t *val_stored = NULL; + if (sectrue != norcow_get(key, (const void **)&val_stored, &len)) { + *count = 0; + return storage_set_counter(key, 0); + } - if (i < len_words) { - *count += hamming_weight(~val_stored[i]); - return norcow_update_word(key, sizeof(uint32_t) * i, val_stored[i] >> 1); - } else { - return storage_set_counter(key, *count); - } + if (len < sizeof(uint32_t) || len % sizeof(uint32_t) != 0) { + return secfalse; + } + uint16_t len_words = len / sizeof(uint32_t); + + uint16_t i = 1; + while (i < len_words && val_stored[i] == 0) { + ++i; + } + + *count = val_stored[0] + 1 + 32 * (i - 1); + + if (i < len_words) { + *count += hamming_weight(~val_stored[i]); + return norcow_update_word(key, sizeof(uint32_t) * i, val_stored[i] >> 1); + } else { + return storage_set_counter(key, *count); + } } -secbool storage_has_pin(void) -{ - if (sectrue != initialized) { - return secfalse; - } +secbool storage_has_pin(void) { + if (sectrue != initialized) { + return secfalse; + } - const void *val = NULL; - uint16_t len; - if (sectrue != norcow_get(PIN_NOT_SET_KEY, &val, &len) || (len > 0 && *(uint8_t*)val != FALSE_BYTE)) { - return secfalse; - } - return sectrue; + const void *val = NULL; + uint16_t len; + if (sectrue != norcow_get(PIN_NOT_SET_KEY, &val, &len) || + (len > 0 && *(uint8_t *)val != FALSE_BYTE)) { + return secfalse; + } + return sectrue; } -uint32_t storage_get_pin_rem(void) -{ - if (sectrue != initialized) { - return 0; - } +uint32_t storage_get_pin_rem(void) { + if (sectrue != initialized) { + return 0; + } - uint32_t ctr = 0; - if (sectrue != pin_get_fails(&ctr)) { - return 0; - } - return PIN_MAX_TRIES - ctr; + uint32_t ctr = 0; + if (sectrue != pin_get_fails(&ctr)) { + return 0; + } + return PIN_MAX_TRIES - ctr; } -secbool storage_change_pin(uint32_t oldpin, uint32_t newpin) -{ - if (sectrue != initialized) { - return secfalse; - } +secbool storage_change_pin(uint32_t oldpin, uint32_t newpin) { + if (sectrue != initialized) { + return secfalse; + } - ui_total = 2 * DERIVE_SECS; - ui_rem = ui_total; - ui_message = (oldpin != PIN_EMPTY && newpin == PIN_EMPTY) ? VERIFYING_PIN_MSG : PROCESSING_MSG; + ui_total = 2 * DERIVE_SECS; + ui_rem = ui_total; + ui_message = (oldpin != PIN_EMPTY && newpin == PIN_EMPTY) ? VERIFYING_PIN_MSG + : PROCESSING_MSG; - if (sectrue != unlock(oldpin)) { - return secfalse; - } - secbool ret = set_pin(newpin); - memzero(&oldpin, sizeof(oldpin)); - memzero(&newpin, sizeof(newpin)); - return ret; + if (sectrue != unlock(oldpin)) { + return secfalse; + } + secbool ret = set_pin(newpin); + memzero(&oldpin, sizeof(oldpin)); + memzero(&newpin, sizeof(newpin)); + return ret; } -void storage_wipe(void) -{ - norcow_wipe(); - norcow_active_version = NORCOW_VERSION; - memzero(authentication_sum, sizeof(authentication_sum)); - memzero(cached_keys, sizeof(cached_keys)); - init_wiped_storage(); +void storage_wipe(void) { + norcow_wipe(); + norcow_active_version = NORCOW_VERSION; + memzero(authentication_sum, sizeof(authentication_sum)); + memzero(cached_keys, sizeof(cached_keys)); + init_wiped_storage(); } -static void __handle_fault(const char *msg, const char *file, int line, const char *func) -{ - static secbool in_progress = secfalse; +static void __handle_fault(const char *msg, const char *file, int line, + const char *func) { + static secbool in_progress = secfalse; - // If fault handling is already in progress, then we are probably facing a fault injection attack, so wipe. - if (secfalse != in_progress) { - storage_wipe(); - __fatal_error("Fault detected", msg, file, line, func); - } - - // We use the PIN fail counter as a fault counter. Increment the counter, check that it was incremented and halt. - in_progress = sectrue; - uint32_t ctr; - if (sectrue != pin_get_fails(&ctr)) { - storage_wipe(); - __fatal_error("Fault detected", msg, file, line, func); - } - - if (sectrue != storage_pin_fails_increase()) { - storage_wipe(); - __fatal_error("Fault detected", msg, file, line, func); - } + // If fault handling is already in progress, then we are probably facing a + // fault injection attack, so wipe. + if (secfalse != in_progress) { + storage_wipe(); + __fatal_error("Fault detected", msg, file, line, func); + } + + // We use the PIN fail counter as a fault counter. Increment the counter, + // check that it was incremented and halt. + in_progress = sectrue; + uint32_t ctr; + if (sectrue != pin_get_fails(&ctr)) { + storage_wipe(); + __fatal_error("Fault detected", msg, file, line, func); + } - uint32_t ctr_new; - if (sectrue != pin_get_fails(&ctr_new) || ctr + 1 != ctr_new) { - storage_wipe(); - } + if (sectrue != storage_pin_fails_increase()) { + storage_wipe(); __fatal_error("Fault detected", msg, file, line, func); + } + + uint32_t ctr_new; + if (sectrue != pin_get_fails(&ctr_new) || ctr + 1 != ctr_new) { + storage_wipe(); + } + __fatal_error("Fault detected", msg, file, line, func); } /* - * Reads the PIN fail counter in version 0 format. Returns the current number of failed PIN entries. + * Reads the PIN fail counter in version 0 format. Returns the current number of + * failed PIN entries. */ -static secbool v0_pin_get_fails(uint32_t *ctr) -{ - const uint16_t V0_PIN_FAIL_KEY = 0x0001; - // The PIN_FAIL_KEY points to an area of words, initialized to - // 0xffffffff (meaning no PIN failures). The first non-zero word - // in this area is the current PIN failure counter. If PIN_FAIL_KEY - // has no configuration or is empty, the PIN failure counter is 0. - // We rely on the fact that flash allows to clear bits and we clear one - // bit to indicate PIN failure. On success, the word is set to 0, - // indicating that the next word is the PIN failure counter. - - // Find the current pin failure counter - const void *val = NULL; - uint16_t len = 0; - if (secfalse != norcow_get(V0_PIN_FAIL_KEY, &val, &len)) { - for (unsigned int i = 0; i < len / sizeof(uint32_t); i++) { - uint32_t word = ((const uint32_t*)val)[i]; - if (word != 0) { - *ctr = hamming_weight(~word); - return sectrue; - } - } +static secbool v0_pin_get_fails(uint32_t *ctr) { + const uint16_t V0_PIN_FAIL_KEY = 0x0001; + // The PIN_FAIL_KEY points to an area of words, initialized to + // 0xffffffff (meaning no PIN failures). The first non-zero word + // in this area is the current PIN failure counter. If PIN_FAIL_KEY + // has no configuration or is empty, the PIN failure counter is 0. + // We rely on the fact that flash allows to clear bits and we clear one + // bit to indicate PIN failure. On success, the word is set to 0, + // indicating that the next word is the PIN failure counter. + + // Find the current pin failure counter + const void *val = NULL; + uint16_t len = 0; + if (secfalse != norcow_get(V0_PIN_FAIL_KEY, &val, &len)) { + for (unsigned int i = 0; i < len / sizeof(uint32_t); i++) { + uint32_t word = ((const uint32_t *)val)[i]; + if (word != 0) { + *ctr = hamming_weight(~word); + return sectrue; + } } + } - // No PIN failures - *ctr = 0; - return sectrue; + // No PIN failures + *ctr = 0; + return sectrue; } -static secbool storage_upgrade(void) -{ - const uint16_t V0_PIN_KEY = 0x0000; - const uint16_t V0_PIN_FAIL_KEY = 0x0001; - uint16_t key = 0; - uint16_t len = 0; - const void *val = NULL; +static secbool storage_upgrade(void) { + const uint16_t V0_PIN_KEY = 0x0000; + const uint16_t V0_PIN_FAIL_KEY = 0x0001; + uint16_t key = 0; + uint16_t len = 0; + const void *val = NULL; + + if (norcow_active_version == 0) { + random_buffer(cached_keys, sizeof(cached_keys)); - if (norcow_active_version == 0) { - random_buffer(cached_keys, sizeof(cached_keys)); + // Initialize the storage authentication tag. + auth_init(); - // Initialize the storage authentication tag. - auth_init(); + // Set the new storage version number. + uint32_t version = NORCOW_VERSION; + if (sectrue != + storage_set_encrypted(VERSION_KEY, &version, sizeof(version))) { + return secfalse; + } - // Set the new storage version number. - uint32_t version = NORCOW_VERSION; - if (sectrue != storage_set_encrypted(VERSION_KEY, &version, sizeof(version))) { - return secfalse; - } + // Set EDEK_PVC_KEY and PIN_NOT_SET_KEY. + ui_total = DERIVE_SECS; + ui_rem = ui_total; + ui_message = PROCESSING_MSG; + if (sectrue == norcow_get(V0_PIN_KEY, &val, &len)) { + set_pin(*(const uint32_t *)val); + } else { + set_pin(PIN_EMPTY); + } - // Set EDEK_PVC_KEY and PIN_NOT_SET_KEY. - ui_total = DERIVE_SECS; - ui_rem = ui_total; - ui_message = PROCESSING_MSG; - if (sectrue == norcow_get(V0_PIN_KEY, &val, &len)) { - set_pin(*(const uint32_t*)val); - } else { - set_pin(PIN_EMPTY); - } + // Convert PIN failure counter. + uint32_t fails = 0; + v0_pin_get_fails(&fails); + pin_logs_init(fails); - // Convert PIN failure counter. - uint32_t fails = 0; - v0_pin_get_fails(&fails); - pin_logs_init(fails); - - // Copy the remaining entries (encrypting the protected ones). - uint32_t offset = 0; - while (sectrue == norcow_get_next(&offset, &key, &val, &len)) { - if (key == V0_PIN_KEY || key == V0_PIN_FAIL_KEY) { - continue; - } - - secbool ret; - if (((key >> 8) & FLAG_PUBLIC) != 0) { - ret = norcow_set(key, val, len); - } else { - ret = storage_set_encrypted(key, val, len); - } - - if (sectrue != ret) { - return secfalse; - } - } + // Copy the remaining entries (encrypting the protected ones). + uint32_t offset = 0; + while (sectrue == norcow_get_next(&offset, &key, &val, &len)) { + if (key == V0_PIN_KEY || key == V0_PIN_FAIL_KEY) { + continue; + } - unlocked = secfalse; - memzero(cached_keys, sizeof(cached_keys)); - } else { + secbool ret; + if (((key >> 8) & FLAG_PUBLIC) != 0) { + ret = norcow_set(key, val, len); + } else { + ret = storage_set_encrypted(key, val, len); + } + + if (sectrue != ret) { return secfalse; + } } - norcow_active_version = NORCOW_VERSION; - return norcow_upgrade_finish(); + unlocked = secfalse; + memzero(cached_keys, sizeof(cached_keys)); + } else { + return secfalse; + } + + norcow_active_version = NORCOW_VERSION; + return norcow_upgrade_finish(); } diff --git a/storage/storage.h b/storage/storage.h index e3a163247..becfb2990 100644 --- a/storage/storage.h +++ b/storage/storage.h @@ -20,13 +20,15 @@ #ifndef __STORAGE_H__ #define __STORAGE_H__ -#include #include +#include #include "secbool.h" -typedef secbool (*PIN_UI_WAIT_CALLBACK)(uint32_t wait, uint32_t progress, const char* message); +typedef secbool (*PIN_UI_WAIT_CALLBACK)(uint32_t wait, uint32_t progress, + const char *message); -void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt, const uint16_t salt_len); +void storage_init(PIN_UI_WAIT_CALLBACK callback, const uint8_t *salt, + const uint16_t salt_len); void storage_wipe(void); secbool storage_is_unlocked(void); void storage_lock(void); @@ -35,7 +37,8 @@ secbool storage_has_pin(void); secbool storage_pin_fails_increase(void); uint32_t storage_get_pin_rem(void); secbool storage_change_pin(const uint32_t oldpin, const uint32_t newpin); -secbool storage_get(const uint16_t key, void *val, const uint16_t max_len, uint16_t *len); +secbool storage_get(const uint16_t key, void *val, const uint16_t max_len, + uint16_t *len); secbool storage_set(const uint16_t key, const void *val, uint16_t len); secbool storage_delete(const uint16_t key); secbool storage_set_counter(const uint16_t key, const uint32_t count); diff --git a/core/tools/clang-format-check b/tools/clang-format-check similarity index 100% rename from core/tools/clang-format-check rename to tools/clang-format-check diff --git a/core/help.awk b/tools/help.awk similarity index 100% rename from core/help.awk rename to tools/help.awk diff --git a/tools/style.c.exclude b/tools/style.c.exclude new file mode 100644 index 000000000..e67f656a2 --- /dev/null +++ b/tools/style.c.exclude @@ -0,0 +1,15 @@ +^\./core/embed/bootloader/protob/ +^\./crypto/aes/ +^\./crypto/chacha20poly1305/ +^\./crypto/ed25519-donna/ +^\./crypto/gui/ +^\./crypto/monero/base58 +^\./crypto/monero/int-util +^\./crypto/blake2 +^\./crypto/check_mem +^\./crypto/groestl +^\./crypto/ripemd160 +^\./crypto/segwit_addr +^\./crypto/sha2 +^\./crypto/sha3 +^\./legacy/vendor diff --git a/tools/style.c.include b/tools/style.c.include new file mode 100644 index 000000000..276419c79 --- /dev/null +++ b/tools/style.c.include @@ -0,0 +1,5 @@ +^\./common/ +^\./core/embed/ +^\./crypto/ +^\./legacy/ +^\./storage/ diff --git a/tools/style.py.exclude b/tools/style.py.exclude new file mode 100644 index 000000000..fa02c7629 --- /dev/null +++ b/tools/style.py.exclude @@ -0,0 +1,2 @@ +^\./legacy/firmware/protob/messages_pb2\.py +^\./legacy/vendor diff --git a/tools/style.py.include b/tools/style.py.include new file mode 100644 index 000000000..0e2706842 --- /dev/null +++ b/tools/style.py.include @@ -0,0 +1,4 @@ +^\./common/ +^\./core/src/ +^\./crypto/ +^\./legacy/