core+legacy: rework code styling checks

pull/89/head
Pavol Rusnak 5 years ago
parent 9f8ebcf183
commit 8b06598474
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

1
.gitmodules vendored

@ -23,6 +23,7 @@
[submodule "legacy/vendor/nanopb"] [submodule "legacy/vendor/nanopb"]
path = legacy/vendor/nanopb path = legacy/vendor/nanopb
url = https://github.com/nanopb/nanopb.git url = https://github.com/nanopb/nanopb.git
ignore = untracked
[submodule "legacy/vendor/QR-Code-generator"] [submodule "legacy/vendor/QR-Code-generator"]
path = legacy/vendor/QR-Code-generator path = legacy/vendor/QR-Code-generator
url = https://github.com/nayuki/QR-Code-generator.git url = https://github.com/nayuki/QR-Code-generator.git

@ -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 )

@ -1,13 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import json
import sys import sys
from glob import glob from glob import glob
import json
from hashlib import sha256 from hashlib import sha256
try: try:
opt = sys.argv[1] opt = sys.argv[1]
except: except IndexError:
print("Usage: gen.py [core|mcu|check])") print("Usage: gen.py [core|mcu|check])")
sys.exit(1) sys.exit(1)
@ -22,12 +21,12 @@ def gen_core(data):
for d in data: for d in data:
if "u2f" in d: if "u2f" in d:
url, label = d["u2f"], d["label"] url, label = d["u2f"], d["label"]
print(" \"%s\": \"%s\"," % (url, label)) print(' "%s": "%s",' % (url, label))
print(" # WebAuthn") print(" # WebAuthn")
for d in data: for d in data:
if "webauthn" in d: if "webauthn" in d:
origin, label = d["webauthn"], d["label"] origin, label = d["webauthn"], d["label"]
print(" \"%s\": \"%s\"," % (origin, label)) print(' "%s": "%s",' % (origin, label))
print("}") print("}")
@ -36,12 +35,17 @@ def gen_mcu(data):
if "u2f" in d: if "u2f" in d:
url, label = d["u2f"], d["label"] url, label = d["u2f"], d["label"]
h = sha256(url.encode()).digest() 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: if "webauthn" in d:
origin, label = d["webauthn"], d["label"] origin, label = d["webauthn"], d["label"]
h = sha256(origin.encode()).digest() 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 = [] data = []

@ -1,3 +1,4 @@
// clang-format off
// TREZORv1 production public keys // 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\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", "\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",

@ -1,2 +1,3 @@
// clang-format off
// sample public key "correct horse battery staple" // 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" "\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"

@ -1,8 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from glob import glob
import os import os
import re import re
import sys import sys
from glob import glob
error = False error = False
@ -21,7 +21,9 @@ for fn in sorted(glob(os.path.join(MYDIR, "messages-*.proto"))):
line = line.strip().split(" ") line = line.strip().split(" ")
if line[0] not in ["enum", "message"]: if line[0] not in ["enum", "message"]:
continue 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]) print("ERROR:", fn, line[1])
error = True error = True

@ -1,10 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from collections import defaultdict, OrderedDict
import re
import os
import json
import glob import glob
import json
import logging import logging
import os
import re
from collections import OrderedDict, defaultdict
try: try:
import requests import requests

@ -3,38 +3,38 @@ from trezorlib import protobuf as p
class CoinDef(p.MessageType): class CoinDef(p.MessageType):
FIELDS = { FIELDS = {
1: ('coin_name', p.UnicodeType, 0), 1: ("coin_name", p.UnicodeType, 0),
2: ('coin_shortcut', p.UnicodeType, 0), 2: ("coin_shortcut", p.UnicodeType, 0),
3: ('coin_label', p.UnicodeType, 0), 3: ("coin_label", p.UnicodeType, 0),
4: ('curve_name', p.UnicodeType, 0), 4: ("curve_name", p.UnicodeType, 0),
5: ('address_type', p.UVarintType, 0), 5: ("address_type", p.UVarintType, 0),
6: ('address_type_p2sh', p.UVarintType, 0), 6: ("address_type_p2sh", p.UVarintType, 0),
7: ('maxfee_kb', p.UVarintType, 0), 7: ("maxfee_kb", p.UVarintType, 0),
8: ('minfee_kb', p.UVarintType, 0), 8: ("minfee_kb", p.UVarintType, 0),
9: ('signed_message_header', p.BytesType, 0), 9: ("signed_message_header", p.BytesType, 0),
10: ('hash_genesis_block', p.BytesType, 0), 10: ("hash_genesis_block", p.BytesType, 0),
11: ('xprv_magic', p.UVarintType, 0), 11: ("xprv_magic", p.UVarintType, 0),
12: ('xpub_magic', p.UVarintType, 0), 12: ("xpub_magic", p.UVarintType, 0),
13: ('xpub_magic_segwit_p2sh', p.UVarintType, 0), 13: ("xpub_magic_segwit_p2sh", p.UVarintType, 0),
14: ('xpub_magic_segwit_native', p.UVarintType, 0), 14: ("xpub_magic_segwit_native", p.UVarintType, 0),
15: ('bech32_prefix', p.UnicodeType, 0), 15: ("bech32_prefix", p.UnicodeType, 0),
16: ('cashaddr_prefix', p.UnicodeType, 0), 16: ("cashaddr_prefix", p.UnicodeType, 0),
17: ('slip44', p.UVarintType, 0), 17: ("slip44", p.UVarintType, 0),
18: ('segwit', p.BoolType, 0), 18: ("segwit", p.BoolType, 0),
19: ('decred', p.BoolType, 0), 19: ("decred", p.BoolType, 0),
20: ('fork_id', p.UVarintType, 0), 20: ("fork_id", p.UVarintType, 0),
21: ('force_bip143', p.BoolType, 0), 21: ("force_bip143", p.BoolType, 0),
22: ('dust_limit', p.UVarintType, 0), 22: ("dust_limit", p.UVarintType, 0),
23: ('uri_prefix', p.UnicodeType, 0), 23: ("uri_prefix", p.UnicodeType, 0),
24: ('min_address_length', p.UVarintType, 0), 24: ("min_address_length", p.UVarintType, 0),
25: ('max_address_length', p.UVarintType, 0), 25: ("max_address_length", p.UVarintType, 0),
26: ('icon', p.BytesType, 0), 26: ("icon", p.BytesType, 0),
28: ('website', p.UnicodeType, 0), 28: ("website", p.UnicodeType, 0),
29: ('github', p.UnicodeType, 0), 29: ("github", p.UnicodeType, 0),
30: ('maintainer', p.UnicodeType, 0), 30: ("maintainer", p.UnicodeType, 0),
31: ('blocktime_seconds', p.UVarintType, 0), 31: ("blocktime_seconds", p.UVarintType, 0),
32: ('bip115', p.BoolType, 0), 32: ("bip115", p.BoolType, 0),
33: ('cooldown', p.UVarintType, 0), 33: ("cooldown", p.UVarintType, 0),
} }
def __init__( def __init__(
@ -73,7 +73,7 @@ class CoinDef(p.MessageType):
default_fee_b: dict = None, default_fee_b: dict = None,
bitcore: dict = None, bitcore: dict = None,
blockbook: dict = None, blockbook: dict = None,
cooldown: int = None cooldown: int = None,
): ):
self.coin_name = coin_name self.coin_name = coin_name
self.coin_shortcut = coin_shortcut self.coin_shortcut = coin_shortcut

