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"]
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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,3 +1,5 @@
// clang-format off
/*
* 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):
# 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

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

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

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

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

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

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

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

@ -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("<L", data[12:16])[0]
assert size == len(data) - 1024
def check_signatures(data):
# Analyses given firmware and prints out
# status of included signatures
@ -146,7 +146,7 @@ def check_signatures(data):
used.append(indexes[x])
print("Slot #%d signature: VALID" % (x + 1), signature.hex())
except:
except Exception:
print("Slot #%d signature: INVALID" % (x + 1), signature.hex())
@ -202,7 +202,7 @@ def sign(data, is_pem):
index = i
break
if index == None:
if index is None:
raise Exception("Unable to find private key index. Unknown private key?")
signature = key.sign_deterministic(to_sign, hashfunc=hashlib.sha256)

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

@ -1,19 +1,19 @@
#!/usr/bin/env python
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:
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)

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

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

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

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

@ -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, };

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

@ -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 <stdint.h>
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()

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

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

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

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

@ -1,35 +1,35 @@
#include <readline/history.h>
#include <readline/readline.h>
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
#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);
}
}

@ -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 "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;
}

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

File diff suppressed because it is too large Load Diff

@ -20,13 +20,15 @@
#ifndef __STORAGE_H__
#define __STORAGE_H__
#include <stdint.h>
#include <stddef.h>
#include <stdint.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);
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);

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