@ -1,14 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Fetch information about coins and tokens supported by Trezor and update it in coins_details.json.""" """Fetch information about coins and tokens supported by Trezor and update it in coins_details.json."""
import os
import time
import json import json
import logging import logging
import requests import os
import sys import sys
import coin_info import time
import click import click
import requests
import coin_info
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -149,7 +150,7 @@ def summary(coins, api_key):
try: try:
ret = coinmarketcap_call("global-metrics/quotes/latest", api_key) ret = coinmarketcap_call("global-metrics/quotes/latest", api_key)
total_marketcap = int(ret["data"]["quote"]["USD"]["total_market_cap"]) total_marketcap = int(ret["data"]["quote"]["USD"]["total_market_cap"])
except: except Exception:
pass pass
return dict( return dict(

@ -1,13 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import fnmatch import fnmatch
import glob
import io import io
import json import json
import logging import logging
import re
import sys
import os import os
import glob import re
import struct import struct
import sys
import zlib import zlib
from collections import defaultdict from collections import defaultdict
from hashlib import sha256 from hashlib import sha256
@ -524,8 +524,7 @@ def cli(colors):
# fmt: off # fmt: off
@click.option("--backend/--no-backend", "-b", default=False, help="Check blockbook/bitcore responses") @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("--icons/--no-icons", default=True, help="Check icon files")
@click.option("-d", "--show-duplicates", type=click.Choice(("all", "nontoken", "errors")), @click.option("-d", "--show-duplicates", type=click.Choice(("all", "nontoken", "errors")), default="errors", help="How much information about duplicate shortcuts should be shown.")
default="errors", help="How much information about duplicate shortcuts should be shown.")
# fmt: on # fmt: on
def check(backend, icons, show_duplicates): def check(backend, icons, show_duplicates):
"""Validate coin definitions. """Validate coin definitions.

@ -1,13 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import click
import json import json
import os import os
import requests
import tempfile
import subprocess import subprocess
import sys import tempfile
import click
import requests
LIVE_URL = "https://trezor.io/static/json/coins_details.json" LIVE_URL = "https://trezor.io/static/json/coins_details.json"
COINS_DETAILS = os.path.join( COINS_DETAILS = os.path.join(

@ -1,11 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import re import json
import os import os
import re
import subprocess import subprocess
import sys import sys
import click import click
import coin_info import coin_info
import json
SUPPORT_INFO = coin_info.get_support_data() SUPPORT_INFO = coin_info.get_support_data()

@ -39,7 +39,7 @@ CFLAGS += -DGITREV=$(GITREV)
## help commands: ## help commands:
help: ## show this help help: ## show this help
@awk -f help.awk $(MAKEFILE_LIST) @awk -f ../tools/help.awk $(MAKEFILE_LIST)
## dependencies commands: ## 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: ## run pylint on application sources and tests
pylint -E $(shell find src tests -name *.py) 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: ## code generation:
templates: ## render Mako templates (for lists of coins, tokens, etc.) templates: ## render Mako templates (for lists of coins, tokens, etc.)

@ -241,6 +241,4 @@ void display_refresh(void) {
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD
} }
const char *display_save(const char *prefix) { const char *display_save(const char *prefix) { return NULL; }
return NULL;
}

@ -498,6 +498,4 @@ void display_refresh(void) {
} }
} }
const char *display_save(const char *prefix) { const char *display_save(const char *prefix) { return NULL; }
return NULL;
}

@ -1,3 +1,5 @@
// clang-format off
/* /*
* This file is part of the MicroPython project, http://micropython.org/ * This file is part of the MicroPython project, http://micropython.org/
* *

@ -31,6 +31,6 @@ def get_type(wire_type):
for msg_name in dir(MessageType): for msg_name in dir(MessageType):
# Modules contain internal variables that may cause exception here. # Modules contain internal variables that may cause exception here.
# No Message begins with underscore so it's safe to skip those. # No Message begins with underscore so it's safe to skip those.
if (msg_name[0] == '_'): if msg_name[0] == "_":
continue continue
type_to_name[getattr(MessageType, msg_name)] = msg_name type_to_name[getattr(MessageType, msg_name)] = msg_name

@ -1,2 +0,0 @@
---
BasedOnStyle: Google

@ -5,82 +5,80 @@ START_TEST(test_ed25519_cardano_sign_vectors) {
ed25519_secret_key secret_key_extension; ed25519_secret_key secret_key_extension;
ed25519_signature signature; ed25519_signature signature;
static const char static const char *vectors[] = {
*vectors[] = "6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5"
{ "3", // private key
"6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5" "60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8"
"3", // private key "e", // private key extension
"60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8" "64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe"
"e", // private key extension "1", // public key
"64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe" "45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7"
"1", // public key "9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10"
"45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7" "d", // signature
"9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10"
"d", // signature "e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830"
"c", // private key
"e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830" "794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a"
"c", // private key "4", // private key extension
"794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a" "95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d"
"4", // private key extension "f", // public key
"95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d" "f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1"
"f", // public key "9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560"
"f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1" "f", // signature
"9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560"
"f", // signature "9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0"
"c", // private key
"9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0" "b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb"
"c", // private key "b", // private key extension
"b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb" "79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19"
"b", // private key extension "f", // public key
"79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19" "2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a"
"f", // public key "88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800"
"2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a" "f", // signature
"88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800"
"f", // signature "52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40"
"c", // private key
"52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40" "6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580"
"c", // private key "3", // private key extension
"6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580" "dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d"
"3", // private key extension "6", // public key
"dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d" "0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6"
"6", // public key "2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160"
"0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6" "2", // signature
"2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160"
"2", // signature "11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0"
"4", // private key
"11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0" "c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235"
"4", // private key "2", // private key extension
"c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235" "839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7"
"2", // private key extension "8", // public key
"839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7" "e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f"
"8", // public key "9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490"
"e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f" "5", // signature
"9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490"
"5", // signature "5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50"
"5", // private key
"5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50" "ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c"
"5", // private key "d", // private key extension
"ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c" "75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7"
"d", // private key extension "6", // public key
"75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7" "631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb"
"6", // public key "c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890"
"631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb" "6", // signature
"c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890"
"6", // signature "624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50"
"d", // private key
"624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50" "097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0"
"d", // private key "2", // private key extension
"097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0" "0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0"
"2", // private key extension "0", // public key
"0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0" "1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a"
"0", // public key "57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90"
"1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a" "1", // signature
"57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90"
"1", // signature 0,
0,
0, };
0,
};
const char **test_data; const char **test_data;
test_data = vectors; test_data = vectors;

@ -5,10 +5,11 @@ import hashlib
import os import os
import random import random
import curve25519
import ecdsa import ecdsa
import pytest import pytest
import curve25519
def bytes2num(s): def bytes2num(s):
res = 0 res = 0
@ -30,48 +31,48 @@ class Point:
points = [ points = [
Point( Point(
"secp256k1", "secp256k1",
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8,
), ),
Point( Point(
"secp256k1", "secp256k1",
0x1, 0x1,
0x4218f20ae6c646b363db68605822fb14264ca8d2587fdd6fbc750d587e76a7ee, 0x4218F20AE6C646B363DB68605822FB14264CA8D2587FDD6FBC750D587E76A7EE,
), ),
Point( Point(
"secp256k1", "secp256k1",
0x2, 0x2,
0x66fbe727b2ba09e09f5a98d70a5efce8424c5fa425bbda1c511f860657b8535e, 0x66FBE727B2BA09E09F5A98D70A5EFCE8424C5FA425BBDA1C511F860657B8535E,
), ),
Point( Point(
"secp256k1", "secp256k1",
0x1b, 0x1B,
0x1adcea1cf831b0ad1653e769d1a229091d0cc68d4b0328691b9caacc76e37c90, 0x1ADCEA1CF831B0AD1653E769D1A229091D0CC68D4B0328691B9CAACC76E37C90,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296,
0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x0, 0x0,
0x66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4, 0x66485C780E2F83D72433BD5D84A06BB6541C2AF31DAE871728BF856A174F93F4,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x0, 0x0,
0x99b7a386f1d07c29dbcc42a27b5f9449abe3d50de25178e8d7407a95e8b06c0b, 0x99B7A386F1D07C29DBCC42A27B5F9449ABE3D50DE25178E8D7407A95E8B06C0B,
), ),
Point( Point(
"nist256p1", "nist256p1",
0xaf8bbdfe8cdd5577acbf345b543d28cf402f4e94d3865b97ea0787f2d3aa5d22, 0xAF8BBDFE8CDD5577ACBF345B543D28CF402F4E94D3865B97EA0787F2D3AA5D22,
0x35802b8b376b995265918b078bc109c21a535176585c40f519aca52d6afc147c, 0x35802B8B376B995265918B078BC109C21A535176585C40F519ACA52D6AFC147C,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x80000, 0x80000,
0x580610071f440f0dcc14a22e2d5d5afc1224c0cd11a3b4b51b8ecd2224ee1ce2, 0x580610071F440F0DCC14A22E2D5D5AFC1224C0CD11A3B4B51B8ECD2224EE1CE2,
), ),
] ]

@ -102,7 +102,7 @@ def is_valid_der(data):
try: try:
structure, _ = der_decode(data) structure, _ = der_decode(data)
return data == der_encode(structure) return data == der_encode(structure)
except: except Exception:
return False return False
@ -140,7 +140,7 @@ def parse_ec_pubkey(public_key):
try: try:
public_key = bytes(public_key["public_key"].asOctets()) public_key = bytes(public_key["public_key"].asOctets())
except: except Exception:
raise ParseError("Not a BER encoded named elliptic curve public key") raise ParseError("Not a BER encoded named elliptic curve public key")
return curve_name, public_key return curve_name, public_key
@ -152,13 +152,13 @@ def parse_ecdsa256_signature(signature):
raise ParseError("Not a valid DER") raise ParseError("Not a valid DER")
try: try:
signature, _ = der_decode(signature, asn1Spec=EcSignature()) signature, _ = der_decode(signature, asn1Spec=EcSignature())
except: except Exception:
raise ParseError("Not a valid DER encoded ECDSA signature") raise ParseError("Not a valid DER encoded ECDSA signature")
try: try:
r = int(signature["r"]).to_bytes(32, byteorder="big") r = int(signature["r"]).to_bytes(32, byteorder="big")
s = int(signature["s"]).to_bytes(32, byteorder="big") s = int(signature["s"]).to_bytes(32, byteorder="big")
signature = r + s signature = r + s
except: except Exception:
raise ParseError("Not a valid DER encoded 256 bit ECDSA signature") raise ParseError("Not a valid DER encoded 256 bit ECDSA signature")
return signature return signature
@ -281,7 +281,7 @@ def aes_cbc_decrypt(key, iv, ciphertext):
def load_json_testvectors(filename): def load_json_testvectors(filename):
try: try:
result = json.loads(open(os.path.join(testvectors_directory, filename)).read()) result = json.loads(open(os.path.join(testvectors_directory, filename)).read())
except: except Exception:
raise DataError() raise DataError()
return result return result
@ -310,7 +310,7 @@ def generate_aes(filename):
plaintext = unhexlify(test["msg"]) plaintext = unhexlify(test["msg"])
ciphertext = unhexlify(test["ct"]) ciphertext = unhexlify(test["ct"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if len(key) not in [128 / 8, 192 / 8, 256 / 8]: if len(key) not in [128 / 8, 192 / 8, 256 / 8]:
@ -359,7 +359,7 @@ def generate_chacha_poly(filename):
ciphertext = unhexlify(test["ct"]) ciphertext = unhexlify(test["ct"])
tag = unhexlify(test["tag"]) tag = unhexlify(test["tag"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if result is None: if result is None:
@ -406,7 +406,7 @@ def generate_curve25519_dh(filename):
private_key = unhexlify(test["private"]) private_key = unhexlify(test["private"])
shared = unhexlify(test["shared"]) shared = unhexlify(test["shared"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if curve_name != "curve25519": if curve_name != "curve25519":
@ -448,7 +448,7 @@ def generate_ecdh(filename):
private_key = parse_signed_hex(test["private"]) private_key = parse_signed_hex(test["private"])
shared = unhexlify(test["shared"]) shared = unhexlify(test["shared"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
try: try:
@ -498,7 +498,7 @@ def generate_ecdsa(filename):
try: try:
public_key = unhexlify(test_group["keyDer"]) public_key = unhexlify(test_group["keyDer"])
except: except Exception:
raise DataError() raise DataError()
try: try:
@ -521,7 +521,7 @@ def generate_ecdsa(filename):
signature = unhexlify(test["sig"]) signature = unhexlify(test["sig"])
message = unhexlify(test["msg"]) message = unhexlify(test["msg"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if result is None: if result is None:
@ -563,7 +563,7 @@ def generate_eddsa(filename):
try: try:
public_key = unhexlify(test_group["keyDer"]) public_key = unhexlify(test_group["keyDer"])
except: except Exception:
raise DataError() raise DataError()
try: try:
@ -579,7 +579,7 @@ def generate_eddsa(filename):
signature = unhexlify(test["sig"]) signature = unhexlify(test["sig"])
message = unhexlify(test["msg"]) message = unhexlify(test["msg"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if result is None: if result is None:

@ -1,2 +0,0 @@
---
BasedOnStyle: Google

@ -1,12 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
from __future__ import print_function from __future__ import print_function
bl = open('bl.bin').read() bl = open("bl.bin").read()
fw = open('fw.bin').read() fw = open("fw.bin").read()
combined = bl + fw[:256] + (32768-256)*'\x00' + fw[256:] 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("bootloader : %d bytes" % len(bl))
print('firmware : %d bytes' % len(fw)) print("firmware : %d bytes" % len(fw))
print('combined : %d bytes' % len(combined)) print("combined : %d bytes" % len(combined))

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys
import os import os
import sys
TOTALSIZE = 32768 TOTALSIZE = 32768
MAXSIZE = TOTALSIZE - 32 MAXSIZE = TOTALSIZE - 32
@ -8,7 +8,10 @@ MAXSIZE = TOTALSIZE - 32
fn = sys.argv[1] fn = sys.argv[1]
fs = os.stat(fn).st_size fs = os.stat(fn).st_size
if fs > MAXSIZE: if fs > MAXSIZE:
raise Exception('bootloader has to be smaller than %d bytes (current size is %d)' % (MAXSIZE, fs)) raise Exception(
with open(fn, 'ab') as f: "bootloader has to be smaller than %d bytes (current size is %d)"
f.write(b'\x00' * (TOTALSIZE - fs)) % (MAXSIZE, fs)
f.close() )
with open(fn, "ab") as f:
f.write(b"\x00" * (TOTALSIZE - fs))
f.close()

@ -7,7 +7,6 @@ import struct
import ecdsa import ecdsa
SLOTS = 3 SLOTS = 3
pubkeys = { pubkeys = {
@ -94,7 +93,7 @@ def update_hashes_in_header(data):
data = bytearray(data) data = bytearray(data)
o = 0 o = 0
for h in prepare_hashes(data[FWHEADER_SIZE:]): for h in prepare_hashes(data[FWHEADER_SIZE:]):
data[0x20 + o:0x20 + o + 32] = h data[0x20 + o : 0x20 + o + 32] = h
o += 32 o += 32
return bytes(data) return bytes(data)
@ -112,6 +111,7 @@ def check_size(data):
size = struct.unpack("<L", data[12:16])[0] size = struct.unpack("<L", data[12:16])[0]
assert size == len(data) - 1024 assert size == len(data) - 1024
def check_signatures(data): def check_signatures(data):
# Analyses given firmware and prints out # Analyses given firmware and prints out
# status of included signatures # status of included signatures
@ -146,7 +146,7 @@ def check_signatures(data):
used.append(indexes[x]) used.append(indexes[x])
print("Slot #%d signature: VALID" % (x + 1), signature.hex()) print("Slot #%d signature: VALID" % (x + 1), signature.hex())
except: except Exception:
print("Slot #%d signature: INVALID" % (x + 1), signature.hex()) print("Slot #%d signature: INVALID" % (x + 1), signature.hex())
@ -202,7 +202,7 @@ def sign(data, is_pem):
index = i index = i
break break
if index == None: if index is None:
raise Exception("Unable to find private key index. Unknown private key?") raise Exception("Unable to find private key index. Unknown private key?")
signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256) signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256)

@ -2,29 +2,37 @@
import hashlib import hashlib
import os import os
import subprocess import subprocess
import ecdsa
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
print('master secret:', end='') import ecdsa
print("master secret:", end="")
h = input() h = input()
if h: if h:
h = unhexlify(h).encode('ascii') h = unhexlify(h).encode("ascii")
else: else:
h = hashlib.sha256(os.urandom(1024)).digest() h = hashlib.sha256(os.urandom(1024)).digest()
print() print()
print('master secret:', hexlify(h)) print("master secret:", hexlify(h))
print() print()
for i in range(1, 6): for i in range(1, 6):
se = hashlib.sha256(h + chr(i).encode('ascii')).hexdigest() se = hashlib.sha256(h + chr(i).encode("ascii")).hexdigest()
print('seckey', i, ':', se) print("seckey", i, ":", se)
sk = ecdsa.SigningKey.from_secret_exponent(secexp = int(se, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256) sk = ecdsa.SigningKey.from_secret_exponent(
print('pubkey', i, ':', (b'04' + hexlify(sk.get_verifying_key().to_string())).decode('ascii')) secexp=int(se, 16), curve=ecdsa.curves.SECP256k1, hashfunc=hashlib.sha256
print(sk.to_pem().decode('ascii')) )
print(
"pubkey",
i,
":",
(b"04" + hexlify(sk.get_verifying_key().to_string())).decode("ascii"),
)
print(sk.to_pem().decode("ascii"))
p = subprocess.Popen('ssss-split -t 3 -n 5 -x'.split(' '), stdin = subprocess.PIPE) p = subprocess.Popen("ssss-split -t 3 -n 5 -x".split(" "), stdin=subprocess.PIPE)
p.communicate(input = hexlify(h) + '\n') p.communicate(input=hexlify(h) + "\n")
# to recover use: # to recover use:
# $ ssss-combine -t 3 -x # $ ssss-combine -t 3 -x

@ -1,19 +1,19 @@
#!/usr/bin/env python #!/usr/bin/env python
from hashlib import sha256 from hashlib import sha256
fn = '../bootloader/bootloader.bin' fn = "../bootloader/bootloader.bin"
data = open(fn, 'rb').read() data = open(fn, "rb").read()
if len(data) > 32768: if len(data) > 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() h = sha256(sha256(data).digest()).digest()
bl_hash = ', '.join('0x%02x' % x for x in bytearray(h)) bl_hash = ", ".join("0x%02x" % x for x in bytearray(h))
bl_data = ', '.join('0x%02x' % x for x in bytearray(data)) bl_data = ", ".join("0x%02x" % x for x in bytearray(data))
with open('bl_data.h', 'wt') as f: 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_hash[32] = {%s};\n" % bl_hash)
f.write('static const uint8_t bl_data[32768] = {%s};\n' % bl_data) f.write("static const uint8_t bl_data[32768] = {%s};\n" % bl_data)

@ -256,12 +256,12 @@ void fsm_msgEntropyAck(const EntropyAck *msg) {
} }
void fsm_msgBackupDevice(const BackupDevice *msg) { void fsm_msgBackupDevice(const BackupDevice *msg) {
(void)msg;
CHECK_INITIALIZED CHECK_INITIALIZED
CHECK_PIN_UNCACHED CHECK_PIN_UNCACHED
(void)
msg;
char mnemonic[MAX_MNEMONIC_LEN + 1]; char mnemonic[MAX_MNEMONIC_LEN + 1];
if (config_getMnemonic(mnemonic, sizeof(mnemonic))) { if (config_getMnemonic(mnemonic, sizeof(mnemonic))) {
reset_backup(true, mnemonic); reset_backup(true, mnemonic);

@ -1,11 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys import sys
from collections import defaultdict from collections import defaultdict
from messages_pb2 import MessageType
from messages_pb2 import wire_in, wire_out from messages_pb2 import (
from messages_pb2 import wire_debug_in, wire_debug_out MessageType,
from messages_pb2 import wire_bootloader, wire_no_fsm wire_bootloader,
wire_debug_in,
wire_debug_out,
wire_in,
wire_no_fsm,
wire_out,
)
fh = open("messages_map.h", "wt") fh = open("messages_map.h", "wt")
fl = open("messages_map_limits.h", "wt") fl = open("messages_map_limits.h", "wt")
@ -24,7 +29,7 @@ LABELS = {
def handle_message(fh, fl, skipped, message, extension): def handle_message(fh, fl, skipped, message, extension):
name = message.name name = message.name
short_name = name.split("MessageType_", 1).pop() short_name = name.split("MessageType_", 1).pop()
assert(short_name != name) assert short_name != name
for s in skipped: for s in skipped:
if short_name.startswith(s): if short_name.startswith(s):
@ -37,14 +42,14 @@ def handle_message(fh, fl, skipped, message, extension):
bootloader = options.Extensions[wire_bootloader] bootloader = options.Extensions[wire_bootloader]
no_fsm = options.Extensions[wire_no_fsm] no_fsm = options.Extensions[wire_no_fsm]
if getattr(options, 'deprecated', None): if getattr(options, "deprecated", None):
fh.write('\t// Message %s is deprecated\n' % short_name) fh.write("\t// Message %s is deprecated\n" % short_name)
return return
if bootloader: 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 return
if no_fsm: 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 return
if direction == "i": if direction == "i":
@ -52,13 +57,15 @@ def handle_message(fh, fl, skipped, message, extension):
else: else:
process_func = "0" process_func = "0"
fh.write(TEMPLATE.format( fh.write(
type="'%c'," % interface, TEMPLATE.format(
dir="'%c'," % direction, type="'%c'," % interface,
msg_id="MessageType_%s," % name, dir="'%c'," % direction,
fields="%s_fields," % short_name, msg_id="MessageType_%s," % name,
process_func=process_func, fields="%s_fields," % short_name,
)) process_func=process_func,
)
)
bufsize = None bufsize = None
t = interface + direction t = interface + direction
@ -69,13 +76,20 @@ def handle_message(fh, fl, skipped, message, extension):
elif t == "do": elif t == "do":
bufsize = "MSG_DEBUG_OUT_SIZE" bufsize = "MSG_DEBUG_OUT_SIZE"
if bufsize: 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:] skipped = sys.argv[1:]
fh.write("\t// This file is automatically generated by messages_map.py -- DO NOT EDIT!\n") fh.write(
fl.write("// This file is automatically generated by messages_map.py -- DO NOT EDIT!\n\n") "\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) messages = defaultdict(list)

@ -1,3 +1,4 @@
// clang-format off
/** /**
* Copyright FIDO Alliance, 2017 * Copyright FIDO Alliance, 2017
* *

@ -1,3 +1,4 @@
// clang-format off
/** /**
* Copyright FIDO Alliance, 2017 * Copyright FIDO Alliance, 2017
* *

@ -1,3 +1,4 @@
// clang-format off
#include "bitmaps.h" #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, }; 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, };

@ -4,8 +4,8 @@
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {
uint8_t width, height; uint8_t width, height;
const uint8_t *data; const uint8_t *data;
} BITMAP; } BITMAP;
extern const BITMAP bmp_digit0; extern const BITMAP bmp_digit0;

@ -1,58 +1,64 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import glob import glob
import os import os
from PIL import Image from PIL import Image
hdrs = [] hdrs = []
data = [] data = []
imgs = [] imgs = []
def encode_pixels(img): def encode_pixels(img):
r = '' r = ""
img = [ (x[0] + x[1] + x[2] > 384 and '1' or '0') for x in img] img = [(x[0] + x[1] + x[2] > 384 and "1" or "0") for x in img]
for i in range(len(img) // 8): for i in range(len(img) // 8):
c = ''.join(img[i * 8 : i * 8 + 8]) c = "".join(img[i * 8 : i * 8 + 8])
r += '0x%02x, ' % int(c, 2) r += "0x%02x, " % int(c, 2)
return r return r
cnt = 0 cnt = 0
for fn in sorted(glob.glob('*.png')): for fn in sorted(glob.glob("*.png")):
print('Processing:', fn) print("Processing:", fn)
im = Image.open(fn) im = Image.open(fn)
name = os.path.splitext(fn)[0] name = os.path.splitext(fn)[0]
w, h = im.size w, h = im.size
if w % 8 != 0: if w % 8 != 0:
raise Exception('Width must be divisable by 8! (%s is %dx%d)' % (fn, w, h)) raise Exception("Width must be divisable by 8! (%s is %dx%d)" % (fn, w, h))
img = list(im.getdata()) img = list(im.getdata())
hdrs.append('extern const BITMAP bmp_%s;\n' % name) 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)) 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))) data.append("const uint8_t bmp_%s_data[] = { %s};\n" % (name, encode_pixels(img)))
cnt += 1 cnt += 1
with open('../bitmaps.c', 'wt') as f: with open("../bitmaps.c", "wt") as f:
f.write('#include "bitmaps.h"\n\n') f.write("// clang-format off\n")
for i in range(cnt): f.write('#include "bitmaps.h"\n\n')
f.write(data[i]) for i in range(cnt):
f.write('\n') f.write(data[i])
for i in range(cnt): f.write("\n")
f.write(imgs[i]) for i in range(cnt):
f.close() f.write(imgs[i])
f.close()
with open('../bitmaps.h', 'wt') as f:
f.write('''#ifndef __BITMAPS_H__ with open("../bitmaps.h", "wt") as f:
f.write(
"""#ifndef __BITMAPS_H__
#define __BITMAPS_H__ #define __BITMAPS_H__
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {
uint8_t width, height; uint8_t width, height;
const uint8_t *data; const uint8_t *data;
} BITMAP; } BITMAP;
''') """
)
for i in range(cnt): for i in range(cnt):
f.write(hdrs[i]) f.write(hdrs[i])
f.write('\n#endif\n') f.write("\n#endif\n")
f.close() f.close()

@ -1,18 +1,16 @@
#include "fonts.h" #include "fonts.h"
const uint8_t * const font_data[2][128] = { const uint8_t *const font_data[2][128] = {
{ {
#include"font.inc" #include "font.inc"
}, },
{ {
#include"fontfixed.inc" #include "fontfixed.inc"
}, },
}; };
int fontCharWidth(int font, char c) { int fontCharWidth(int font, char c) { return font_data[font][c & 0x7f][0]; }
return font_data[font][c & 0x7f][0];
}
const uint8_t *fontCharData(int font, char c) { const uint8_t *fontCharData(int font, char c) {
return font_data[font][c & 0x7f] + 1; return font_data[font][c & 0x7f] + 1;
} }

@ -5,10 +5,10 @@
#define FONT_HEIGHT 8 #define FONT_HEIGHT 8
#define FONT_STANDARD 0 #define FONT_STANDARD 0
#define FONT_FIXED 1 #define FONT_FIXED 1
#define FONT_DOUBLE 0x80 #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); int fontCharWidth(int font, char c);
const uint8_t *fontCharData(int font, char c); const uint8_t *fontCharData(int font, char c);

@ -1,39 +1,40 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from PIL import Image from PIL import Image
class Img(object):
class Img(object):
def __init__(self, fn): def __init__(self, fn):
im = Image.open(fn) im = Image.open(fn)
self.w, self.h = im.size self.w, self.h = im.size
self.data = list(im.getdata()) self.data = list(im.getdata())
def pixel(self, r, c): def pixel(self, r, c):
p = self.data[ r + c * self.w ] p = self.data[r + c * self.w]
if p == (255, 255, 255): if p == (255, 255, 255):
return '0' return "0"
if p == (0, 0, 0): if p == (0, 0, 0):
return '1' return "1"
if p == (255, 0, 255): if p == (255, 0, 255):
return None return None
raise Exception('Unknown color', p) raise Exception("Unknown color", p)
def convert(imgfile, outfile): def convert(imgfile, outfile):
img = Img(imgfile) img = Img(imgfile)
cur = '' cur = ""
with open(outfile, 'w') as f: with open(outfile, "w") as f:
for i in range(128): for i in range(128):
x = (i % 16) * 10 x = (i % 16) * 10
y = (i // 16) * 10 y = (i // 16) * 10
cur = '' cur = ""
while img.pixel(x, y) != None: while img.pixel(x, y) is not None:
val = ''.join(img.pixel(x, y + j) for j in range(8)) val = "".join(img.pixel(x, y + j) for j in range(8))
x += 1 x += 1
cur += '\\x%02x' % int(val, 2) cur += "\\x%02x" % int(val, 2)
cur = '\\x%02x' % (len(cur) // 4) + cur cur = "\\x%02x" % (len(cur) // 4) + cur
ch = chr(i) if i >= 32 and i <= 126 else '_' ch = chr(i) if i >= 32 and i <= 126 else "_"
f.write('\t/* 0x%02x %c */ (uint8_t *)"%s",\n' % (i, ch , cur)) f.write('\t/* 0x%02x %c */ (uint8_t *)"%s",\n' % (i, ch, cur))
convert('fonts/fontfixed.png', 'fontfixed.inc') convert("fonts/fontfixed.png", "fontfixed.inc")
convert('fonts/font.png', 'font.inc') convert("fonts/font.png", "font.inc")

@ -2,99 +2,102 @@
from __future__ import print_function from __future__ import print_function
handlers = [ handlers = [
'hard_fault_handler', "hard_fault_handler",
'mem_manage_handler', "mem_manage_handler",
'bus_fault_handler', "bus_fault_handler",
'usage_fault_handler', "usage_fault_handler",
'nvic_wwdg_isr', "nvic_wwdg_isr",
'pvd_isr', "pvd_isr",
'tamp_stamp_isr', "tamp_stamp_isr",
'rtc_wkup_isr', "rtc_wkup_isr",
'flash_isr', "flash_isr",
'rcc_isr', "rcc_isr",
'exti0_isr', "exti0_isr",
'exti1_isr', "exti1_isr",
'exti2_isr', "exti2_isr",
'exti3_isr', "exti3_isr",
'exti4_isr', "exti4_isr",
'dma1_stream0_isr', "dma1_stream0_isr",
'dma1_stream1_isr', "dma1_stream1_isr",
'dma1_stream2_isr', "dma1_stream2_isr",
'dma1_stream3_isr', "dma1_stream3_isr",
'dma1_stream4_isr', "dma1_stream4_isr",
'dma1_stream5_isr', "dma1_stream5_isr",
'dma1_stream6_isr', "dma1_stream6_isr",
'adc_isr', "adc_isr",
'can1_tx_isr', "can1_tx_isr",
'can1_rx0_isr', "can1_rx0_isr",
'can1_rx1_isr', "can1_rx1_isr",
'can1_sce_isr', "can1_sce_isr",
'exti9_5_isr', "exti9_5_isr",
'tim1_brk_tim9_isr', "tim1_brk_tim9_isr",
'tim1_up_tim10_isr', "tim1_up_tim10_isr",
'tim1_trg_com_tim11_isr', "tim1_trg_com_tim11_isr",
'tim1_cc_isr', "tim1_cc_isr",
'tim2_isr', "tim2_isr",
'tim3_isr', "tim3_isr",
'tim4_isr', "tim4_isr",
'i2c1_ev_isr', "i2c1_ev_isr",
'i2c1_er_isr', "i2c1_er_isr",
'i2c2_ev_isr', "i2c2_ev_isr",
'i2c2_er_isr', "i2c2_er_isr",
'spi1_isr', "spi1_isr",
'spi2_isr', "spi2_isr",
'usart1_isr', "usart1_isr",
'usart2_isr', "usart2_isr",
'usart3_isr', "usart3_isr",
'exti15_10_isr', "exti15_10_isr",
'rtc_alarm_isr', "rtc_alarm_isr",
'usb_fs_wkup_isr', "usb_fs_wkup_isr",
'tim8_brk_tim12_isr', "tim8_brk_tim12_isr",
'tim8_up_tim13_isr', "tim8_up_tim13_isr",
'tim8_trg_com_tim14_isr', "tim8_trg_com_tim14_isr",
'tim8_cc_isr', "tim8_cc_isr",
'dma1_stream7_isr', "dma1_stream7_isr",
'fsmc_isr', "fsmc_isr",
'sdio_isr', "sdio_isr",
'tim5_isr', "tim5_isr",
'spi3_isr', "spi3_isr",
'uart4_isr', "uart4_isr",
'uart5_isr', "uart5_isr",
'tim6_dac_isr', "tim6_dac_isr",
'tim7_isr', "tim7_isr",
'dma2_stream0_isr', "dma2_stream0_isr",
'dma2_stream1_isr', "dma2_stream1_isr",
'dma2_stream2_isr', "dma2_stream2_isr",
'dma2_stream3_isr', "dma2_stream3_isr",
'dma2_stream4_isr', "dma2_stream4_isr",
'eth_isr', "eth_isr",
'eth_wkup_isr', "eth_wkup_isr",
'can2_tx_isr', "can2_tx_isr",
'can2_rx0_isr', "can2_rx0_isr",
'can2_rx1_isr', "can2_rx1_isr",
'can2_sce_isr', "can2_sce_isr",
'otg_fs_isr', "otg_fs_isr",
'dma2_stream5_isr', "dma2_stream5_isr",
'dma2_stream6_isr', "dma2_stream6_isr",
'dma2_stream7_isr', "dma2_stream7_isr",
'usart6_isr', "usart6_isr",
'i2c3_ev_isr', "i2c3_ev_isr",
'i2c3_er_isr', "i2c3_er_isr",
'otg_hs_ep1_out_isr', "otg_hs_ep1_out_isr",
'otg_hs_ep1_in_isr', "otg_hs_ep1_in_isr",
'otg_hs_wkup_isr', "otg_hs_wkup_isr",
'otg_hs_isr', "otg_hs_isr",
'dcmi_isr', "dcmi_isr",
'cryp_isr', "cryp_isr",
'hash_rng_isr', "hash_rng_isr",
] ]
with open('handlers.c', 'wt') as f: with open("handlers.c", "wt") as f:
f.write('#include "layout.h"\n') f.write('#include "layout.h"\n')
f.write('#include "oled.h"\n\n') f.write('#include "oled.h"\n\n')
for i in handlers: for i in handlers:
f.write('void __attribute__((noreturn)) %s(void)\n' % i) f.write("void __attribute__((noreturn)) %s(void)\n" % i)
f.write('{\n') 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(
f.write('\tfor (;;) {} // loop forever\n') '\tlayoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Encountered", NULL, "%s", NULL, "Please restart", "the device.");\n'
f.write('}\n\n') % i.upper()
)
f.write("\tfor (;;) {} // loop forever\n")
f.write("}\n\n")

@ -1,35 +1,35 @@
#include <readline/history.h>
#include <readline/readline.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "fonts.h" #include "fonts.h"
static inline char convert(char c) { static inline char convert(char c) {
if (c < 0x80) { if (c < 0x80) {
return c; return c;
} else if (c >= 0xC0) { } else if (c >= 0xC0) {
return '_'; return '_';
} else { } else {
return '\0'; return '\0';
} }
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
char *line; char *line;
int font = FONT_STANDARD; int font = FONT_STANDARD;
while ((line = readline(NULL)) != NULL) { while ((line = readline(NULL)) != NULL) {
size_t length = strlen(line); size_t length = strlen(line);
if (length) { if (length) {
add_history(line); add_history(line);
} }
size_t width = 0; size_t width = 0;
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++) {
width += fontCharWidth(font, convert(line[i])) + 1; width += fontCharWidth(font, convert(line[i])) + 1;
} }
printf("%zu\n", width); printf("%zu\n", width);
free(line); free(line);
} }
} }

@ -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 =

@ -19,33 +19,35 @@
#include <string.h> #include <string.h>
#include "norcow.h"
#include "flash.h"
#include "common.h" #include "common.h"
#include "flash.h"
#include "norcow.h"
// NRC2 = 4e524332 // NRC2 = 4e524332
#define NORCOW_MAGIC ((uint32_t)0x3243524e) #define NORCOW_MAGIC ((uint32_t)0x3243524e)
// NRCW = 4e524357 // 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_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 #define NORCOW_VERSION_LEN NORCOW_WORD_SIZE
// The key value which is used to indicate that the entry is not set. // 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. // The key value which is used to indicate that the entry has been deleted.
#define NORCOW_KEY_DELETED (0x0000) #define NORCOW_KEY_DELETED (0x0000)
// The offset from the beginning of the sector where stored items start. // 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. // Map from sector index to sector number.
static const uint8_t norcow_sectors[NORCOW_SECTOR_COUNT] = NORCOW_SECTORS; 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_active_sector = 0;
static uint8_t norcow_write_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 * Returns pointer to sector, starting with offset
* Fails when there is not enough space for data of given size * 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) static const void *norcow_ptr(uint8_t sector, uint32_t offset, uint32_t size) {
{ ensure(sectrue * (sector <= NORCOW_SECTOR_COUNT), "invalid sector");
ensure(sectrue * (sector <= NORCOW_SECTOR_COUNT), "invalid sector"); return flash_get_address(norcow_sectors[sector], offset, size);
return flash_get_address(norcow_sectors[sector], offset, size);
} }
/* /*
* Writes data to given sector, starting from offset * 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) 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) { if (sector >= NORCOW_SECTOR_COUNT) {
return secfalse; return secfalse;
} }
if (offset + NORCOW_PREFIX_LEN + len > NORCOW_SECTOR_SIZE) { if (offset + NORCOW_PREFIX_LEN + len > NORCOW_SECTOR_SIZE) {
return secfalse; return secfalse;
} }
ensure(flash_unlock_write(), NULL); ensure(flash_unlock_write(), NULL);
// write prefix // write prefix
ensure(flash_write_word(norcow_sectors[sector], offset, prefix), NULL); ensure(flash_write_word(norcow_sectors[sector], offset, prefix), NULL);
offset += NORCOW_PREFIX_LEN; offset += NORCOW_PREFIX_LEN;
if (data != NULL) { if (data != NULL) {
// write data // write data
for (uint16_t i = 0; i < len; i++, offset++) { for (uint16_t i = 0; i < len; i++, offset++) {
ensure(flash_write_byte(norcow_sectors[sector], offset, data[i]), NULL); ensure(flash_write_byte(norcow_sectors[sector], offset, data[i]), NULL);
}
} else {
offset += len;
} }
} else {
offset += len;
}
// pad with zeroes // pad with zeroes
for (; offset % NORCOW_WORD_SIZE; offset++) { for (; offset % NORCOW_WORD_SIZE; offset++) {
ensure(flash_write_byte(norcow_sectors[sector], offset, 0x00), NULL); ensure(flash_write_byte(norcow_sectors[sector], offset, 0x00), NULL);
} }
ensure(flash_lock_write(), NULL); ensure(flash_lock_write(), NULL);
return sectrue; return sectrue;
} }
/* /*
* Erases sector (and sets a magic) * 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 #if NORCOW_HEADER_LEN > 0
// Backup the sector header. // Backup the sector header.
uint32_t header_backup[NORCOW_HEADER_LEN/sizeof(uint32_t)]; uint32_t header_backup[NORCOW_HEADER_LEN / sizeof(uint32_t)];
const void *sector_start = norcow_ptr(sector, 0, NORCOW_HEADER_LEN); const void *sector_start = norcow_ptr(sector, 0, NORCOW_HEADER_LEN);
memcpy(header_backup, sector_start, sizeof(header_backup)); memcpy(header_backup, sector_start, sizeof(header_backup));
#endif #endif
ensure(flash_erase(norcow_sectors[sector]), "erase failed"); ensure(flash_erase(norcow_sectors[sector]), "erase failed");
#if NORCOW_HEADER_LEN > 0 #if NORCOW_HEADER_LEN > 0
// Copy the sector header back. // Copy the sector header back.
ensure(flash_unlock_write(), NULL); ensure(flash_unlock_write(), NULL);
for (uint32_t i = 0; i < NORCOW_HEADER_LEN/sizeof(uint32_t); ++i) { 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_write_word(norcow_sectors[sector], i * sizeof(uint32_t),
} header_backup[i]),
ensure(flash_lock_write(), NULL); NULL);
}
ensure(flash_lock_write(), NULL);
#endif #endif
if (sectrue == set_magic) { 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, NULL, 0),
ensure(norcow_write(sector, NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN, ~NORCOW_VERSION, NULL, 0), "set version failed"); "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 #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 * 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) static secbool read_item(uint8_t sector, uint32_t offset, uint16_t *key,
{ const void **val, uint16_t *len, uint32_t *pos) {
*pos = offset; *pos = offset;
const void *k = norcow_ptr(sector, *pos, 2); const void *k = norcow_ptr(sector, *pos, 2);
if (k == NULL) return secfalse; if (k == NULL) return secfalse;
*pos += 2; *pos += 2;
memcpy(key, k, sizeof(uint16_t)); memcpy(key, k, sizeof(uint16_t));
if (*key == NORCOW_KEY_FREE) { if (*key == NORCOW_KEY_FREE) {
return secfalse; return secfalse;
} }
const void *l = norcow_ptr(sector, *pos, 2); const void *l = norcow_ptr(sector, *pos, 2);
if (l == NULL) return secfalse; if (l == NULL) return secfalse;
*pos += 2; *pos += 2;
memcpy(len, l, sizeof(uint16_t)); memcpy(len, l, sizeof(uint16_t));
*val = norcow_ptr(sector, *pos, *len); *val = norcow_ptr(sector, *pos, *len);
if (*val == NULL) return secfalse; if (*val == NULL) return secfalse;
*pos += *len; *pos += *len;
ALIGN4(*pos); ALIGN4(*pos);
return sectrue; return sectrue;
} }
/* /*
* Writes one item starting from offset * 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) 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; uint32_t prefix = ((uint32_t)len << 16) | key;
*pos = offset + NORCOW_PREFIX_LEN + len; *pos = offset + NORCOW_PREFIX_LEN + len;
ALIGN4(*pos); ALIGN4(*pos);
return norcow_write(sector, offset, prefix, val, len); return norcow_write(sector, offset, prefix, val, len);
} }
/* /*
* Finds the offset from the beginning of the sector where stored items start. * 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) 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); const uint32_t *magic = norcow_ptr(sector, NORCOW_HEADER_LEN,
if (magic == NULL) { NORCOW_MAGIC_LEN + NORCOW_VERSION_LEN);
return secfalse; if (magic == NULL) {
} return secfalse;
}
if (*magic == NORCOW_MAGIC) {
*offset = NORCOW_STORAGE_START; if (*magic == NORCOW_MAGIC) {
*version = ~(magic[1]); *offset = NORCOW_STORAGE_START;
} else if (*magic == NORCOW_MAGIC_V0) { *version = ~(magic[1]);
*offset = NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN; } else if (*magic == NORCOW_MAGIC_V0) {
*version = 0; *offset = NORCOW_HEADER_LEN + NORCOW_MAGIC_LEN;
} else { *version = 0;
return secfalse; } else {
} return secfalse;
}
return sectrue; return sectrue;
} }
/* /*
* Finds item in given sector * Finds item in given sector
*/ */
static secbool find_item(uint8_t sector, uint16_t key, const void **val, uint16_t *len) static secbool find_item(uint8_t sector, uint16_t key, const void **val,
{ uint16_t *len) {
*val = NULL; *val = NULL;
*len = 0; *len = 0;
uint32_t offset; uint32_t offset;
uint32_t version; uint32_t version;
if (sectrue != find_start_offset(sector, &offset, &version)) { if (sectrue != find_start_offset(sector, &offset, &version)) {
return secfalse; return secfalse;
}
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) {
for (;;) { *val = v;
uint16_t k, l; *len = 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;
} }
return sectrue * (*val != NULL); offset = pos;
}
return sectrue * (*val != NULL);
} }
/* /*
* Finds first unused offset in given sector * Finds first unused offset in given sector
*/ */
static uint32_t find_free_offset(uint8_t sector) static uint32_t find_free_offset(uint8_t sector) {
{ uint32_t offset;
uint32_t offset; uint32_t version;
uint32_t version; if (sectrue != find_start_offset(sector, &offset, &version)) {
if (sectrue != find_start_offset(sector, &offset, &version)) { return secfalse;
return secfalse; }
}
for (;;) {
for (;;) { uint16_t key, len;
uint16_t key, len; const void *val;
const void *val; uint32_t pos;
uint32_t pos; if (sectrue != read_item(sector, offset, &key, &val, &len, &pos)) {
if (sectrue != read_item(sector, offset, &key, &val, &len, &pos)) { break;
break;
}
offset = pos;
} }
return offset; offset = pos;
}
return offset;
} }
/* /*
* Compacts active sector and sets new active sector * Compacts active sector and sets new active sector
*/ */
static void compact(void) static void compact(void) {
{ uint32_t offsetr;
uint32_t offsetr; uint32_t version;
uint32_t version; if (sectrue != find_start_offset(norcow_active_sector, &offsetr, &version)) {
if (sectrue != find_start_offset(norcow_active_sector, &offsetr, &version)) { return;
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; // skip deleted items
erase_sector(norcow_write_sector, sectrue); if (k == NORCOW_KEY_DELETED) {
uint32_t offsetw = NORCOW_STORAGE_START; continue;
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;
} }
erase_sector(norcow_active_sector, secfalse); // copy the item
norcow_active_sector = norcow_write_sector; uint32_t posw;
norcow_active_version = NORCOW_VERSION; ensure(write_item(norcow_write_sector, offsetw, k, v, l, &posw),
norcow_free_offset = find_free_offset(norcow_write_sector); "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 * Initializes storage
*/ */
void norcow_init(uint32_t *norcow_version) void norcow_init(uint32_t *norcow_version) {
{ flash_init();
flash_init(); secbool found = secfalse;
secbool found = secfalse; *norcow_version = 0;
*norcow_version = 0; // detect active sector - starts with magic and has highest version
// detect active sector - starts with magic and has highest version for (uint8_t i = 0; i < NORCOW_SECTOR_COUNT; i++) {
for (uint8_t i = 0; i < NORCOW_SECTOR_COUNT; i++) { uint32_t offset;
uint32_t offset; if (sectrue == find_start_offset(i, &offset, &norcow_active_version) &&
if (sectrue == find_start_offset(i, &offset, &norcow_active_version) && norcow_active_version >= *norcow_version) { norcow_active_version >= *norcow_version) {
found = sectrue; found = sectrue;
norcow_active_sector = i; norcow_active_sector = i;
*norcow_version = norcow_active_version; *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);
} }
}
// 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 * Wipe the storage
*/ */
void norcow_wipe(void) void norcow_wipe(void) {
{ erase_sector(0, sectrue);
erase_sector(0, sectrue); for (uint8_t i = 1; i < NORCOW_SECTOR_COUNT; i++) {
for (uint8_t i = 1; i < NORCOW_SECTOR_COUNT; i++) { erase_sector(i, secfalse);
erase_sector(i, secfalse); }
} norcow_active_sector = 0;
norcow_active_sector = 0; norcow_active_version = NORCOW_VERSION;
norcow_active_version = NORCOW_VERSION; norcow_write_sector = 0;
norcow_write_sector = 0; norcow_free_offset = NORCOW_STORAGE_START;
norcow_free_offset = NORCOW_STORAGE_START;
} }
/* /*
* Looks for the given key, returns status of the operation * Looks for the given key, returns status of the operation
*/ */
secbool norcow_get(uint16_t key, const void **val, uint16_t *len) secbool norcow_get(uint16_t key, const void **val, uint16_t *len) {
{ return find_item(norcow_active_sector, key, val, 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) secbool norcow_get_next(uint32_t *offset, uint16_t *key, const void **val,
{ uint16_t *len) {
if (*offset == 0) { if (*offset == 0) {
uint32_t version; uint32_t version;
if (sectrue != find_start_offset(norcow_active_sector, offset, &version)) { if (sectrue != find_start_offset(norcow_active_sector, offset, &version)) {
return secfalse; return secfalse;
}
} }
}
for (;;) { for (;;) {
uint32_t pos = 0; uint32_t pos = 0;
secbool ret = read_item(norcow_active_sector, *offset, key, val, len, &pos); secbool ret = read_item(norcow_active_sector, *offset, key, val, len, &pos);
if (sectrue != ret) { if (sectrue != ret) {
break; break;
} }
*offset = pos; *offset = pos;
// Skip deleted items. // Skip deleted items.
if (*key == NORCOW_KEY_DELETED) { if (*key == NORCOW_KEY_DELETED) {
continue; continue;
} }
if (norcow_active_version == 0) { if (norcow_active_version == 0) {
// Check whether the item is the latest instance. // Check whether the item is the latest instance.
uint32_t offsetr = *offset; uint32_t offsetr = *offset;
for (;;) { for (;;) {
uint16_t k; uint16_t k;
uint16_t l; uint16_t l;
const void *v; const void *v;
ret = read_item(norcow_active_sector, offsetr, &k, &v, &l, &offsetr); ret = read_item(norcow_active_sector, offsetr, &k, &v, &l, &offsetr);
if (sectrue != ret) { if (sectrue != ret) {
// There is no newer instance of the item. // There is no newer instance of the item.
return sectrue; return sectrue;
} }
if (*key == k) { if (*key == k) {
// There exists a newer instance of the item. // There exists a newer instance of the item.
break; break;
}
}
} else {
return sectrue;
} }
}
} 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 * as val, then norcow_set allocates a new key of size len. The value should
* then be written using norcow_update_bytes(). * then be written using norcow_update_bytes().
*/ */
secbool norcow_set(uint16_t key, const void *val, uint16_t len) secbool norcow_set(uint16_t key, const void *val, uint16_t len) {
{ secbool found;
secbool found; return norcow_set_ex(key, val, len, &found);
return norcow_set_ex(key, val, len, &found);
} }
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) {
// Key 0xffff is used as a marker to indicate that the entry is not set. // Key 0xffff is used as a marker to indicate that the entry is not set.
if (key == NORCOW_KEY_FREE) { if (key == NORCOW_KEY_FREE) {
return secfalse; return secfalse;
} }
const uint8_t sector_num = norcow_sectors[norcow_write_sector]; const uint8_t sector_num = norcow_sectors[norcow_write_sector];
secbool ret = secfalse; secbool ret = secfalse;
const void *ptr = NULL; const void *ptr = NULL;
uint16_t len_old = 0; uint16_t len_old = 0;
*found = find_item(norcow_write_sector, key, &ptr, &len_old); *found = find_item(norcow_write_sector, key, &ptr, &len_old);
// Try to update the entry if it already exists. // Try to update the entry if it already exists.
uint32_t offset = 0; uint32_t offset = 0;
if (sectrue == *found) { if (sectrue == *found) {
offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE); offset =
if (val != NULL && len_old == len) { (const uint8_t *)ptr -
ret = sectrue; (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE);
ensure(flash_unlock_write(), NULL); if (val != NULL && len_old == len) {
for (uint16_t i = 0; i < len; i++) { ret = sectrue;
if (sectrue != flash_write_byte(sector_num, offset + i, ((const uint8_t*)val)[i])) { ensure(flash_unlock_write(), NULL);
ret = secfalse; for (uint16_t i = 0; i < len; i++) {
break; if (sectrue != flash_write_byte(sector_num, offset + i,
} ((const uint8_t *)val)[i])) {
} ret = secfalse;
ensure(flash_lock_write(), NULL); break;
} }
}
ensure(flash_lock_write(), NULL);
} }
}
// If the update was not possible then write the entry as a new item. // If the update was not possible then write the entry as a new item.
if (secfalse == ret) { if (secfalse == ret) {
// Delete the old item. // Delete the old item.
if (sectrue == *found) { if (sectrue == *found) {
ensure(flash_unlock_write(), NULL); ensure(flash_unlock_write(), NULL);
// Update the prefix to indicate that the old item has been deleted. // Update the prefix to indicate that the old item has been deleted.
uint32_t prefix = (uint32_t)len_old << 16; uint32_t prefix = (uint32_t)len_old << 16;
ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix), NULL); ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix),
NULL);
// Delete the old item data. // Delete the old item data.
uint32_t end = offset + len_old; uint32_t end = offset + len_old;
while (offset < end) { while (offset < end) {
ensure(flash_write_word(sector_num, offset, 0x00000000), NULL); ensure(flash_write_word(sector_num, offset, 0x00000000), NULL);
offset += NORCOW_WORD_SIZE; offset += NORCOW_WORD_SIZE;
} }
ensure(flash_lock_write(), NULL); 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;
}
} }
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. * Deletes the given key, returns status of the operation.
*/ */
secbool norcow_delete(uint16_t key) secbool norcow_delete(uint16_t key) {
{ // Key 0xffff is used as a marker to indicate that the entry is not set.
// Key 0xffff is used as a marker to indicate that the entry is not set. if (key == NORCOW_KEY_FREE) {
if (key == NORCOW_KEY_FREE) { return secfalse;
return secfalse; }
}
const uint8_t sector_num = norcow_sectors[norcow_write_sector]; const uint8_t sector_num = norcow_sectors[norcow_write_sector];
const void *ptr = NULL; const void *ptr = NULL;
uint16_t len = 0; uint16_t len = 0;
if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) { if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) {
return secfalse; 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. // Update the prefix to indicate that the item has been deleted.
uint32_t prefix = (uint32_t)len << 16; uint32_t prefix = (uint32_t)len << 16;
ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix), NULL); ensure(flash_write_word(sector_num, offset - NORCOW_PREFIX_LEN, prefix),
NULL);
// Delete the item data. // Delete the item data.
uint32_t end = offset + len; uint32_t end = offset + len;
while (offset < end) { while (offset < end) {
ensure(flash_write_word(sector_num, offset, 0x00000000), NULL); ensure(flash_write_word(sector_num, offset, 0x00000000), NULL);
offset += NORCOW_WORD_SIZE; 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 * Update a word in flash at the given pointer. The pointer must point
* into the NORCOW area. * into the NORCOW area.
*/ */
secbool norcow_update_word(uint16_t key, uint16_t offset, uint32_t value) secbool norcow_update_word(uint16_t key, uint16_t offset, uint32_t value) {
{ const void *ptr;
const void *ptr; uint16_t len;
uint16_t len; if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) {
if (sectrue != find_item(norcow_write_sector, key, &ptr, &len)) { return secfalse;
return secfalse; }
} if ((offset & 3) != 0 || offset >= len) {
if ((offset & 3) != 0 || offset >= len) { return secfalse;
return secfalse; }
} uint32_t sector_offset =
uint32_t sector_offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) + offset; (const uint8_t *)ptr -
ensure(flash_unlock_write(), NULL); (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) +
ensure(flash_write_word(norcow_sectors[norcow_write_sector], sector_offset, value), NULL); offset;
ensure(flash_lock_write(), NULL); ensure(flash_unlock_write(), NULL);
return sectrue; 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. * 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) secbool norcow_update_bytes(const uint16_t key, const uint16_t offset,
{ const uint8_t *data, const uint16_t len) {
const void *ptr; const void *ptr;
uint16_t allocated_len; uint16_t allocated_len;
if (sectrue != find_item(norcow_write_sector, key, &ptr, &allocated_len)) { if (sectrue != find_item(norcow_write_sector, key, &ptr, &allocated_len)) {
return secfalse; return secfalse;
} }
if (offset + len > allocated_len) { if (offset + len > allocated_len) {
return secfalse; return secfalse;
} }
uint32_t sector_offset = (const uint8_t*) ptr - (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) + offset; uint32_t sector_offset =
uint8_t sector = norcow_sectors[norcow_write_sector]; (const uint8_t *)ptr -
ensure(flash_unlock_write(), NULL); (const uint8_t *)norcow_ptr(norcow_write_sector, 0, NORCOW_SECTOR_SIZE) +
for (uint16_t i = 0; i < len; i++, sector_offset++) { offset;
ensure(flash_write_byte(sector, sector_offset, data[i]), NULL); uint8_t sector = norcow_sectors[norcow_write_sector];
} ensure(flash_unlock_write(), NULL);
ensure(flash_lock_write(), NULL); for (uint16_t i = 0; i < len; i++, sector_offset++) {
return sectrue; ensure(flash_write_byte(sector, sector_offset, data[i]), NULL);
}
ensure(flash_lock_write(), NULL);
return sectrue;
} }
/* /*
* Complete storage version upgrade * Complete storage version upgrade
*/ */
secbool norcow_upgrade_finish(void) secbool norcow_upgrade_finish(void) {
{ erase_sector(norcow_active_sector, secfalse);
erase_sector(norcow_active_sector, secfalse); norcow_active_sector = norcow_write_sector;
norcow_active_sector = norcow_write_sector; norcow_active_version = NORCOW_VERSION;
norcow_active_version = NORCOW_VERSION; return sectrue;
return sectrue;
} }

@ -45,9 +45,11 @@ void norcow_wipe(void);
secbool norcow_get(uint16_t key, const void **val, uint16_t *len); 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 * 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(). * then be written using norcow_update_bytes().
*/ */
secbool norcow_set(uint16_t key, const void *val, uint16_t len); 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. * 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. * Update the value of the given key starting at the given offset.
* Note that you can only change bits from 1 to 0. * 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 * Complete storage version upgrade

File diff suppressed because it is too large Load Diff

@ -20,13 +20,15 @@
#ifndef __STORAGE_H__ #ifndef __STORAGE_H__
#define __STORAGE_H__ #define __STORAGE_H__
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include "secbool.h" #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); void storage_wipe(void);
secbool storage_is_unlocked(void); secbool storage_is_unlocked(void);
void storage_lock(void); void storage_lock(void);
@ -35,7 +37,8 @@ secbool storage_has_pin(void);
secbool storage_pin_fails_increase(void); secbool storage_pin_fails_increase(void);
uint32_t storage_get_pin_rem(void); uint32_t storage_get_pin_rem(void);
secbool storage_change_pin(const uint32_t oldpin, const uint32_t newpin); 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_set(const uint16_t key, const void *val, uint16_t len);
secbool storage_delete(const uint16_t key); secbool storage_delete(const uint16_t key);
secbool storage_set_counter(const uint16_t key, const uint32_t count); secbool storage_set_counter(const uint16_t key, const uint32_t count);

@ -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

@ -0,0 +1,5 @@
^\./common/
^\./core/embed/
^\./crypto/
^\./legacy/
^\./storage/

@ -0,0 +1,2 @@
^\./legacy/firmware/protob/messages_pb2\.py
^\./legacy/vendor

@ -0,0 +1,4 @@
^\./common/
^\./core/src/
^\./crypto/
^\./legacy/
Loading…
Cancel
Save