format: start using clang-format with style=Google

pull/25/head
Pavol Rusnak 5 years ago
parent e53826e951
commit 0b7dbc12cb
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -1,3 +1,2 @@
---
BasedOnStyle: Google
IndentWidth: 4

@ -86,10 +86,11 @@ style: ## apply code style on application sources and tests
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 $(shell find embed -type f -name *.[ch])
./tools/clang-format-check embed/*/*.{c,h} embed/extmod/modtrezor*/*.{c,h}
cstyle: ## apply code style on low-level C code
clang-format -i $(shell find embed -type f -name *.[ch])
clang-format -i embed/*/*.{c,h} embed/extmod/modtrezor*/*.{c,h}
## code generation:

@ -21,8 +21,8 @@
#include "common.h"
#include "display.h"
#include "image.h"
#include "flash.h"
#include "image.h"
#include "rng.h"
#include "sdcard.h"
@ -45,8 +45,7 @@ static const uint8_t * const BOARDLOADER_KEYS[] = {
#endif
};
static uint32_t check_sdcard(void)
{
static uint32_t check_sdcard(void) {
if (sectrue != sdcard_power_on()) {
return 0;
}
@ -61,25 +60,27 @@ static uint32_t check_sdcard(void)
memzero(buf, sizeof(buf));
const secbool read_status = sdcard_read_blocks(buf, 0, IMAGE_HEADER_SIZE / SDCARD_BLOCK_SIZE);
const secbool read_status =
sdcard_read_blocks(buf, 0, IMAGE_HEADER_SIZE / SDCARD_BLOCK_SIZE);
sdcard_power_off();
image_header hdr;
if ((sectrue == read_status) && (sectrue == load_image_header((const uint8_t *)buf, BOOTLOADER_IMAGE_MAGIC, BOOTLOADER_IMAGE_MAXSIZE, BOARDLOADER_KEY_M, BOARDLOADER_KEY_N, BOARDLOADER_KEYS, &hdr))) {
if ((sectrue == read_status) &&
(sectrue ==
load_image_header((const uint8_t *)buf, BOOTLOADER_IMAGE_MAGIC,
BOOTLOADER_IMAGE_MAXSIZE, BOARDLOADER_KEY_M,
BOARDLOADER_KEY_N, BOARDLOADER_KEYS, &hdr))) {
return hdr.codelen;
} else {
return 0;
}
}
static void progress_callback(int pos, int len) {
display_printf(".");
}
static void progress_callback(int pos, int len) { display_printf("."); }
static secbool copy_sdcard(void)
{
static secbool copy_sdcard(void) {
display_backlight(255);
display_printf("TREZOR Boardloader\n");
@ -127,7 +128,8 @@ static secbool copy_sdcard(void)
22,
FLASH_SECTOR_FIRMWARE_EXTRA_END,
};
if (sectrue != flash_erase_sectors(sectors, sizeof(sectors), progress_callback)) {
if (sectrue !=
flash_erase_sectors(sectors, sizeof(sectors), progress_callback)) {
display_printf(" failed\n");
return secfalse;
}
@ -144,7 +146,10 @@ static secbool copy_sdcard(void)
for (int i = 0; i < (IMAGE_HEADER_SIZE + codelen) / SDCARD_BLOCK_SIZE; i++) {
ensure(sdcard_read_blocks(buf, i, 1), NULL);
for (int j = 0; j < SDCARD_BLOCK_SIZE / sizeof(uint32_t); j++) {
ensure(flash_write_word(FLASH_SECTOR_BOOTLOADER, i * SDCARD_BLOCK_SIZE + j * sizeof(uint32_t), buf[j]), NULL);
ensure(flash_write_word(FLASH_SECTOR_BOOTLOADER,
i * SDCARD_BLOCK_SIZE + j * sizeof(uint32_t),
buf[j]),
NULL);
}
}
@ -157,8 +162,7 @@ static secbool copy_sdcard(void)
return sectrue;
}
int main(void)
{
int main(void) {
if (sectrue != reset_flags_check()) {
return 1;
}
@ -169,7 +173,8 @@ int main(void)
if (sectrue != flash_configure_option_bytes()) {
// display is not initialized so don't call ensure
secbool r = flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL);
secbool r =
flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL);
(void)r;
return 2;
}
@ -185,15 +190,16 @@ int main(void)
image_header hdr;
ensure(
load_image_header((const uint8_t *)BOOTLOADER_START, BOOTLOADER_IMAGE_MAGIC, BOOTLOADER_IMAGE_MAXSIZE, BOARDLOADER_KEY_M, BOARDLOADER_KEY_N, BOARDLOADER_KEYS, &hdr),
ensure(load_image_header((const uint8_t *)BOOTLOADER_START,
BOOTLOADER_IMAGE_MAGIC, BOOTLOADER_IMAGE_MAXSIZE,
BOARDLOADER_KEY_M, BOARDLOADER_KEY_N,
BOARDLOADER_KEYS, &hdr),
"invalid bootloader header");
const uint8_t sectors[] = {
FLASH_SECTOR_BOOTLOADER,
};
ensure(
check_image_contents(&hdr, IMAGE_HEADER_SIZE, sectors, 1),
ensure(check_image_contents(&hdr, IMAGE_HEADER_SIZE, sectors, 1),
"invalid bootloader hash");
jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE);

@ -28,9 +28,9 @@
#include "icon_cancel.h"
#include "icon_confirm.h"
#include "icon_info.h"
#include "icon_done.h"
#include "icon_fail.h"
#include "icon_info.h"
#include "icon_install.h"
#include "icon_wipe.h"
@ -47,21 +47,21 @@
// common shared functions
static void ui_confirm_cancel_buttons(void)
{
static void ui_confirm_cancel_buttons(void) {
display_bar_radius(9, 184, 108, 50, COLOR_BL_FAIL, COLOR_WHITE, 4);
display_icon(9 + (108 - 16) / 2, 184 + (50 - 16) / 2, 16, 16, toi_icon_cancel + 12, sizeof(toi_icon_cancel) - 12, COLOR_WHITE, COLOR_BL_FAIL);
display_icon(9 + (108 - 16) / 2, 184 + (50 - 16) / 2, 16, 16,
toi_icon_cancel + 12, sizeof(toi_icon_cancel) - 12, COLOR_WHITE,
COLOR_BL_FAIL);
display_bar_radius(123, 184, 108, 50, COLOR_BL_DONE, COLOR_WHITE, 4);
display_icon(123 + (108 - 19) / 2, 184 + (50 - 16) / 2, 20, 16, toi_icon_confirm + 12, sizeof(toi_icon_confirm) - 12, COLOR_WHITE, COLOR_BL_DONE);
display_icon(123 + (108 - 19) / 2, 184 + (50 - 16) / 2, 20, 16,
toi_icon_confirm + 12, sizeof(toi_icon_confirm) - 12,
COLOR_WHITE, COLOR_BL_DONE);
}
static const char *format_ver(const char *format, uint32_t version)
{
static const char *format_ver(const char *format, uint32_t version) {
static char ver_str[64];
mini_snprintf(ver_str, sizeof(ver_str), format,
(int)(version & 0xFF),
(int)((version >> 8) & 0xFF),
(int)((version >> 16) & 0xFF)
mini_snprintf(ver_str, sizeof(ver_str), format, (int)(version & 0xFF),
(int)((version >> 8) & 0xFF), (int)((version >> 16) & 0xFF)
// ignore build field (int)((version >> 24) & 0xFF)
);
return ver_str;
@ -71,8 +71,8 @@ static const char *format_ver(const char *format, uint32_t version)
static uint16_t boot_background;
void ui_screen_boot(const vendor_header * const vhdr, const image_header * const hdr)
{
void ui_screen_boot(const vendor_header *const vhdr,
const image_header *const hdr) {
const int show_string = ((vhdr->vtrust & VTRUST_STRING) == 0);
if ((vhdr->vtrust & VTRUST_RED) == 0) {
boot_background = COLOR_BL_FAIL;
@ -90,176 +90,209 @@ void ui_screen_boot(const vendor_header * const vhdr, const image_header * const
// check whether vendor image is 120x120
if (memcmp(vimg, "TOIf\x78\x00\x78\x00", 4) == 0) {
uint32_t datalen = *(uint32_t *)(vimg + 8);
display_image((DISPLAY_RESX - 120) / 2, image_top, 120, 120, vimg + 12, datalen);
display_image((DISPLAY_RESX - 120) / 2, image_top, 120, 120, vimg + 12,
datalen);
}
if (show_string) {
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5 - 50, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_WHITE, boot_background);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5 - 50, vhdr->vstr,
vhdr->vstr_len, FONT_NORMAL, COLOR_WHITE,
boot_background);
const char *ver_str = format_ver("%d.%d.%d", fw_version);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5 - 25, ver_str, -1, FONT_NORMAL, COLOR_WHITE, boot_background);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5 - 25, ver_str, -1,
FONT_NORMAL, COLOR_WHITE, boot_background);
}
}
void ui_screen_boot_wait(int wait_seconds)
{
void ui_screen_boot_wait(int wait_seconds) {
char wait_str[16];
mini_snprintf(wait_str, sizeof(wait_str), "starting in %d s", wait_seconds);
display_bar(0, DISPLAY_RESY - 5 - 20, DISPLAY_RESX, 5 + 20, boot_background);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5, wait_str, -1, FONT_NORMAL, COLOR_WHITE, boot_background);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5, wait_str, -1,
FONT_NORMAL, COLOR_WHITE, boot_background);
}
void ui_screen_boot_click(void) {
display_bar(0, DISPLAY_RESY - 5 - 20, DISPLAY_RESX, 5 + 20, boot_background);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5, "click to continue ...", -1, FONT_NORMAL, COLOR_WHITE, boot_background);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5,
"click to continue ...", -1, FONT_NORMAL, COLOR_WHITE,
boot_background);
}
// welcome UI
void ui_screen_first(void)
{
display_icon(0, 0, 240, 240, toi_icon_logo + 12, sizeof(toi_icon_logo) - 12, COLOR_BLACK, COLOR_WHITE);
void ui_screen_first(void) {
display_icon(0, 0, 240, 240, toi_icon_logo + 12, sizeof(toi_icon_logo) - 12,
COLOR_BLACK, COLOR_WHITE);
}
void ui_screen_second(void)
{
void ui_screen_second(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_icon((DISPLAY_RESX - 200) / 2, (DISPLAY_RESY - 60) / 2, 200, 60, toi_icon_safeplace + 12, sizeof(toi_icon_safeplace) - 12, COLOR_BLACK, COLOR_WHITE);
display_icon((DISPLAY_RESX - 200) / 2, (DISPLAY_RESY - 60) / 2, 200, 60,
toi_icon_safeplace + 12, sizeof(toi_icon_safeplace) - 12,
COLOR_BLACK, COLOR_WHITE);
}
void ui_screen_third(void)
{
void ui_screen_third(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_icon((DISPLAY_RESX - 180) / 2, (DISPLAY_RESY - 30) / 2 - 5, 180, 30, toi_icon_welcome + 12, sizeof(toi_icon_welcome) - 12, COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 220, "Go to trezor.io/start", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_icon((DISPLAY_RESX - 180) / 2, (DISPLAY_RESY - 30) / 2 - 5, 180, 30,
toi_icon_welcome + 12, sizeof(toi_icon_welcome) - 12,
COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 220, "Go to trezor.io/start", -1, FONT_NORMAL,
COLOR_BLACK, COLOR_WHITE);
}
// info UI
void ui_screen_info(secbool buttons, const vendor_header * const vhdr, const image_header * const hdr)
{
void ui_screen_info(secbool buttons, const vendor_header *const vhdr,
const image_header *const hdr) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
const char *ver_str = format_ver("Bootloader %d.%d.%d", VERSION_UINT32);
display_text(16, 32, ver_str, -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12, COLOR_BL_GRAY, COLOR_WHITE);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12,
COLOR_BL_GRAY, COLOR_WHITE);
if (vhdr && hdr) {
ver_str = format_ver("Firmware %d.%d.%d", (hdr->version));
display_text(55, 70, ver_str, -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE);
display_text(55, 95, "by", -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE);
display_text(55, 120, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE);
display_text(55, 120, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL,
COLOR_BL_GRAY, COLOR_WHITE);
} else {
display_text(55, 70, "No Firmware", -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE);
display_text(55, 70, "No Firmware", -1, FONT_NORMAL, COLOR_BL_GRAY,
COLOR_WHITE);
}
if (sectrue == buttons) {
display_text_center(120, 170, "Connect to host?", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 170, "Connect to host?", -1, FONT_NORMAL,
COLOR_BLACK, COLOR_WHITE);
ui_confirm_cancel_buttons();
} else {
display_text_center(120, 220, "Go to trezor.io/start", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 220, "Go to trezor.io/start", -1, FONT_NORMAL,
COLOR_BLACK, COLOR_WHITE);
}
}
void ui_screen_info_fingerprint(const image_header * const hdr)
{
void ui_screen_info_fingerprint(const image_header *const hdr) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_text(16, 32, "Firmware fingerprint", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(16, 32, "Firmware fingerprint", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK);
static const char *hexdigits = "0123456789abcdef";
char fingerprint_str[64];
for (int i = 0; i < 32; i++) {
fingerprint_str[i * 2 ] = hexdigits[(hdr->fingerprint[i] >> 4) & 0xF];
fingerprint_str[i * 2] = hexdigits[(hdr->fingerprint[i] >> 4) & 0xF];
fingerprint_str[i * 2 + 1] = hexdigits[hdr->fingerprint[i] & 0xF];
}
for (int i = 0; i < 4; i++) {
display_text_center(120, 70 + i * 25, fingerprint_str + i * 16, 16, FONT_MONO, COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 70 + i * 25, fingerprint_str + i * 16, 16,
FONT_MONO, COLOR_BLACK, COLOR_WHITE);
}
display_bar_radius(9, 184, 222, 50, COLOR_BL_DONE, COLOR_WHITE, 4);
display_icon(9 + (222 - 19) / 2, 184 + (50 - 16) / 2, 20, 16, toi_icon_confirm + 12, sizeof(toi_icon_confirm) - 12, COLOR_WHITE, COLOR_BL_DONE);
display_icon(9 + (222 - 19) / 2, 184 + (50 - 16) / 2, 20, 16,
toi_icon_confirm + 12, sizeof(toi_icon_confirm) - 12,
COLOR_WHITE, COLOR_BL_DONE);
}
// install UI
void ui_screen_install_confirm_upgrade(const vendor_header * const vhdr, const image_header * const hdr)
{
void ui_screen_install_confirm_upgrade(const vendor_header *const vhdr,
const image_header *const hdr) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_text(16, 32, "Firmware update", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(16, 32, "Firmware update", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12, COLOR_BLACK, COLOR_WHITE);
display_text(55, 70, "Update firmware by", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(55, 95, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12,
COLOR_BLACK, COLOR_WHITE);
display_text(55, 70, "Update firmware by", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_text(55, 95, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
const char *ver_str = format_ver("to version %d.%d.%d?", hdr->version);
display_text(55, 120, ver_str, -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
ui_confirm_cancel_buttons();
}
void ui_screen_install_confirm_newvendor(const vendor_header * const vhdr, const image_header * const hdr)
{
void ui_screen_install_confirm_newvendor(const vendor_header *const vhdr,
const image_header *const hdr) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_text(16, 32, "Vendor change", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(16, 32, "Vendor change", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12, COLOR_BLACK, COLOR_WHITE);
display_text(55, 70, "Install firmware by", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(55, 95, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12,
COLOR_BLACK, COLOR_WHITE);
display_text(55, 70, "Install firmware by", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_text(55, 95, vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
const char *ver_str = format_ver("(version %d.%d.%d)?", hdr->version);
display_text(55, 120, ver_str, -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 170, "Seed will be erased!", -1, FONT_NORMAL, COLOR_BL_FAIL, COLOR_WHITE);
display_text_center(120, 170, "Seed will be erased!", -1, FONT_NORMAL,
COLOR_BL_FAIL, COLOR_WHITE);
ui_confirm_cancel_buttons();
}
void ui_screen_install(void)
{
void ui_screen_install(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(0, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Installing firmware", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_loader(0, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install,
sizeof(toi_icon_install), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24,
"Installing firmware", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
}
void ui_screen_install_progress_erase(int pos, int len)
{
display_loader(250 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
void ui_screen_install_progress_erase(int pos, int len) {
display_loader(250 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE,
toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
}
void ui_screen_install_progress_upload(int pos)
{
display_loader(pos, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
void ui_screen_install_progress_upload(int pos) {
display_loader(pos, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install,
sizeof(toi_icon_install), COLOR_BLACK);
}
// wipe UI
void ui_screen_wipe_confirm(void)
{
void ui_screen_wipe_confirm(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_text(16, 32, "Wipe device", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(16, 32, "Wipe device", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12, COLOR_BLACK, COLOR_WHITE);
display_text(55, 70, "Do you want to", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text(55, 95, "wipe the device?", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text_center(120, 170, "Seed will be erased!", -1, FONT_NORMAL, COLOR_BL_FAIL, COLOR_WHITE);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12,
COLOR_BLACK, COLOR_WHITE);
display_text(55, 70, "Do you want to", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_text(55, 95, "wipe the device?", -1, FONT_NORMAL, COLOR_BLACK,
COLOR_WHITE);
display_text_center(120, 170, "Seed will be erased!", -1, FONT_NORMAL,
COLOR_BL_FAIL, COLOR_WHITE);
ui_confirm_cancel_buttons();
}
void ui_screen_wipe(void)
{
void ui_screen_wipe(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(0, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Wiping device", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_loader(0, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe,
sizeof(toi_icon_wipe), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Wiping device", -1,
FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
}
void ui_screen_wipe_progress(int pos, int len)
{
display_loader(1000 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK);
void ui_screen_wipe_progress(int pos, int len) {
display_loader(1000 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE,
toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK);
}
// done UI
void ui_screen_done(int restart_seconds, secbool full_redraw)
{
void ui_screen_done(int restart_seconds, secbool full_redraw) {
const char *str;
char count_str[24];
if (restart_seconds >= 1) {
mini_snprintf(count_str, sizeof(count_str), "Done! Restarting in %d s", restart_seconds);
mini_snprintf(count_str, sizeof(count_str), "Done! Restarting in %d s",
restart_seconds);
str = count_str;
} else {
str = "Done! Unplug the device.";
@ -267,55 +300,58 @@ void ui_screen_done(int restart_seconds, secbool full_redraw)
if (sectrue == full_redraw) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
}
display_loader(1000, -20, COLOR_BL_DONE, COLOR_WHITE, toi_icon_done, sizeof(toi_icon_done), COLOR_BLACK);
display_loader(1000, -20, COLOR_BL_DONE, COLOR_WHITE, toi_icon_done,
sizeof(toi_icon_done), COLOR_BLACK);
if (secfalse == full_redraw) {
display_bar(0, DISPLAY_RESY - 24 - 18, 240, 23, COLOR_WHITE);
}
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, str, -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, str, -1, FONT_NORMAL,
COLOR_BLACK, COLOR_WHITE);
}
// error UI
void ui_screen_fail(void)
{
void ui_screen_fail(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_FAIL, COLOR_WHITE, toi_icon_fail, sizeof(toi_icon_fail), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Failed! Please, reconnect.", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_FAIL, COLOR_WHITE, toi_icon_fail,
sizeof(toi_icon_fail), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24,
"Failed! Please, reconnect.", -1, FONT_NORMAL,
COLOR_BLACK, COLOR_WHITE);
}
// general functions
void ui_fadein(void)
{
display_fade(0, BACKLIGHT_NORMAL, 1000);
}
void ui_fadein(void) { display_fade(0, BACKLIGHT_NORMAL, 1000); }
void ui_fadeout(void)
{
void ui_fadeout(void) {
display_fade(BACKLIGHT_NORMAL, 0, 500);
display_clear();
}
int ui_user_input(int zones)
{
int ui_user_input(int zones) {
for (;;) {
uint32_t evt = touch_click();
uint16_t x = touch_unpack_x(evt);
uint16_t y = touch_unpack_y(evt);
// clicked on Cancel button
if ((zones & INPUT_CANCEL) && x >= 9 && x < 9 + 108 && y > 184 && y < 184 + 50) {
if ((zones & INPUT_CANCEL) && x >= 9 && x < 9 + 108 && y > 184 &&
y < 184 + 50) {
return INPUT_CANCEL;
}
// clicked on Confirm button
if ((zones & INPUT_CONFIRM) && x >= 123 && x < 123 + 108 && y > 184 && y < 184 + 50) {
if ((zones & INPUT_CONFIRM) && x >= 123 && x < 123 + 108 && y > 184 &&
y < 184 + 50) {
return INPUT_CONFIRM;
}
// clicked on Long Confirm button
if ((zones & INPUT_LONG_CONFIRM) && x >= 9 && x < 9 + 222 && y > 184 && y < 184 + 50) {
if ((zones & INPUT_LONG_CONFIRM) && x >= 9 && x < 9 + 222 && y > 184 &&
y < 184 + 50) {
return INPUT_LONG_CONFIRM;
}
// clicked on Info icon
if ((zones & INPUT_INFO) && x >= 16 && x < 16 + 32 && y > 54 && y < 54 + 32) {
if ((zones & INPUT_INFO) && x >= 16 && x < 16 + 32 && y > 54 &&
y < 54 + 32) {
return INPUT_INFO;
}
}

@ -20,10 +20,11 @@
#ifndef __BOOTUI_H__
#define __BOOTUI_H__
#include "secbool.h"
#include "image.h"
#include "secbool.h"
void ui_screen_boot(const vendor_header * const vhdr, const image_header * const hdr);
void ui_screen_boot(const vendor_header* const vhdr,
const image_header* const hdr);
void ui_screen_boot_wait(int wait_seconds);
void ui_screen_boot_click(void);
@ -31,11 +32,14 @@ void ui_screen_first(void);
void ui_screen_second(void);
void ui_screen_third(void);
void ui_screen_info(secbool buttons, const vendor_header * const vhdr, const image_header * const hdr);
void ui_screen_info_fingerprint(const image_header * const hdr);
void ui_screen_info(secbool buttons, const vendor_header* const vhdr,
const image_header* const hdr);
void ui_screen_info_fingerprint(const image_header* const hdr);
void ui_screen_install_confirm_upgrade(const vendor_header * const vhdr, const image_header * const hdr);
void ui_screen_install_confirm_newvendor(const vendor_header * const vhdr, const image_header * const hdr);
void ui_screen_install_confirm_upgrade(const vendor_header* const vhdr,
const image_header* const hdr);
void ui_screen_install_confirm_newvendor(const vendor_header* const vhdr,
const image_header* const hdr);
void ui_screen_install(void);
void ui_screen_install_progress_erase(int pos, int len);
void ui_screen_install_progress_upload(int pos);

@ -21,11 +21,11 @@
#include <sys/types.h>
#include "common.h"
#include "mpu.h"
#include "image.h"
#include "flash.h"
#include "display.h"
#include "flash.h"
#include "image.h"
#include "mini_printf.h"
#include "mpu.h"
#include "rng.h"
#include "secbool.h"
#include "touch.h"
@ -51,7 +51,6 @@ static const uint8_t * const BOOTLOADER_KEYS[] = {
#define USB_IFACE_NUM 0
static void usb_init_all(void) {
static const usb_dev_info_t dev_info = {
.device_class = 0x00,
.device_subclass = 0x00,
@ -87,14 +86,15 @@ static void usb_init_all(void) {
usb_start();
}
static secbool bootloader_usb_loop(const vendor_header * const vhdr, const image_header * const hdr)
{
static secbool bootloader_usb_loop(const vendor_header *const vhdr,
const image_header *const hdr) {
usb_init_all();
uint8_t buf[USB_PACKET_SIZE];
for (;;) {
int r = usb_webusb_read_blocking(USB_IFACE_NUM, buf, USB_PACKET_SIZE, USB_TIMEOUT);
int r = usb_webusb_read_blocking(USB_IFACE_NUM, buf, USB_PACKET_SIZE,
USB_TIMEOUT);
if (r != USB_PACKET_SIZE) {
continue;
}
@ -155,8 +155,7 @@ static secbool bootloader_usb_loop(const vendor_header * const vhdr, const image
usb_stop();
usb_deinit();
return secfalse; // shutdown
} else
if (r == 0) { // last chunk received
} else if (r == 0) { // last chunk received
ui_screen_install_progress_upload(1000);
ui_fadeout();
ui_screen_done(4, sectrue);
@ -183,15 +182,22 @@ static secbool bootloader_usb_loop(const vendor_header * const vhdr, const image
}
}
secbool load_vendor_header_keys(const uint8_t * const data, vendor_header * const vhdr)
{
return load_vendor_header(data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N, BOOTLOADER_KEYS, vhdr);
secbool load_vendor_header_keys(const uint8_t *const data,
vendor_header *const vhdr) {
return load_vendor_header(data, BOOTLOADER_KEY_M, BOOTLOADER_KEY_N,
BOOTLOADER_KEYS, vhdr);
}
static secbool check_vendor_keys_lock(const vendor_header * const vhdr) {
static secbool check_vendor_keys_lock(const vendor_header *const vhdr) {
uint8_t lock[FLASH_OTP_BLOCK_SIZE];
ensure(flash_otp_read(FLASH_OTP_BLOCK_VENDOR_KEYS_LOCK, 0, lock, FLASH_OTP_BLOCK_SIZE), NULL);
if (0 == memcmp(lock, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", FLASH_OTP_BLOCK_SIZE)) {
ensure(flash_otp_read(FLASH_OTP_BLOCK_VENDOR_KEYS_LOCK, 0, lock,
FLASH_OTP_BLOCK_SIZE),
NULL);
if (0 ==
memcmp(lock,
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
FLASH_OTP_BLOCK_SIZE)) {
return sectrue;
}
uint8_t hash[32];
@ -203,8 +209,7 @@ static secbool check_vendor_keys_lock(const vendor_header * const vhdr) {
#if PRODUCTION
static void check_bootloader_version(void)
{
static void check_bootloader_version(void) {
uint8_t bits[FLASH_OTP_BLOCK_SIZE];
for (int i = 0; i < FLASH_OTP_BLOCK_SIZE * 8; i++) {
if (i < VERSION_MONOTONIC) {
@ -213,18 +218,22 @@ static void check_bootloader_version(void)
bits[i / 8] |= (1 << (7 - (i % 8)));
}
}
ensure(flash_otp_write(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_write(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits,
FLASH_OTP_BLOCK_SIZE),
NULL);
uint8_t bits2[FLASH_OTP_BLOCK_SIZE];
ensure(flash_otp_read(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits2, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_read(FLASH_OTP_BLOCK_BOOTLOADER_VERSION, 0, bits2,
FLASH_OTP_BLOCK_SIZE),
NULL);
ensure(sectrue * (0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE)), "Bootloader downgraded");
ensure(sectrue * (0 == memcmp(bits, bits2, FLASH_OTP_BLOCK_SIZE)),
"Bootloader downgraded");
}
#endif
int main(void)
{
int main(void) {
touch_init();
touch_power_on();
@ -254,15 +263,20 @@ main_start:
// detect whether the devices contains a valid firmware
firmware_present = load_vendor_header_keys((const uint8_t *)FIRMWARE_START, &vhdr);
firmware_present =
load_vendor_header_keys((const uint8_t *)FIRMWARE_START, &vhdr);
if (sectrue == firmware_present) {
firmware_present = check_vendor_keys_lock(&vhdr);
}
if (sectrue == firmware_present) {
firmware_present = load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr);
firmware_present = load_image_header(
(const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC,
FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr);
}
if (sectrue == firmware_present) {
firmware_present = check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT);
firmware_present =
check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen,
FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT);
}
// start the bootloader if no or broken firmware found ...
@ -286,7 +300,8 @@ main_start:
ui_fadein();
// erase storage
ensure(flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL), NULL);
ensure(flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL),
NULL);
// and start the usb loop
if (bootloader_usb_loop(NULL, NULL) != sectrue) {
@ -323,7 +338,8 @@ main_start:
// show fingerprint
ui_screen_info_fingerprint(&hdr);
ui_fadein();
while (INPUT_LONG_CONFIRM != ui_user_input(INPUT_LONG_CONFIRM)) { }
while (INPUT_LONG_CONFIRM != ui_user_input(INPUT_LONG_CONFIRM)) {
}
ui_fadeout();
ui_screen_info(sectrue, &vhdr, &hdr);
ui_fadein();
@ -336,26 +352,23 @@ main_start:
}
}
ensure(
load_vendor_header_keys((const uint8_t *)FIRMWARE_START, &vhdr),
ensure(load_vendor_header_keys((const uint8_t *)FIRMWARE_START, &vhdr),
"invalid vendor header");
ensure(
check_vendor_keys_lock(&vhdr),
"unauthorized vendor keys");
ensure(check_vendor_keys_lock(&vhdr), "unauthorized vendor keys");
ensure(
load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr),
ensure(load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen),
FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE,
vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr),
"invalid firmware header");
ensure(
check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT),
ensure(check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen,
FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT),
"invalid firmware hash");
// if all VTRUST flags are unset = ultimate trust => skip the procedure
if ((vhdr.vtrust & VTRUST_ALL) != VTRUST_ALL) {
// ui_fadeout(); // no fadeout - we start from black screen
ui_screen_boot(&vhdr, &hdr);
ui_fadein();

@ -39,8 +39,8 @@
#define MSG_HEADER1_LEN 9
#define MSG_HEADER2_LEN 1
secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size)
{
secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id,
uint32_t *msg_size) {
if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') {
return secfalse;
}
@ -57,8 +57,8 @@ typedef struct {
} usb_write_state;
/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */
static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
{
static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf,
size_t count) {
usb_write_state *state = (usb_write_state *)(stream->state);
size_t written = 0;
@ -75,10 +75,12 @@ static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
return true;
} else {
// append data that fits
memcpy(state->buf + state->packet_pos, buf + written, USB_PACKET_SIZE - state->packet_pos);
memcpy(state->buf + state->packet_pos, buf + written,
USB_PACKET_SIZE - state->packet_pos);
written += USB_PACKET_SIZE - state->packet_pos;
// send packet
int r = usb_webusb_write_blocking(state->iface_num, state->buf, USB_PACKET_SIZE, USB_TIMEOUT);
int r = usb_webusb_write_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
// prepare new packet
state->packet_index++;
@ -91,23 +93,23 @@ static bool _usb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
return true;
}
static void _usb_write_flush(usb_write_state *state)
{
static void _usb_write_flush(usb_write_state *state) {
// if packet is not filled up completely
if (state->packet_pos < USB_PACKET_SIZE) {
// pad it with zeroes
memzero(state->buf + state->packet_pos, USB_PACKET_SIZE - state->packet_pos);
memzero(state->buf + state->packet_pos,
USB_PACKET_SIZE - state->packet_pos);
}
// send packet
int r = usb_webusb_write_blocking(state->iface_num, state->buf, USB_PACKET_SIZE, USB_TIMEOUT);
int r = usb_webusb_write_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
}
static secbool _send_msg(uint8_t iface_num, uint16_t msg_id, const pb_field_t fields[], const void *msg)
{
static secbool _send_msg(uint8_t iface_num, uint16_t msg_id,
const pb_field_t fields[], const void *msg) {
// determine message size by serializing it into a dummy stream
pb_ostream_t sizestream = {
.callback = NULL,
pb_ostream_t sizestream = {.callback = NULL,
.state = NULL,
.max_size = SIZE_MAX,
.bytes_written = 0,
@ -121,20 +123,25 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id, const pb_field_t fi
.iface_num = iface_num,
.packet_index = 0,
.packet_pos = MSG_HEADER1_LEN,
.buf = {
'?', '#', '#',
(msg_id >> 8) & 0xFF, msg_id & 0xFF,
(msg_size >> 24) & 0xFF, (msg_size >> 16) & 0xFF, (msg_size >> 8) & 0xFF, msg_size & 0xFF,
.buf =
{
'?',
'#',
'#',
(msg_id >> 8) & 0xFF,
msg_id & 0xFF,
(msg_size >> 24) & 0xFF,
(msg_size >> 16) & 0xFF,
(msg_size >> 8) & 0xFF,
msg_size & 0xFF,
},
};
pb_ostream_t stream = {
.callback = &_usb_write,
pb_ostream_t stream = {.callback = &_usb_write,
.state = &state,
.max_size = SIZE_MAX,
.bytes_written = 0,
.errmsg = NULL
};
.errmsg = NULL};
if (false == pb_encode(&stream, fields, msg)) {
return secfalse;
@ -146,11 +153,33 @@ static secbool _send_msg(uint8_t iface_num, uint16_t msg_id, const pb_field_t fi
}
#define MSG_SEND_INIT(TYPE) TYPE msg_send = TYPE##_init_default
#define MSG_SEND_ASSIGN_VALUE(FIELD, VALUE) { msg_send.has_##FIELD = true; msg_send.FIELD = VALUE; }
#define MSG_SEND_ASSIGN_STRING(FIELD, VALUE) { msg_send.has_##FIELD = true; memzero(msg_send.FIELD, sizeof(msg_send.FIELD)); strncpy(msg_send.FIELD, VALUE, sizeof(msg_send.FIELD) - 1); }
#define MSG_SEND_ASSIGN_STRING_LEN(FIELD, VALUE, LEN) { msg_send.has_##FIELD = true; memzero(msg_send.FIELD, sizeof(msg_send.FIELD)); strncpy(msg_send.FIELD, VALUE, MIN(LEN, sizeof(msg_send.FIELD) - 1)); }
#define MSG_SEND_ASSIGN_BYTES(FIELD, VALUE, LEN) { msg_send.has_##FIELD = true; memzero(msg_send.FIELD.bytes, sizeof(msg_send.FIELD.bytes)); memcpy(msg_send.FIELD.bytes, VALUE, MIN(LEN, sizeof(msg_send.FIELD.bytes))); msg_send.FIELD.size = MIN(LEN, sizeof(msg_send.FIELD.bytes)); }
#define MSG_SEND(TYPE) _send_msg(iface_num, MessageType_MessageType_##TYPE, TYPE##_fields, &msg_send)
#define MSG_SEND_ASSIGN_VALUE(FIELD, VALUE) \
{ \
msg_send.has_##FIELD = true; \
msg_send.FIELD = VALUE; \
}
#define MSG_SEND_ASSIGN_STRING(FIELD, VALUE) \
{ \
msg_send.has_##FIELD = true; \
memzero(msg_send.FIELD, sizeof(msg_send.FIELD)); \
strncpy(msg_send.FIELD, VALUE, sizeof(msg_send.FIELD) - 1); \
}
#define MSG_SEND_ASSIGN_STRING_LEN(FIELD, VALUE, LEN) \
{ \
msg_send.has_##FIELD = true; \
memzero(msg_send.FIELD, sizeof(msg_send.FIELD)); \
strncpy(msg_send.FIELD, VALUE, MIN(LEN, sizeof(msg_send.FIELD) - 1)); \
}
#define MSG_SEND_ASSIGN_BYTES(FIELD, VALUE, LEN) \
{ \
msg_send.has_##FIELD = true; \
memzero(msg_send.FIELD.bytes, sizeof(msg_send.FIELD.bytes)); \
memcpy(msg_send.FIELD.bytes, VALUE, \
MIN(LEN, sizeof(msg_send.FIELD.bytes))); \
msg_send.FIELD.size = MIN(LEN, sizeof(msg_send.FIELD.bytes)); \
}
#define MSG_SEND(TYPE) \
_send_msg(iface_num, MessageType_MessageType_##TYPE, TYPE##_fields, &msg_send)
typedef struct {
uint8_t iface_num;
@ -160,8 +189,7 @@ typedef struct {
} usb_read_state;
/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */
static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
{
static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count) {
usb_read_state *state = (usb_read_state *)(stream->state);
size_t read = 0;
@ -178,10 +206,12 @@ static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
return true;
} else {
// append data that fits
memcpy(buf + read, state->buf + state->packet_pos, USB_PACKET_SIZE - state->packet_pos);
memcpy(buf + read, state->buf + state->packet_pos,
USB_PACKET_SIZE - state->packet_pos);
read += USB_PACKET_SIZE - state->packet_pos;
// read next packet
int r = usb_webusb_read_blocking(state->iface_num, state->buf, USB_PACKET_SIZE, USB_TIMEOUT);
int r = usb_webusb_read_blocking(state->iface_num, state->buf,
USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
// prepare next packet
state->packet_index++;
@ -192,26 +222,19 @@ static bool _usb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
return true;
}
static void _usb_read_flush(usb_read_state *state)
{
(void)state;
}
static void _usb_read_flush(usb_read_state *state) { (void)state; }
static secbool _recv_msg(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const pb_field_t fields[], void *msg)
{
usb_read_state state = {
.iface_num = iface_num,
static secbool _recv_msg(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const pb_field_t fields[], void *msg) {
usb_read_state state = {.iface_num = iface_num,
.packet_index = 0,
.packet_pos = MSG_HEADER1_LEN,
.buf = buf
};
.buf = buf};
pb_istream_t stream = {
.callback = &_usb_read,
pb_istream_t stream = {.callback = &_usb_read,
.state = &state,
.bytes_left = msg_size,
.errmsg = NULL
};
.errmsg = NULL};
if (false == pb_decode_noinit(&stream, fields, msg)) {
return secfalse;
@ -223,19 +246,21 @@ static secbool _recv_msg(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, con
}
#define MSG_RECV_INIT(TYPE) TYPE msg_recv = TYPE##_init_default
#define MSG_RECV_CALLBACK(FIELD, CALLBACK) { msg_recv.FIELD.funcs.decode = &CALLBACK; }
#define MSG_RECV(TYPE) _recv_msg(iface_num, msg_size, buf, TYPE##_fields, &msg_recv)
#define MSG_RECV_CALLBACK(FIELD, CALLBACK) \
{ msg_recv.FIELD.funcs.decode = &CALLBACK; }
#define MSG_RECV(TYPE) \
_recv_msg(iface_num, msg_size, buf, TYPE##_fields, &msg_recv)
void send_user_abort(uint8_t iface_num, const char *msg)
{
void send_user_abort(uint8_t iface_num, const char *msg) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ActionCancelled);
MSG_SEND_ASSIGN_STRING(message, msg);
MSG_SEND(Failure);
}
static void send_msg_features(uint8_t iface_num, const vendor_header * const vhdr, const image_header * const hdr)
{
static void send_msg_features(uint8_t iface_num,
const vendor_header *const vhdr,
const image_header *const hdr) {
MSG_SEND_INIT(Features);
MSG_SEND_ASSIGN_STRING(vendor, "trezor.io");
MSG_SEND_ASSIGN_VALUE(major_version, VERSION_MAJOR);
@ -258,22 +283,23 @@ static void send_msg_features(uint8_t iface_num, const vendor_header * const vhd
MSG_SEND(Features);
}
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr)
{
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const vendor_header *const vhdr,
const image_header *const hdr) {
MSG_RECV_INIT(Initialize);
MSG_RECV(Initialize);
send_msg_features(iface_num, vhdr, hdr);
}
void process_msg_GetFeatures(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr)
{
void process_msg_GetFeatures(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const vendor_header *const vhdr,
const image_header *const hdr) {
MSG_RECV_INIT(GetFeatures);
MSG_RECV(GetFeatures);
send_msg_features(iface_num, vhdr, hdr);
}
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) {
MSG_RECV_INIT(Ping);
MSG_RECV(Ping);
@ -284,8 +310,8 @@ void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
static uint32_t firmware_remaining, firmware_block, chunk_requested;
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf) {
firmware_remaining = 0;
firmware_block = 0;
chunk_requested = 0;
@ -294,9 +320,13 @@ void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
MSG_RECV(FirmwareErase);
firmware_remaining = msg_recv.has_length ? msg_recv.length : 0;
if ((firmware_remaining > 0) && ((firmware_remaining % sizeof(uint32_t)) == 0) && (firmware_remaining <= (FIRMWARE_SECTORS_COUNT * IMAGE_CHUNK_SIZE))) {
if ((firmware_remaining > 0) &&
((firmware_remaining % sizeof(uint32_t)) == 0) &&
(firmware_remaining <= (FIRMWARE_SECTORS_COUNT * IMAGE_CHUNK_SIZE))) {
// request new firmware
chunk_requested = (firmware_remaining > IMAGE_CHUNK_SIZE) ? IMAGE_CHUNK_SIZE : firmware_remaining;
chunk_requested = (firmware_remaining > IMAGE_CHUNK_SIZE)
? IMAGE_CHUNK_SIZE
: firmware_remaining;
MSG_SEND_INIT(FirmwareRequest);
MSG_SEND_ASSIGN_VALUE(offset, 0);
MSG_SEND_ASSIGN_VALUE(length, chunk_requested);
@ -312,11 +342,11 @@ void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
static uint32_t chunk_size = 0;
// SRAM is unused, so we can use it for chunk buffer
uint8_t * const chunk_buffer = (uint8_t * const)0x20000000;
uint8_t *const chunk_buffer = (uint8_t *const)0x20000000;
/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */
static bool _read_payload(pb_istream_t *stream, const pb_field_t *field, void **arg)
{
static bool _read_payload(pb_istream_t *stream, const pb_field_t *field,
void **arg) {
#define BUFSIZE 32768
if (stream->bytes_left > IMAGE_CHUNK_SIZE) {
@ -333,10 +363,14 @@ static bool _read_payload(pb_istream_t *stream, const pb_field_t *field, void **
while (stream->bytes_left) {
// update loader but skip first block
if (firmware_block > 0) {
ui_screen_install_progress_upload(250 + 750 * (firmware_block * IMAGE_CHUNK_SIZE + chunk_written) / (firmware_block * IMAGE_CHUNK_SIZE + firmware_remaining));
ui_screen_install_progress_upload(
250 + 750 * (firmware_block * IMAGE_CHUNK_SIZE + chunk_written) /
(firmware_block * IMAGE_CHUNK_SIZE + firmware_remaining));
}
// read data
if (!pb_read(stream, (pb_byte_t *)(chunk_buffer + chunk_written), (stream->bytes_left > BUFSIZE) ? BUFSIZE : stream->bytes_left)) {
if (!pb_read(
stream, (pb_byte_t *)(chunk_buffer + chunk_written),
(stream->bytes_left > BUFSIZE) ? BUFSIZE : stream->bytes_left)) {
chunk_size = 0;
return false;
}
@ -346,10 +380,10 @@ static bool _read_payload(pb_istream_t *stream, const pb_field_t *field, void **
return true;
}
secbool load_vendor_header_keys(const uint8_t * const data, vendor_header * const vhdr);
secbool load_vendor_header_keys(const uint8_t *const data,
vendor_header *const vhdr);
static int version_compare(uint32_t vera, uint32_t verb)
{
static int version_compare(uint32_t vera, uint32_t verb) {
int a, b;
a = vera & 0xFF;
b = verb & 0xFF;
@ -365,15 +399,23 @@ static int version_compare(uint32_t vera, uint32_t verb)
return a - b;
}
static void detect_installation(vendor_header *current_vhdr, image_header *current_hdr, const vendor_header * const new_vhdr, const image_header * const new_hdr, secbool *is_new, secbool *is_upgrade)
{
static void detect_installation(vendor_header *current_vhdr,
image_header *current_hdr,
const vendor_header *const new_vhdr,
const image_header *const new_hdr,
secbool *is_new, secbool *is_upgrade) {
*is_new = secfalse;
*is_upgrade = secfalse;
if (sectrue != load_vendor_header_keys((const uint8_t *)FIRMWARE_START, current_vhdr)) {
if (sectrue !=
load_vendor_header_keys((const uint8_t *)FIRMWARE_START, current_vhdr)) {
*is_new = sectrue;
return;
}
if (sectrue != load_image_header((const uint8_t *)FIRMWARE_START + current_vhdr->hdrlen, FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, current_vhdr->vsig_m, current_vhdr->vsig_n, current_vhdr->vpub, current_hdr)) {
if (sectrue !=
load_image_header((const uint8_t *)FIRMWARE_START + current_vhdr->hdrlen,
FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE,
current_vhdr->vsig_m, current_vhdr->vsig_n,
current_vhdr->vpub, current_hdr)) {
*is_new = sectrue;
return;
}
@ -391,8 +433,8 @@ static void detect_installation(vendor_header *current_vhdr, image_header *curre
static int firmware_upload_chunk_retry = FIRMWARE_UPLOAD_CHUNK_RETRY_COUNT;
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf) {
MSG_RECV_INIT(FirmwareUpload);
MSG_RECV_CALLBACK(payload, _read_payload);
secbool r = MSG_RECV(FirmwareUpload);
@ -417,7 +459,10 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
MSG_SEND(Failure);
return -2;
}
if (sectrue != load_image_header(chunk_buffer + vhdr.hdrlen, FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr)) {
if (sectrue != load_image_header(chunk_buffer + vhdr.hdrlen,
FIRMWARE_IMAGE_MAGIC,
FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m,
vhdr.vsig_n, vhdr.vpub, &hdr)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Invalid firmware header");
@ -428,14 +473,14 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
vendor_header current_vhdr;
image_header current_hdr;
secbool is_new = secfalse, is_upgrade = secfalse;
detect_installation(&current_vhdr, &current_hdr, &vhdr, &hdr, &is_new, &is_upgrade);
detect_installation(&current_vhdr, &current_hdr, &vhdr, &hdr, &is_new,
&is_upgrade);
int response = INPUT_CANCEL;
if (sectrue == is_new) {
// new installation - auto confirm
response = INPUT_CONFIRM;
} else
if (sectrue == is_upgrade) {
} else if (sectrue == is_upgrade) {
// firmware upgrade
ui_fadeout();
ui_screen_install_confirm_upgrade(&vhdr, &hdr);
@ -463,9 +508,12 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
// if firmware is not upgrade, erase storage
if (sectrue != is_upgrade) {
ensure(flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL), NULL);
ensure(flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL),
NULL);
}
ensure(flash_erase_sectors(FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT, ui_screen_install_progress_erase), NULL);
ensure(flash_erase_sectors(FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT,
ui_screen_install_progress_erase),
NULL);
firstskip = IMAGE_HEADER_SIZE + vhdr.hdrlen;
}
@ -479,8 +527,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
return -5;
}
if (sectrue != check_single_hash(hdr.hashes + firmware_block * 32, chunk_buffer + firstskip, chunk_size - firstskip)) {
if (sectrue != check_single_hash(hdr.hashes + firmware_block * 32,
chunk_buffer + firstskip,
chunk_size - firstskip)) {
if (firmware_upload_chunk_retry > 0) {
--firmware_upload_chunk_retry;
MSG_SEND_INIT(FirmwareRequest);
@ -499,9 +548,11 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
ensure(flash_unlock_write(), NULL);
const uint32_t * const src = (const uint32_t * const)chunk_buffer;
const uint32_t *const src = (const uint32_t *const)chunk_buffer;
for (int i = 0; i < chunk_size / sizeof(uint32_t); i++) {
ensure(flash_write_word(FIRMWARE_SECTORS[firmware_block], i * sizeof(uint32_t), src[i]), NULL);
ensure(flash_write_word(FIRMWARE_SECTORS[firmware_block],
i * sizeof(uint32_t), src[i]),
NULL);
}
ensure(flash_lock_write(), NULL);
@ -511,7 +562,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
firmware_upload_chunk_retry = FIRMWARE_UPLOAD_CHUNK_RETRY_COUNT;
if (firmware_remaining > 0) {
chunk_requested = (firmware_remaining > IMAGE_CHUNK_SIZE) ? IMAGE_CHUNK_SIZE : firmware_remaining;
chunk_requested = (firmware_remaining > IMAGE_CHUNK_SIZE)
? IMAGE_CHUNK_SIZE
: firmware_remaining;
MSG_SEND_INIT(FirmwareRequest);
MSG_SEND_ASSIGN_VALUE(offset, firmware_block * IMAGE_CHUNK_SIZE);
MSG_SEND_ASSIGN_VALUE(length, chunk_requested);
@ -523,8 +576,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
return (int)firmware_remaining;
}
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) {
static const uint8_t sectors[] = {
FLASH_SECTOR_STORAGE_1,
FLASH_SECTOR_STORAGE_2,
@ -547,7 +599,8 @@ int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
22,
FLASH_SECTOR_FIRMWARE_EXTRA_END,
};
if (sectrue != flash_erase_sectors(sectors, sizeof(sectors), ui_screen_wipe_progress)) {
if (sectrue !=
flash_erase_sectors(sectors, sizeof(sectors), ui_screen_wipe_progress)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");
@ -560,18 +613,21 @@ int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
}
}
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) {
// consume remaining message
int remaining_chunks = 0;
if (msg_size > (USB_PACKET_SIZE - MSG_HEADER1_LEN)) {
// calculate how many blocks need to be read to drain the message (rounded up to not leave any behind)
remaining_chunks = (msg_size - (USB_PACKET_SIZE - MSG_HEADER1_LEN) + ((USB_PACKET_SIZE - MSG_HEADER2_LEN) - 1)) / (USB_PACKET_SIZE - MSG_HEADER2_LEN);
// calculate how many blocks need to be read to drain the message (rounded
// up to not leave any behind)
remaining_chunks = (msg_size - (USB_PACKET_SIZE - MSG_HEADER1_LEN) +
((USB_PACKET_SIZE - MSG_HEADER2_LEN) - 1)) /
(USB_PACKET_SIZE - MSG_HEADER2_LEN);
}
for (int i = 0; i < remaining_chunks; i++) {
int r = usb_webusb_read_blocking(iface_num, buf, USB_PACKET_SIZE, USB_TIMEOUT);
int r =
usb_webusb_read_blocking(iface_num, buf, USB_PACKET_SIZE, USB_TIMEOUT);
ensure(sectrue * (r == USB_PACKET_SIZE), NULL);
}

@ -29,15 +29,22 @@
#define FIRMWARE_UPLOAD_CHUNK_RETRY_COUNT 2
secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size);
secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id,
uint32_t *msg_size);
void send_user_abort(uint8_t iface_num, const char *msg);
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr);
void process_msg_GetFeatures(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr);
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const vendor_header *const vhdr,
const image_header *const hdr);
void process_msg_GetFeatures(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
const vendor_header *const vhdr,
const image_header *const hdr);
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf);
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
uint8_t *buf);
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);

@ -2,7 +2,9 @@
#define VERSION_MINOR 0
#define VERSION_PATCH 3
#define VERSION_BUILD 0
#define VERSION_UINT32 (VERSION_MAJOR | (VERSION_MINOR << 8) | (VERSION_PATCH << 16) | (VERSION_BUILD << 24))
#define VERSION_UINT32 \
(VERSION_MAJOR | (VERSION_MINOR << 8) | (VERSION_PATCH << 16) | \
(VERSION_BUILD << 24))
#define FIX_VERSION_MAJOR 2
#define FIX_VERSION_MINOR 0

@ -19,21 +19,22 @@
#include <string.h>
#include "py/runtime.h"
#include "py/mphal.h"
#include "py/objstr.h"
#include "py/runtime.h"
#if MICROPY_PY_TREZORCONFIG
#include "embed/extmod/trezorobj.h"
#include "storage.h"
#include "common.h"
#include "memzero.h"
#include "storage.h"
STATIC mp_obj_t ui_wait_callback = mp_const_none;
STATIC secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress, const char* message) {
STATIC secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress,
const char *message) {
if (mp_obj_is_callable(ui_wait_callback)) {
mp_obj_t args[3];
args[0] = mp_obj_new_int(wait);
@ -61,7 +62,8 @@ STATIC mp_obj_t mod_trezorconfig_init(size_t n_args, const mp_obj_t *args) {
memzero(HW_ENTROPY_DATA, sizeof(HW_ENTROPY_DATA));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_init_obj, 0, 1, mod_trezorconfig_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_init_obj, 0, 1,
mod_trezorconfig_init);
/// def check_pin(pin: int) -> bool:
/// '''
@ -74,7 +76,8 @@ STATIC mp_obj_t mod_trezorconfig_check_pin(mp_obj_t pin) {
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorconfig_check_pin_obj, mod_trezorconfig_check_pin);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorconfig_check_pin_obj,
mod_trezorconfig_check_pin);
/// def unlock(pin: int) -> bool:
/// '''
@ -88,7 +91,8 @@ STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin) {
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorconfig_unlock_obj, mod_trezorconfig_unlock);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorconfig_unlock_obj,
mod_trezorconfig_unlock);
/// def lock() -> None:
/// '''
@ -98,7 +102,8 @@ STATIC mp_obj_t mod_trezorconfig_lock(void) {
storage_lock();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_lock_obj, mod_trezorconfig_lock);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_lock_obj,
mod_trezorconfig_lock);
/// def has_pin() -> bool:
/// '''
@ -110,7 +115,8 @@ STATIC mp_obj_t mod_trezorconfig_has_pin(void) {
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_has_pin_obj, mod_trezorconfig_has_pin);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_has_pin_obj,
mod_trezorconfig_has_pin);
/// def get_pin_rem() -> int:
/// '''
@ -119,7 +125,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_has_pin_obj, mod_trezorconfig_
STATIC mp_obj_t mod_trezorconfig_get_pin_rem(void) {
return mp_obj_new_int_from_uint(storage_get_pin_rem());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_get_pin_rem_obj, mod_trezorconfig_get_pin_rem);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_get_pin_rem_obj,
mod_trezorconfig_get_pin_rem);
/// def change_pin(pin: int, newpin: int) -> bool:
/// '''
@ -133,12 +140,14 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(mp_obj_t pin, mp_obj_t newpin) {
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorconfig_change_pin_obj, mod_trezorconfig_change_pin);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorconfig_change_pin_obj,
mod_trezorconfig_change_pin);
/// def get(app: int, key: int, public: bool=False) -> bytes:
/// '''
/// Gets the value of the given key for the given app (or None if not set).
/// Raises a RuntimeError if decryption or authentication of the stored value fails.
/// Raises a RuntimeError if decryption or authentication of the stored
/// value fails.
/// '''
STATIC mp_obj_t mod_trezorconfig_get(size_t n_args, const mp_obj_t *args) {
uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F;
@ -162,7 +171,8 @@ STATIC mp_obj_t mod_trezorconfig_get(size_t n_args, const mp_obj_t *args) {
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_get_obj, 2, 3, mod_trezorconfig_get);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_get_obj, 2, 3,
mod_trezorconfig_get);
/// def set(app: int, key: int, value: bytes, public: bool=False) -> None:
/// '''
@ -182,7 +192,8 @@ STATIC mp_obj_t mod_trezorconfig_set(size_t n_args, const mp_obj_t *args) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_obj, 3, 4, mod_trezorconfig_set);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_obj, 3, 4,
mod_trezorconfig_set);
/// def delete(app: int, key: int, public: bool=False) -> bool:
/// '''
@ -200,13 +211,16 @@ STATIC mp_obj_t mod_trezorconfig_delete(size_t n_args, const mp_obj_t *args) {
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_delete_obj, 2, 3, mod_trezorconfig_delete);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_delete_obj, 2, 3,
mod_trezorconfig_delete);
/// def set_counter(app: int, key: int, count: int, writable_locked: bool=False) -> bool:
/// def set_counter(app: int, key: int, count: int, writable_locked: bool=False)
/// -> bool:
/// '''
/// Sets the given key of the given app as a counter with the given value.
/// '''
STATIC mp_obj_t mod_trezorconfig_set_counter(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorconfig_set_counter(size_t n_args,
const mp_obj_t *args) {
uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F;
uint8_t key = trezor_obj_get_uint8(args[1]);
if (n_args > 3 && args[3] == mp_const_true) {
@ -227,13 +241,16 @@ STATIC mp_obj_t mod_trezorconfig_set_counter(size_t n_args, const mp_obj_t *args
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_counter_obj, 3, 4, mod_trezorconfig_set_counter);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_set_counter_obj, 3,
4, mod_trezorconfig_set_counter);
/// def next_counter(app: int, key: int, writable_locked: bool=False) -> bool:
/// '''
/// Increments the counter stored under the given key of the given app and returns the new value.
/// Increments the counter stored under the given key of the given app and
/// returns the new value.
/// '''
STATIC mp_obj_t mod_trezorconfig_next_counter(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorconfig_next_counter(size_t n_args,
const mp_obj_t *args) {
uint8_t app = trezor_obj_get_uint8(args[0]) & 0x3F;
uint8_t key = trezor_obj_get_uint8(args[1]);
if (n_args > 2 && args[2] == mp_const_true) {
@ -248,7 +265,8 @@ STATIC mp_obj_t mod_trezorconfig_next_counter(size_t n_args, const mp_obj_t *arg
}
return mp_obj_new_int_from_uint(count);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_next_counter_obj, 2, 3, mod_trezorconfig_next_counter);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_next_counter_obj, 2,
3, mod_trezorconfig_next_counter);
/// def wipe() -> None:
/// '''
@ -258,29 +276,36 @@ STATIC mp_obj_t mod_trezorconfig_wipe(void) {
storage_wipe();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_wipe_obj, mod_trezorconfig_wipe);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_wipe_obj,
mod_trezorconfig_wipe);
STATIC const mp_rom_map_elem_t mp_module_trezorconfig_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorconfig) },
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&mod_trezorconfig_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_check_pin), MP_ROM_PTR(&mod_trezorconfig_check_pin_obj) },
{ MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&mod_trezorconfig_unlock_obj) },
{ MP_ROM_QSTR(MP_QSTR_lock), MP_ROM_PTR(&mod_trezorconfig_lock_obj) },
{ MP_ROM_QSTR(MP_QSTR_has_pin), MP_ROM_PTR(&mod_trezorconfig_has_pin_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_pin_rem), MP_ROM_PTR(&mod_trezorconfig_get_pin_rem_obj) },
{ MP_ROM_QSTR(MP_QSTR_change_pin), MP_ROM_PTR(&mod_trezorconfig_change_pin_obj) },
{ MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&mod_trezorconfig_get_obj) },
{ MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mod_trezorconfig_set_obj) },
{ MP_ROM_QSTR(MP_QSTR_delete), MP_ROM_PTR(&mod_trezorconfig_delete_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_counter), MP_ROM_PTR(&mod_trezorconfig_set_counter_obj) },
{ MP_ROM_QSTR(MP_QSTR_next_counter), MP_ROM_PTR(&mod_trezorconfig_next_counter_obj) },
{ MP_ROM_QSTR(MP_QSTR_wipe), MP_ROM_PTR(&mod_trezorconfig_wipe_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorconfig)},
{MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&mod_trezorconfig_init_obj)},
{MP_ROM_QSTR(MP_QSTR_check_pin),
MP_ROM_PTR(&mod_trezorconfig_check_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&mod_trezorconfig_unlock_obj)},
{MP_ROM_QSTR(MP_QSTR_lock), MP_ROM_PTR(&mod_trezorconfig_lock_obj)},
{MP_ROM_QSTR(MP_QSTR_has_pin), MP_ROM_PTR(&mod_trezorconfig_has_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_get_pin_rem),
MP_ROM_PTR(&mod_trezorconfig_get_pin_rem_obj)},
{MP_ROM_QSTR(MP_QSTR_change_pin),
MP_ROM_PTR(&mod_trezorconfig_change_pin_obj)},
{MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&mod_trezorconfig_get_obj)},
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mod_trezorconfig_set_obj)},
{MP_ROM_QSTR(MP_QSTR_delete), MP_ROM_PTR(&mod_trezorconfig_delete_obj)},
{MP_ROM_QSTR(MP_QSTR_set_counter),
MP_ROM_PTR(&mod_trezorconfig_set_counter_obj)},
{MP_ROM_QSTR(MP_QSTR_next_counter),
MP_ROM_PTR(&mod_trezorconfig_next_counter_obj)},
{MP_ROM_QSTR(MP_QSTR_wipe), MP_ROM_PTR(&mod_trezorconfig_wipe_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorconfig_globals, mp_module_trezorconfig_globals_table);
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorconfig_globals,
mp_module_trezorconfig_globals_table);
const mp_obj_module_t mp_module_trezorconfig = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_trezorconfig_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mp_module_trezorconfig_globals,
};
#endif // MICROPY_PY_TREZORCONFIG

@ -27,13 +27,15 @@
#if TREZOR_MODEL == T
#define NORCOW_SECTOR_SIZE (64*1024)
#define NORCOW_SECTORS {FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2}
#define NORCOW_SECTOR_SIZE (64 * 1024)
#define NORCOW_SECTORS \
{ FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2 }
#elif TREZOR_MODEL == 1
#define NORCOW_SECTOR_SIZE (16*1024)
#define NORCOW_SECTORS {2, 3}
#define NORCOW_SECTOR_SIZE (16 * 1024)
#define NORCOW_SECTORS \
{ 2, 3 }
#else

@ -58,15 +58,12 @@
#include "crc.h"
static const uint32_t crc32tab[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190,
0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344,
0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278,
0xbdbdf21c
};
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4,
0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c};
/* crc is previous value for incremental computation, 0xffffffff initially */
uint32_t checksum_crc32(const uint8_t *data, uint32_t length, uint32_t crc)
{
uint32_t checksum_crc32(const uint8_t *data, uint32_t length, uint32_t crc) {
for (uint32_t i = 0; i < length; ++i) {
crc ^= data[i];
crc = crc32tab[crc & 0x0f] ^ (crc >> 4);
@ -74,5 +71,5 @@ uint32_t checksum_crc32(const uint8_t *data, uint32_t length, uint32_t crc)
}
// return value suitable for passing in next time, for final value invert it
return crc/* ^ 0xffffffff*/;
return crc /* ^ 0xffffffff*/;
}

@ -48,7 +48,9 @@ typedef struct _mp_obj_AES_t {
/// '''
/// Initialize AES context.
/// '''
STATIC mp_obj_t mod_trezorcrypto_AES_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_AES_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 2, 3, false);
mp_obj_AES_t *o = m_new_obj(mp_obj_AES_t);
o->base.type = type;
@ -59,13 +61,15 @@ STATIC mp_obj_t mod_trezorcrypto_AES_make_new(const mp_obj_type_t *type, size_t
mp_buffer_info_t key;
mp_get_buffer_raise(args[1], &key, MP_BUFFER_READ);
if (key.len != 16 && key.len != 24 && key.len != 32) {
mp_raise_ValueError("Invalid length of key (has to be 128, 192 or 256 bits)");
mp_raise_ValueError(
"Invalid length of key (has to be 128, 192 or 256 bits)");
}
if (n_args > 2) {
mp_buffer_info_t iv;
mp_get_buffer_raise(args[2], &iv, MP_BUFFER_READ);
if (iv.len != AES_BLOCK_SIZE) {
mp_raise_ValueError("Invalid length of initialization vector (has to be 128 bits)");
mp_raise_ValueError(
"Invalid length of initialization vector (has to be 128 bits)");
}
memcpy(o->iv, iv.buf, AES_BLOCK_SIZE);
} else {
@ -103,9 +107,11 @@ static mp_obj_t aes_update(mp_obj_t self, mp_obj_t data, bool encrypt) {
mp_raise_ValueError("Invalid data length");
}
if (encrypt) {
aes_ecb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, &(o->encrypt_ctx));
aes_ecb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len,
&(o->encrypt_ctx));
} else {
aes_ecb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, &(o->decrypt_ctx));
aes_ecb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len,
&(o->decrypt_ctx));
}
break;
case CBC:
@ -113,23 +119,29 @@ static mp_obj_t aes_update(mp_obj_t self, mp_obj_t data, bool encrypt) {
mp_raise_ValueError("Invalid data length");
}
if (encrypt) {
aes_cbc_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx));
aes_cbc_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv,
&(o->encrypt_ctx));
} else {
aes_cbc_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->decrypt_ctx));
aes_cbc_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv,
&(o->decrypt_ctx));
}
break;
case CFB:
if (encrypt) {
aes_cfb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx));
aes_cfb_encrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv,
&(o->encrypt_ctx));
} else {
aes_cfb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx)); // decrypt uses encrypt_ctx
aes_cfb_decrypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv,
&(o->encrypt_ctx)); // decrypt uses encrypt_ctx
}
break;
case OFB: // (encrypt == decrypt)
aes_ofb_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, &(o->encrypt_ctx));
aes_ofb_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv,
&(o->encrypt_ctx));
break;
case CTR: // (encrypt == decrypt)
aes_ctr_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv, aes_ctr_cbuf_inc, &(o->encrypt_ctx));
aes_ctr_crypt(buf.buf, (uint8_t *)vstr.buf, buf.len, o->iv,
aes_ctr_cbuf_inc, &(o->encrypt_ctx));
break;
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
@ -142,7 +154,8 @@ static mp_obj_t aes_update(mp_obj_t self, mp_obj_t data, bool encrypt) {
STATIC mp_obj_t mod_trezorcrypto_AES_encrypt(mp_obj_t self, mp_obj_t data) {
return aes_update(self, data, true);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_encrypt_obj, mod_trezorcrypto_AES_encrypt);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_encrypt_obj,
mod_trezorcrypto_AES_encrypt);
/// def decrypt(self, data: bytes) -> bytes:
/// '''
@ -151,7 +164,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_encrypt_obj, mod_trezorcry
STATIC mp_obj_t mod_trezorcrypto_AES_decrypt(mp_obj_t self, mp_obj_t data) {
return aes_update(self, data, false);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_decrypt_obj, mod_trezorcrypto_AES_decrypt);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_AES_decrypt_obj,
mod_trezorcrypto_AES_decrypt);
STATIC mp_obj_t mod_trezorcrypto_AES___del__(mp_obj_t self) {
mp_obj_AES_t *o = MP_OBJ_TO_PTR(self);
@ -160,23 +174,28 @@ STATIC mp_obj_t mod_trezorcrypto_AES___del__(mp_obj_t self) {
memzero(o->iv, AES_BLOCK_SIZE);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_AES___del___obj, mod_trezorcrypto_AES___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_AES___del___obj,
mod_trezorcrypto_AES___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_AES_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_encrypt), MP_ROM_PTR(&mod_trezorcrypto_AES_encrypt_obj) },
{ MP_ROM_QSTR(MP_QSTR_decrypt), MP_ROM_PTR(&mod_trezorcrypto_AES_decrypt_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_AES___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_ECB), MP_OBJ_NEW_SMALL_INT(ECB) },
{ MP_ROM_QSTR(MP_QSTR_CBC), MP_OBJ_NEW_SMALL_INT(CBC) },
{ MP_ROM_QSTR(MP_QSTR_CFB), MP_OBJ_NEW_SMALL_INT(CFB) },
{ MP_ROM_QSTR(MP_QSTR_OFB), MP_OBJ_NEW_SMALL_INT(OFB) },
{ MP_ROM_QSTR(MP_QSTR_CTR), MP_OBJ_NEW_SMALL_INT(CTR) },
{MP_ROM_QSTR(MP_QSTR_encrypt),
MP_ROM_PTR(&mod_trezorcrypto_AES_encrypt_obj)},
{MP_ROM_QSTR(MP_QSTR_decrypt),
MP_ROM_PTR(&mod_trezorcrypto_AES_decrypt_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_AES___del___obj)},
{MP_ROM_QSTR(MP_QSTR_ECB), MP_OBJ_NEW_SMALL_INT(ECB)},
{MP_ROM_QSTR(MP_QSTR_CBC), MP_OBJ_NEW_SMALL_INT(CBC)},
{MP_ROM_QSTR(MP_QSTR_CFB), MP_OBJ_NEW_SMALL_INT(CFB)},
{MP_ROM_QSTR(MP_QSTR_OFB), MP_OBJ_NEW_SMALL_INT(OFB)},
{MP_ROM_QSTR(MP_QSTR_CTR), MP_OBJ_NEW_SMALL_INT(CTR)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_AES_locals_dict, mod_trezorcrypto_AES_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_AES_locals_dict,
mod_trezorcrypto_AES_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_AES_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_AES,
.make_new = mod_trezorcrypto_AES_make_new,
.locals_dict = (void*)&mod_trezorcrypto_AES_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_AES_locals_dict,
};

@ -54,19 +54,35 @@ STATIC const mp_obj_type_t mod_trezorcrypto_HDNode_type;
/// curve_name: str = None) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_depth, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_fingerprint, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_child_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_chain_code, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_private_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_public_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_curve_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{MP_QSTR_depth,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_none}},
{MP_QSTR_fingerprint,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_none}},
{MP_QSTR_child_num,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_none}},
{MP_QSTR_chain_code,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_private_key,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_public_key,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_curve_name,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
mp_buffer_info_t chain_code;
mp_buffer_info_t private_key;
@ -132,7 +148,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_make_new(const mp_obj_type_t *type, size
/// '''
/// Derive a BIP0032 child node in place.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_derive(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_derive(size_t n_args,
const mp_obj_t *args) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(args[0]);
uint32_t i = trezor_obj_get_uint(args[1]);
uint32_t fp = hdnode_fingerprint(&o->hdnode);
@ -142,7 +159,12 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_derive(size_t n_args, const mp_obj_t *ar
if (public) {
res = hdnode_public_ckd(&o->hdnode, i);
} else {
if (0 == memcmp(o->hdnode.private_key, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) {
if (0 ==
memcmp(
o->hdnode.private_key,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
32)) {
memzero(&o->hdnode, sizeof(o->hdnode));
mp_raise_ValueError("Failed to derive, private key not set");
}
@ -156,20 +178,27 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_derive(size_t n_args, const mp_obj_t *ar
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_HDNode_derive_obj, 2, 3, mod_trezorcrypto_HDNode_derive);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_HDNode_derive_obj,
2, 3,
mod_trezorcrypto_HDNode_derive);
/// def derive_cardano(self, index: int) -> None:
/// '''
/// Derive a BIP0032 child node in place using Cardano algorithm.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_cardano(mp_obj_t self, mp_obj_t index) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_cardano(mp_obj_t self,
mp_obj_t index) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
uint32_t i = mp_obj_get_int_truncated(index);
uint32_t fp = hdnode_fingerprint(&o->hdnode);
int res;
// same as in derive
if (0 == memcmp(o->hdnode.private_key, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) {
if (0 ==
memcmp(o->hdnode.private_key,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
32)) {
memzero(&o->hdnode, sizeof(o->hdnode));
mp_raise_ValueError("Failed to derive, private key not set");
}
@ -183,13 +212,16 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_cardano(mp_obj_t self, mp_obj_t i
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_derive_cardano_obj, mod_trezorcrypto_HDNode_derive_cardano);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_derive_cardano_obj,
mod_trezorcrypto_HDNode_derive_cardano);
/// def derive_path(self, path: List[int]) -> None:
/// '''
/// Go through a list of indexes and iteratively derive a child node in place.
/// Go through a list of indexes and iteratively derive a child node in
/// place.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_path(mp_obj_t self, mp_obj_t path) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_path(mp_obj_t self,
mp_obj_t path) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
// get path objects and length
@ -216,43 +248,52 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_derive_path(mp_obj_t self, mp_obj_t path
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_derive_path_obj, mod_trezorcrypto_HDNode_derive_path);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_derive_path_obj,
mod_trezorcrypto_HDNode_derive_path);
STATIC mp_obj_t serialize_public_private(mp_obj_t self, bool use_public, uint32_t version) {
STATIC mp_obj_t serialize_public_private(mp_obj_t self, bool use_public,
uint32_t version) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
char xpub[XPUB_MAXLEN] = {0};
int written;
if (use_public) {
hdnode_fill_public_key(&o->hdnode);
written = hdnode_serialize_public(&o->hdnode, o->fingerprint, version, xpub, XPUB_MAXLEN);
written = hdnode_serialize_public(&o->hdnode, o->fingerprint, version, xpub,
XPUB_MAXLEN);
} else {
written = hdnode_serialize_private(&o->hdnode, o->fingerprint, version, xpub, XPUB_MAXLEN);
written = hdnode_serialize_private(&o->hdnode, o->fingerprint, version,
xpub, XPUB_MAXLEN);
}
if (written <= 0) {
mp_raise_ValueError("Failed to serialize");
}
return mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)xpub, written - 1); // written includes 0 at the end
return mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)xpub,
written - 1); // written includes 0 at the end
}
/// def serialize_public(self, version: int) -> str:
/// '''
/// Serialize the public info from HD node to base58 string.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_serialize_public(mp_obj_t self, mp_obj_t version) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_serialize_public(mp_obj_t self,
mp_obj_t version) {
uint32_t ver = trezor_obj_get_uint(version);
return serialize_public_private(self, true, ver);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_serialize_public_obj, mod_trezorcrypto_HDNode_serialize_public);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_serialize_public_obj,
mod_trezorcrypto_HDNode_serialize_public);
/// def serialize_private(self, version: int) -> str:
/// '''
/// Serialize the private info HD node to base58 string.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_serialize_private(mp_obj_t self, mp_obj_t version) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_serialize_private(mp_obj_t self,
mp_obj_t version) {
uint32_t ver = trezor_obj_get_uint(version);
return serialize_public_private(self, false, ver);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_serialize_private_obj, mod_trezorcrypto_HDNode_serialize_private);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_serialize_private_obj,
mod_trezorcrypto_HDNode_serialize_private);
/// def clone(self) -> HDNode:
/// '''
@ -266,7 +307,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_clone(mp_obj_t self) {
copy->fingerprint = o->fingerprint;
return MP_OBJ_FROM_PTR(copy);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_clone_obj, mod_trezorcrypto_HDNode_clone);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_clone_obj,
mod_trezorcrypto_HDNode_clone);
/// def depth(self) -> int:
/// '''
@ -276,7 +318,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_depth(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_int_from_uint(o->hdnode.depth);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_depth_obj, mod_trezorcrypto_HDNode_depth);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_depth_obj,
mod_trezorcrypto_HDNode_depth);
/// def fingerprint(self) -> int:
/// '''
@ -286,7 +329,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_fingerprint(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_int_from_uint(o->fingerprint);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_fingerprint_obj, mod_trezorcrypto_HDNode_fingerprint);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_fingerprint_obj,
mod_trezorcrypto_HDNode_fingerprint);
/// def child_num(self) -> int:
/// '''
@ -296,7 +340,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_child_num(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_int_from_uint(o->hdnode.child_num);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_child_num_obj, mod_trezorcrypto_HDNode_child_num);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_child_num_obj,
mod_trezorcrypto_HDNode_child_num);
/// def chain_code(self) -> bytes:
/// '''
@ -306,7 +351,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_chain_code(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_bytes(o->hdnode.chain_code, sizeof(o->hdnode.chain_code));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_chain_code_obj, mod_trezorcrypto_HDNode_chain_code);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_chain_code_obj,
mod_trezorcrypto_HDNode_chain_code);
/// def private_key(self) -> bytes:
/// '''
@ -316,7 +362,8 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_private_key(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_bytes(o->hdnode.private_key, sizeof(o->hdnode.private_key));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_private_key_obj, mod_trezorcrypto_HDNode_private_key);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_private_key_obj,
mod_trezorcrypto_HDNode_private_key);
/// def private_key_ext(self) -> bytes:
/// '''
@ -324,9 +371,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_private_key_obj, mod_tr
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_private_key_ext(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
return mp_obj_new_bytes(o->hdnode.private_key_extension, sizeof(o->hdnode.private_key_extension));
return mp_obj_new_bytes(o->hdnode.private_key_extension,
sizeof(o->hdnode.private_key_extension));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_private_key_ext_obj, mod_trezorcrypto_HDNode_private_key_ext);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_private_key_ext_obj,
mod_trezorcrypto_HDNode_private_key_ext);
/// def public_key(self) -> bytes:
/// '''
@ -337,28 +386,33 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_public_key(mp_obj_t self) {
hdnode_fill_public_key(&o->hdnode);
return mp_obj_new_bytes(o->hdnode.public_key, sizeof(o->hdnode.public_key));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_public_key_obj, mod_trezorcrypto_HDNode_public_key);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_public_key_obj,
mod_trezorcrypto_HDNode_public_key);
/// def address(self, version: int) -> str:
/// '''
/// Compute a base58-encoded address string from the HD node.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_address(mp_obj_t self, mp_obj_t version) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_address(mp_obj_t self,
mp_obj_t version) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
uint32_t v = trezor_obj_get_uint(version);
char address[ADDRESS_MAXLEN] = {0};
hdnode_get_address(&o->hdnode, v, address, ADDRESS_MAXLEN);
return mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)address, strlen(address));
return mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)address,
strlen(address));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_address_obj, mod_trezorcrypto_HDNode_address);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_address_obj,
mod_trezorcrypto_HDNode_address);
/// def nem_address(self, network: int) -> str:
/// '''
/// Compute a NEM address string from the HD node.
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_nem_address(mp_obj_t self, mp_obj_t network) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_nem_address(mp_obj_t self,
mp_obj_t network) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
uint8_t n = trezor_obj_get_uint8(network);
@ -367,15 +421,19 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_nem_address(mp_obj_t self, mp_obj_t netw
if (!hdnode_get_nem_address(&o->hdnode, n, address)) {
mp_raise_ValueError("Failed to compute a NEM address");
}
return mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)address, strlen(address));
return mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)address,
strlen(address));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_nem_address_obj, mod_trezorcrypto_HDNode_nem_address);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_HDNode_nem_address_obj,
mod_trezorcrypto_HDNode_nem_address);
/// def nem_encrypt(self, transfer_public_key: bytes, iv: bytes, salt: bytes, payload: bytes) -> bytes:
/// def nem_encrypt(self, transfer_public_key: bytes, iv: bytes, salt: bytes,
/// payload: bytes) -> bytes:
/// '''
/// Encrypts payload using the transfer's public key
/// '''
STATIC mp_obj_t mod_trezorcrypto_HDNode_nem_encrypt(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_HDNode_nem_encrypt(size_t n_args,
const mp_obj_t *args) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(args[0]);
mp_buffer_info_t transfer_pk;
@ -402,12 +460,16 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_nem_encrypt(size_t n_args, const mp_obj_
vstr_t vstr;
vstr_init_len(&vstr, NEM_ENCRYPTED_SIZE(payload.len));
if (!hdnode_nem_encrypt(&o->hdnode, *(const ed25519_public_key *)transfer_pk.buf, iv.buf, salt.buf, payload.buf, payload.len, (uint8_t *)vstr.buf)) {
if (!hdnode_nem_encrypt(
&o->hdnode, *(const ed25519_public_key *)transfer_pk.buf, iv.buf,
salt.buf, payload.buf, payload.len, (uint8_t *)vstr.buf)) {
mp_raise_ValueError("HDNode nem encrypt failed");
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_HDNode_nem_encrypt_obj, 5, 5, mod_trezorcrypto_HDNode_nem_encrypt);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_HDNode_nem_encrypt_obj, 5, 5,
mod_trezorcrypto_HDNode_nem_encrypt);
/// def ethereum_pubkeyhash(self) -> bytes:
/// '''
@ -420,7 +482,9 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode_ethereum_pubkeyhash(mp_obj_t self) {
hdnode_get_ethereum_pubkeyhash(&o->hdnode, pkh);
return mp_obj_new_bytes(pkh, sizeof(pkh));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode_ethereum_pubkeyhash_obj, mod_trezorcrypto_HDNode_ethereum_pubkeyhash);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(
mod_trezorcrypto_HDNode_ethereum_pubkeyhash_obj,
mod_trezorcrypto_HDNode_ethereum_pubkeyhash);
STATIC mp_obj_t mod_trezorcrypto_HDNode___del__(mp_obj_t self) {
mp_obj_HDNode_t *o = MP_OBJ_TO_PTR(self);
@ -428,43 +492,66 @@ STATIC mp_obj_t mod_trezorcrypto_HDNode___del__(mp_obj_t self) {
memzero(&o->hdnode, sizeof(o->hdnode));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode___del___obj, mod_trezorcrypto_HDNode___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_HDNode___del___obj,
mod_trezorcrypto_HDNode___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_HDNode_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_HDNode___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_derive), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_obj) },
{ MP_ROM_QSTR(MP_QSTR_derive_cardano), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_cardano_obj) },
{ MP_ROM_QSTR(MP_QSTR_derive_path), MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_path_obj) },
{ MP_ROM_QSTR(MP_QSTR_serialize_private), MP_ROM_PTR(&mod_trezorcrypto_HDNode_serialize_private_obj) },
{ MP_ROM_QSTR(MP_QSTR_serialize_public), MP_ROM_PTR(&mod_trezorcrypto_HDNode_serialize_public_obj) },
{ MP_ROM_QSTR(MP_QSTR_clone), MP_ROM_PTR(&mod_trezorcrypto_HDNode_clone_obj) },
{ MP_ROM_QSTR(MP_QSTR_depth), MP_ROM_PTR(&mod_trezorcrypto_HDNode_depth_obj) },
{ MP_ROM_QSTR(MP_QSTR_fingerprint), MP_ROM_PTR(&mod_trezorcrypto_HDNode_fingerprint_obj) },
{ MP_ROM_QSTR(MP_QSTR_child_num), MP_ROM_PTR(&mod_trezorcrypto_HDNode_child_num_obj) },
{ MP_ROM_QSTR(MP_QSTR_chain_code), MP_ROM_PTR(&mod_trezorcrypto_HDNode_chain_code_obj) },
{ MP_ROM_QSTR(MP_QSTR_private_key), MP_ROM_PTR(&mod_trezorcrypto_HDNode_private_key_obj) },
{ MP_ROM_QSTR(MP_QSTR_private_key_ext), MP_ROM_PTR(&mod_trezorcrypto_HDNode_private_key_ext_obj) },
{ MP_ROM_QSTR(MP_QSTR_public_key), MP_ROM_PTR(&mod_trezorcrypto_HDNode_public_key_obj) },
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&mod_trezorcrypto_HDNode_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_nem_address), MP_ROM_PTR(&mod_trezorcrypto_HDNode_nem_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_nem_encrypt), MP_ROM_PTR(&mod_trezorcrypto_HDNode_nem_encrypt_obj) },
{ MP_ROM_QSTR(MP_QSTR_ethereum_pubkeyhash), MP_ROM_PTR(&mod_trezorcrypto_HDNode_ethereum_pubkeyhash_obj) },
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_HDNode___del___obj)},
{MP_ROM_QSTR(MP_QSTR_derive),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_obj)},
{MP_ROM_QSTR(MP_QSTR_derive_cardano),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_cardano_obj)},
{MP_ROM_QSTR(MP_QSTR_derive_path),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_derive_path_obj)},
{MP_ROM_QSTR(MP_QSTR_serialize_private),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_serialize_private_obj)},
{MP_ROM_QSTR(MP_QSTR_serialize_public),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_serialize_public_obj)},
{MP_ROM_QSTR(MP_QSTR_clone),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_clone_obj)},
{MP_ROM_QSTR(MP_QSTR_depth),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_depth_obj)},
{MP_ROM_QSTR(MP_QSTR_fingerprint),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_fingerprint_obj)},
{MP_ROM_QSTR(MP_QSTR_child_num),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_child_num_obj)},
{MP_ROM_QSTR(MP_QSTR_chain_code),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_chain_code_obj)},
{MP_ROM_QSTR(MP_QSTR_private_key),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_private_key_obj)},
{MP_ROM_QSTR(MP_QSTR_private_key_ext),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_private_key_ext_obj)},
{MP_ROM_QSTR(MP_QSTR_public_key),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_public_key_obj)},
{MP_ROM_QSTR(MP_QSTR_address),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_address_obj)},
{MP_ROM_QSTR(MP_QSTR_nem_address),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_nem_address_obj)},
{MP_ROM_QSTR(MP_QSTR_nem_encrypt),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_nem_encrypt_obj)},
{MP_ROM_QSTR(MP_QSTR_ethereum_pubkeyhash),
MP_ROM_PTR(&mod_trezorcrypto_HDNode_ethereum_pubkeyhash_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_HDNode_locals_dict, mod_trezorcrypto_HDNode_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_HDNode_locals_dict,
mod_trezorcrypto_HDNode_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_HDNode_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_HDNode,
.make_new = mod_trezorcrypto_HDNode_make_new,
.locals_dict = (void*)&mod_trezorcrypto_HDNode_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_HDNode_locals_dict,
};
/// def deserialize(self, value: str, version_public: int, version_private: int) -> HDNode:
/// def deserialize(self, value: str, version_public: int, version_private: int)
/// -> HDNode:
/// '''
/// Construct a BIP0032 HD node from a base58-serialized value.
/// '''
STATIC mp_obj_t mod_trezorcrypto_bip32_deserialize(mp_obj_t value, mp_obj_t version_public, mp_obj_t version_private) {
STATIC mp_obj_t mod_trezorcrypto_bip32_deserialize(mp_obj_t value,
mp_obj_t version_public,
mp_obj_t version_private) {
mp_buffer_info_t valueb;
mp_get_buffer_raise(value, &valueb, MP_BUFFER_READ);
if (valueb.len == 0) {
@ -474,7 +561,8 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_deserialize(mp_obj_t value, mp_obj_t vers
uint32_t vpriv = trezor_obj_get_uint(version_private);
HDNode hdnode;
uint32_t fingerprint;
if (hdnode_deserialize(valueb.buf, vpub, vpriv, SECP256K1_NAME, &hdnode, &fingerprint) < 0) {
if (hdnode_deserialize(valueb.buf, vpub, vpriv, SECP256K1_NAME, &hdnode,
&fingerprint) < 0) {
mp_raise_ValueError("Failed to deserialize");
}
@ -484,13 +572,15 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_deserialize(mp_obj_t value, mp_obj_t vers
o->fingerprint = fingerprint;
return MP_OBJ_FROM_PTR(o);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_bip32_deserialize_obj, mod_trezorcrypto_bip32_deserialize);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_bip32_deserialize_obj,
mod_trezorcrypto_bip32_deserialize);
/// def from_seed(seed: bytes, curve_name: str) -> HDNode:
/// '''
/// Construct a BIP0032 HD node from a BIP0039 seed value.
/// '''
STATIC mp_obj_t mod_trezorcrypto_bip32_from_seed(mp_obj_t seed, mp_obj_t curve_name) {
STATIC mp_obj_t mod_trezorcrypto_bip32_from_seed(mp_obj_t seed,
mp_obj_t curve_name) {
mp_buffer_info_t seedb;
mp_get_buffer_raise(seed, &seedb, MP_BUFFER_READ);
if (seedb.len == 0) {
@ -511,13 +601,15 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_from_seed(mp_obj_t seed, mp_obj_t curve_n
o->fingerprint = 0;
return MP_OBJ_FROM_PTR(o);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_bip32_from_seed_obj, mod_trezorcrypto_bip32_from_seed);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_bip32_from_seed_obj,
mod_trezorcrypto_bip32_from_seed);
/// def from_mnemonic_cardano(mnemonic: str, passphrase: str) -> bytes:
/// '''
/// Convert mnemonic to hdnode
/// '''
STATIC mp_obj_t mod_trezorcrypto_bip32_from_mnemonic_cardano(mp_obj_t mnemonic, mp_obj_t passphrase) {
STATIC mp_obj_t mod_trezorcrypto_bip32_from_mnemonic_cardano(
mp_obj_t mnemonic, mp_obj_t passphrase) {
mp_buffer_info_t mnemo, phrase;
mp_get_buffer_raise(mnemonic, &mnemo, MP_BUFFER_READ);
mp_get_buffer_raise(passphrase, &phrase, MP_BUFFER_READ);
@ -532,12 +624,14 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_from_mnemonic_cardano(mp_obj_t mnemonic,
mp_raise_ValueError("Invalid mnemonic");
}
const int res = hdnode_from_seed_cardano((const uint8_t *)ppassphrase, phrase.len, entropy, entropy_len / 8, &hdnode);
const int res =
hdnode_from_seed_cardano((const uint8_t *)ppassphrase, phrase.len,
entropy, entropy_len / 8, &hdnode);
if (!res) {
mp_raise_ValueError("Secret key generation from mnemonic is looping forever");
} else
if (res == -1) {
mp_raise_ValueError(
"Secret key generation from mnemonic is looping forever");
} else if (res == -1) {
mp_raise_ValueError("Invalid mnemonic");
}
@ -548,18 +642,24 @@ STATIC mp_obj_t mod_trezorcrypto_bip32_from_mnemonic_cardano(mp_obj_t mnemonic,
return MP_OBJ_FROM_PTR(o);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_bip32_from_mnemonic_cardano_obj, mod_trezorcrypto_bip32_from_mnemonic_cardano);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(
mod_trezorcrypto_bip32_from_mnemonic_cardano_obj,
mod_trezorcrypto_bip32_from_mnemonic_cardano);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_bip32_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bip32) },
{ MP_ROM_QSTR(MP_QSTR_HDNode), MP_ROM_PTR(&mod_trezorcrypto_HDNode_type) },
{ MP_ROM_QSTR(MP_QSTR_deserialize), MP_ROM_PTR(&mod_trezorcrypto_bip32_deserialize_obj) },
{ MP_ROM_QSTR(MP_QSTR_from_seed), MP_ROM_PTR(&mod_trezorcrypto_bip32_from_seed_obj) },
{ MP_ROM_QSTR(MP_QSTR_from_mnemonic_cardano), MP_ROM_PTR(&mod_trezorcrypto_bip32_from_mnemonic_cardano_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bip32)},
{MP_ROM_QSTR(MP_QSTR_HDNode), MP_ROM_PTR(&mod_trezorcrypto_HDNode_type)},
{MP_ROM_QSTR(MP_QSTR_deserialize),
MP_ROM_PTR(&mod_trezorcrypto_bip32_deserialize_obj)},
{MP_ROM_QSTR(MP_QSTR_from_seed),
MP_ROM_PTR(&mod_trezorcrypto_bip32_from_seed_obj)},
{MP_ROM_QSTR(MP_QSTR_from_mnemonic_cardano),
MP_ROM_PTR(&mod_trezorcrypto_bip32_from_mnemonic_cardano_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_bip32_globals, mod_trezorcrypto_bip32_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_bip32_globals,
mod_trezorcrypto_bip32_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_bip32_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_bip32_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_bip32_globals,
};

@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "py/runtime.h"
#include "py/objstr.h"
#include "py/runtime.h"
#include "bip39.h"
@ -28,29 +28,29 @@
/// '''
/// Return the first word from the wordlist starting with prefix.
/// '''
STATIC mp_obj_t mod_trezorcrypto_bip39_find_word(mp_obj_t prefix)
{
STATIC mp_obj_t mod_trezorcrypto_bip39_find_word(mp_obj_t prefix) {
mp_buffer_info_t pfx;
mp_get_buffer_raise(prefix, &pfx, MP_BUFFER_READ);
if (pfx.len == 0) {
return mp_const_none;
}
for (const char * const *w = mnemonic_wordlist(); *w != 0; w++) {
for (const char *const *w = mnemonic_wordlist(); *w != 0; w++) {
if (strncmp(*w, pfx.buf, pfx.len) == 0) {
return mp_obj_new_str(*w, strlen(*w));
}
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_find_word_obj, mod_trezorcrypto_bip39_find_word);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_find_word_obj,
mod_trezorcrypto_bip39_find_word);
/// def complete_word(prefix: str) -> int:
/// '''
/// Return possible 1-letter suffixes for given word prefix.
/// Result is a bitmask, with 'a' on the lowest bit, 'b' on the second lowest, etc.
/// Result is a bitmask, with 'a' on the lowest bit, 'b' on the second
/// lowest, etc.
/// '''
STATIC mp_obj_t mod_trezorcrypto_bip39_complete_word(mp_obj_t prefix)
{
STATIC mp_obj_t mod_trezorcrypto_bip39_complete_word(mp_obj_t prefix) {
mp_buffer_info_t pfx;
mp_get_buffer_raise(prefix, &pfx, MP_BUFFER_READ);
if (pfx.len == 0) {
@ -69,7 +69,8 @@ STATIC mp_obj_t mod_trezorcrypto_bip39_complete_word(mp_obj_t prefix)
}
return mp_obj_new_int(res);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_complete_word_obj, mod_trezorcrypto_bip39_complete_word);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_complete_word_obj,
mod_trezorcrypto_bip39_complete_word);
/// def generate(strength: int) -> str:
/// '''
@ -78,14 +79,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_complete_word_obj, mod_t
STATIC mp_obj_t mod_trezorcrypto_bip39_generate(mp_obj_t strength) {
int bits = mp_obj_get_int(strength);
if (bits % 32 || bits < 128 || bits > 256) {
mp_raise_ValueError("Invalid bit strength (only 128, 160, 192, 224 and 256 values are allowed)");
mp_raise_ValueError(
"Invalid bit strength (only 128, 160, 192, 224 and 256 values are "
"allowed)");
}
const char *mnemo = mnemonic_generate(bits);
mp_obj_t res = mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)mnemo, strlen(mnemo));
mp_obj_t res =
mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)mnemo, strlen(mnemo));
mnemonic_clear();
return res;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_generate_obj, mod_trezorcrypto_bip39_generate);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_generate_obj,
mod_trezorcrypto_bip39_generate);
/// def from_data(data: bytes) -> str:
/// '''
@ -95,14 +100,17 @@ STATIC mp_obj_t mod_trezorcrypto_bip39_from_data(mp_obj_t data) {
mp_buffer_info_t bin;
mp_get_buffer_raise(data, &bin, MP_BUFFER_READ);
if (bin.len % 4 || bin.len < 16 || bin.len > 32) {
mp_raise_ValueError("Invalid data length (only 16, 20, 24, 28 and 32 bytes are allowed)");
mp_raise_ValueError(
"Invalid data length (only 16, 20, 24, 28 and 32 bytes are allowed)");
}
const char *mnemo = mnemonic_from_data(bin.buf, bin.len);
mp_obj_t res = mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)mnemo, strlen(mnemo));
mp_obj_t res =
mp_obj_new_str_copy(&mp_type_str, (const uint8_t *)mnemo, strlen(mnemo));
mnemonic_clear();
return res;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_from_data_obj, mod_trezorcrypto_bip39_from_data);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_from_data_obj,
mod_trezorcrypto_bip39_from_data);
/// def check(mnemonic: str) -> bool:
/// '''
@ -111,23 +119,28 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_from_data_obj, mod_trezo
STATIC mp_obj_t mod_trezorcrypto_bip39_check(mp_obj_t mnemonic) {
mp_buffer_info_t text;
mp_get_buffer_raise(mnemonic, &text, MP_BUFFER_READ);
return (text.len > 0 && mnemonic_check(text.buf)) ? mp_const_true : mp_const_false;
return (text.len > 0 && mnemonic_check(text.buf)) ? mp_const_true
: mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_check_obj, mod_trezorcrypto_bip39_check);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_bip39_check_obj,
mod_trezorcrypto_bip39_check);
STATIC mp_obj_t ui_wait_callback = mp_const_none;
STATIC void wrapped_ui_wait_callback(uint32_t current, uint32_t total) {
if (mp_obj_is_callable(ui_wait_callback)) {
mp_call_function_2_protected(ui_wait_callback, mp_obj_new_int(current), mp_obj_new_int(total));
mp_call_function_2_protected(ui_wait_callback, mp_obj_new_int(current),
mp_obj_new_int(total));
}
}
/// def seed(mnemonic: str, passphrase: str, callback: (int, int -> None)=None) -> bytes:
/// def seed(mnemonic: str, passphrase: str, callback: (int, int -> None)=None)
/// -> bytes:
/// '''
/// Generate seed from mnemonic and passphrase.
/// '''
STATIC mp_obj_t mod_trezorcrypto_bip39_seed(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_bip39_seed(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t mnemo;
mp_buffer_info_t phrase;
mp_get_buffer_raise(args[0], &mnemo, MP_BUFFER_READ);
@ -146,20 +159,26 @@ STATIC mp_obj_t mod_trezorcrypto_bip39_seed(size_t n_args, const mp_obj_t *args)
}
return mp_obj_new_bytes(seed, sizeof(seed));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_bip39_seed_obj, 2, 3, mod_trezorcrypto_bip39_seed);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_bip39_seed_obj, 2,
3, mod_trezorcrypto_bip39_seed);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_bip39_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bip39) },
{ MP_ROM_QSTR(MP_QSTR_find_word), MP_ROM_PTR(&mod_trezorcrypto_bip39_find_word_obj) },
{ MP_ROM_QSTR(MP_QSTR_complete_word), MP_ROM_PTR(&mod_trezorcrypto_bip39_complete_word_obj) },
{ MP_ROM_QSTR(MP_QSTR_generate), MP_ROM_PTR(&mod_trezorcrypto_bip39_generate_obj) },
{ MP_ROM_QSTR(MP_QSTR_from_data), MP_ROM_PTR(&mod_trezorcrypto_bip39_from_data_obj) },
{ MP_ROM_QSTR(MP_QSTR_check), MP_ROM_PTR(&mod_trezorcrypto_bip39_check_obj) },
{ MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_trezorcrypto_bip39_seed_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bip39)},
{MP_ROM_QSTR(MP_QSTR_find_word),
MP_ROM_PTR(&mod_trezorcrypto_bip39_find_word_obj)},
{MP_ROM_QSTR(MP_QSTR_complete_word),
MP_ROM_PTR(&mod_trezorcrypto_bip39_complete_word_obj)},
{MP_ROM_QSTR(MP_QSTR_generate),
MP_ROM_PTR(&mod_trezorcrypto_bip39_generate_obj)},
{MP_ROM_QSTR(MP_QSTR_from_data),
MP_ROM_PTR(&mod_trezorcrypto_bip39_from_data_obj)},
{MP_ROM_QSTR(MP_QSTR_check), MP_ROM_PTR(&mod_trezorcrypto_bip39_check_obj)},
{MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_trezorcrypto_bip39_seed_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_bip39_globals, mod_trezorcrypto_bip39_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_bip39_globals,
mod_trezorcrypto_bip39_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_bip39_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_bip39_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_bip39_globals,
};

@ -39,7 +39,9 @@ STATIC mp_obj_t mod_trezorcrypto_Blake256_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Blake256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Blake256_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Blake256_t *o = m_new_obj(mp_obj_Blake256_t);
o->base.type = type;
@ -64,7 +66,8 @@ STATIC mp_obj_t mod_trezorcrypto_Blake256_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Blake256_update_obj, mod_trezorcrypto_Blake256_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Blake256_update_obj,
mod_trezorcrypto_Blake256_update);
/// def digest(self) -> bytes:
/// '''
@ -79,27 +82,35 @@ STATIC mp_obj_t mod_trezorcrypto_Blake256_digest(mp_obj_t self) {
memzero(&ctx, sizeof(BLAKE256_CTX));
return mp_obj_new_bytes(hash, sizeof(hash));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake256_digest_obj, mod_trezorcrypto_Blake256_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake256_digest_obj,
mod_trezorcrypto_Blake256_digest);
STATIC mp_obj_t mod_trezorcrypto_Blake256___del__(mp_obj_t self) {
mp_obj_Blake256_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(BLAKE256_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake256___del___obj, mod_trezorcrypto_Blake256___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake256___del___obj,
mod_trezorcrypto_Blake256___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Blake256_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Blake256_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Blake256_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Blake256___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(BLAKE256_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(BLAKE256_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Blake256_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Blake256_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Blake256___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(BLAKE256_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(BLAKE256_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Blake256_locals_dict, mod_trezorcrypto_Blake256_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Blake256_locals_dict,
mod_trezorcrypto_Blake256_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Blake256_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Blake256,
.make_new = mod_trezorcrypto_Blake256_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Blake256_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Blake256_locals_dict,
};

@ -37,31 +37,45 @@ typedef struct _mp_obj_Blake2b_t {
STATIC mp_obj_t mod_trezorcrypto_Blake2b_update(mp_obj_t self, mp_obj_t data);
/// def __init__(self, data: bytes = None, outlen: int = Blake2b.digest_size, personal: bytes = None) -> None:
/// def __init__(self, data: bytes = None, outlen: int = Blake2b.digest_size,
/// personal: bytes = None) -> None:
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Blake2b_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Blake2b_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_outlen, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BLAKE2B_DIGEST_LENGTH} },
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_personal, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes}},
{MP_QSTR_outlen,
MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = BLAKE2B_DIGEST_LENGTH}},
{MP_QSTR_key,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_personal,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
size_t data_len;
const uint8_t *data = (const uint8_t *)mp_obj_str_get_data(vals[0].u_obj, &data_len);
const uint8_t *data =
(const uint8_t *)mp_obj_str_get_data(vals[0].u_obj, &data_len);
const mp_int_t outlen = vals[1].u_int;
size_t key_len;
const uint8_t *key = (const uint8_t *)mp_obj_str_get_data(vals[2].u_obj, &key_len);
const uint8_t *key =
(const uint8_t *)mp_obj_str_get_data(vals[2].u_obj, &key_len);
size_t personal_len;
const uint8_t *personal = (const uint8_t *)mp_obj_str_get_data(vals[3].u_obj, &personal_len);
const uint8_t *personal =
(const uint8_t *)mp_obj_str_get_data(vals[3].u_obj, &personal_len);
if (key_len > 0 && personal_len > 0) {
mp_raise_ValueError("Invalid Blake2b parameters: cannot use key and personal at the same time");
mp_raise_ValueError(
"Invalid Blake2b parameters: cannot use key and personal at the same "
"time");
}
mp_obj_Blake2b_t *o = m_new_obj(mp_obj_Blake2b_t);
@ -101,7 +115,8 @@ STATIC mp_obj_t mod_trezorcrypto_Blake2b_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Blake2b_update_obj, mod_trezorcrypto_Blake2b_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Blake2b_update_obj,
mod_trezorcrypto_Blake2b_update);
/// def digest(self) -> bytes:
/// '''
@ -116,27 +131,35 @@ STATIC mp_obj_t mod_trezorcrypto_Blake2b_digest(mp_obj_t self) {
memzero(&ctx, sizeof(BLAKE2B_CTX));
return mp_obj_new_bytes(out, o->ctx.outlen);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2b_digest_obj, mod_trezorcrypto_Blake2b_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2b_digest_obj,
mod_trezorcrypto_Blake2b_digest);
STATIC mp_obj_t mod_trezorcrypto_Blake2b___del__(mp_obj_t self) {
mp_obj_Blake2b_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(BLAKE2B_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2b___del___obj, mod_trezorcrypto_Blake2b___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2b___del___obj,
mod_trezorcrypto_Blake2b___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Blake2b_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Blake2b_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Blake2b_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Blake2b___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(BLAKE2B_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(BLAKE2B_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Blake2b_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Blake2b_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Blake2b___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(BLAKE2B_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(BLAKE2B_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Blake2b_locals_dict, mod_trezorcrypto_Blake2b_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Blake2b_locals_dict,
mod_trezorcrypto_Blake2b_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Blake2b_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Blake2b,
.make_new = mod_trezorcrypto_Blake2b_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Blake2b_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Blake2b_locals_dict,
};

@ -37,31 +37,45 @@ typedef struct _mp_obj_Blake2s_t {
STATIC mp_obj_t mod_trezorcrypto_Blake2s_update(mp_obj_t self, mp_obj_t data);
/// def __init__(self, data: bytes = None, outlen: int = Blake2s.digest_size, key: bytes = None, personal: bytes = None) -> None:
/// def __init__(self, data: bytes = None, outlen: int = Blake2s.digest_size,
/// key: bytes = None, personal: bytes = None) -> None:
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Blake2s_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Blake2s_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_outlen, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BLAKE2S_DIGEST_LENGTH} },
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_personal, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes}},
{MP_QSTR_outlen,
MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = BLAKE2S_DIGEST_LENGTH}},
{MP_QSTR_key,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_personal,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
size_t data_len;
const uint8_t *data = (const uint8_t *)mp_obj_str_get_data(vals[0].u_obj, &data_len);
const uint8_t *data =
(const uint8_t *)mp_obj_str_get_data(vals[0].u_obj, &data_len);
const mp_int_t outlen = vals[1].u_int;
size_t key_len;
const uint8_t *key = (const uint8_t *)mp_obj_str_get_data(vals[2].u_obj, &key_len);
const uint8_t *key =
(const uint8_t *)mp_obj_str_get_data(vals[2].u_obj, &key_len);
size_t personal_len;
const uint8_t *personal = (const uint8_t *)mp_obj_str_get_data(vals[3].u_obj, &personal_len);
const uint8_t *personal =
(const uint8_t *)mp_obj_str_get_data(vals[3].u_obj, &personal_len);
if (key_len > 0 && personal_len > 0) {
mp_raise_ValueError("Invalid Blake2s parameters: cannot use key and personal at the same time");
mp_raise_ValueError(
"Invalid Blake2s parameters: cannot use key and personal at the same "
"time");
}
mp_obj_Blake2s_t *o = m_new_obj(mp_obj_Blake2s_t);
@ -101,7 +115,8 @@ STATIC mp_obj_t mod_trezorcrypto_Blake2s_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Blake2s_update_obj, mod_trezorcrypto_Blake2s_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Blake2s_update_obj,
mod_trezorcrypto_Blake2s_update);
/// def digest(self) -> bytes:
/// '''
@ -116,27 +131,35 @@ STATIC mp_obj_t mod_trezorcrypto_Blake2s_digest(mp_obj_t self) {
memzero(&ctx, sizeof(BLAKE2S_CTX));
return mp_obj_new_bytes(out, o->ctx.outlen);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2s_digest_obj, mod_trezorcrypto_Blake2s_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2s_digest_obj,
mod_trezorcrypto_Blake2s_digest);
STATIC mp_obj_t mod_trezorcrypto_Blake2s___del__(mp_obj_t self) {
mp_obj_Blake2s_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(BLAKE2S_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2s___del___obj, mod_trezorcrypto_Blake2s___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Blake2s___del___obj,
mod_trezorcrypto_Blake2s___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Blake2s_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Blake2s_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Blake2s_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Blake2s___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(BLAKE2S_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(BLAKE2S_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Blake2s_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Blake2s_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Blake2s___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(BLAKE2S_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(BLAKE2S_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Blake2s_locals_dict, mod_trezorcrypto_Blake2s_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Blake2s_locals_dict,
mod_trezorcrypto_Blake2s_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Blake2s_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Blake2s,
.make_new = mod_trezorcrypto_Blake2s_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Blake2s_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Blake2s_locals_dict,
};

@ -39,7 +39,9 @@ typedef struct _mp_obj_ChaCha20Poly1305_t {
/// Initialize the ChaCha20 + Poly1305 context for encryption or decryption
/// using a 32 byte key and 12 byte nonce as in the RFC 7539 style.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_make_new(
const mp_obj_type_t *type, size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 2, 2, false);
mp_obj_ChaCha20Poly1305_t *o = m_new_obj(mp_obj_ChaCha20Poly1305_t);
o->base.type = type;
@ -60,9 +62,11 @@ STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_make_new(const mp_obj_type_t *
/// def encrypt(self, data: bytes) -> bytes:
/// '''
/// Encrypt data (length of data must be divisible by 64 except for the final value).
/// Encrypt data (length of data must be divisible by 64 except for the
/// final value).
/// '''
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_encrypt(mp_obj_t self, mp_obj_t data) {
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_encrypt(mp_obj_t self,
mp_obj_t data) {
mp_obj_ChaCha20Poly1305_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t in;
mp_get_buffer_raise(data, &in, MP_BUFFER_READ);
@ -72,13 +76,16 @@ STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_encrypt(mp_obj_t self, mp_obj_
o->plen += in.len;
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_encrypt_obj, mod_trezorcrypto_ChaCha20Poly1305_encrypt);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_encrypt_obj,
mod_trezorcrypto_ChaCha20Poly1305_encrypt);
/// def decrypt(self, data: bytes) -> bytes:
/// '''
/// Decrypt data (length of data must be divisible by 64 except for the final value).
/// Decrypt data (length of data must be divisible by 64 except for the
/// final value).
/// '''
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_decrypt(mp_obj_t self, mp_obj_t data) {
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_decrypt(mp_obj_t self,
mp_obj_t data) {
mp_obj_ChaCha20Poly1305_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t in;
mp_get_buffer_raise(data, &in, MP_BUFFER_READ);
@ -88,7 +95,8 @@ STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_decrypt(mp_obj_t self, mp_obj_
o->plen += in.len;
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_decrypt_obj, mod_trezorcrypto_ChaCha20Poly1305_decrypt);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_decrypt_obj,
mod_trezorcrypto_ChaCha20Poly1305_decrypt);
/// def auth(self, data: bytes) -> None:
/// '''
@ -96,7 +104,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_decrypt_obj,
/// style with 16 byte padding. This must only be called once and prior
/// to encryption or decryption.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_auth(mp_obj_t self, mp_obj_t data) {
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_auth(mp_obj_t self,
mp_obj_t data) {
mp_obj_ChaCha20Poly1305_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t in;
mp_get_buffer_raise(data, &in, MP_BUFFER_READ);
@ -104,7 +113,8 @@ STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_auth(mp_obj_t self, mp_obj_t d
o->alen += in.len;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_auth_obj, mod_trezorcrypto_ChaCha20Poly1305_auth);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ChaCha20Poly1305_auth_obj,
mod_trezorcrypto_ChaCha20Poly1305_auth);
/// def finish(self) -> bytes:
/// '''
@ -116,7 +126,8 @@ STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305_finish(mp_obj_t self) {
rfc7539_finish(&(o->ctx), o->alen, o->plen, out);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ChaCha20Poly1305_finish_obj, mod_trezorcrypto_ChaCha20Poly1305_finish);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ChaCha20Poly1305_finish_obj,
mod_trezorcrypto_ChaCha20Poly1305_finish);
STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305___del__(mp_obj_t self) {
mp_obj_ChaCha20Poly1305_t *o = MP_OBJ_TO_PTR(self);
@ -125,20 +136,29 @@ STATIC mp_obj_t mod_trezorcrypto_ChaCha20Poly1305___del__(mp_obj_t self) {
o->plen = 0;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ChaCha20Poly1305___del___obj, mod_trezorcrypto_ChaCha20Poly1305___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ChaCha20Poly1305___del___obj,
mod_trezorcrypto_ChaCha20Poly1305___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_ChaCha20Poly1305_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_encrypt), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_encrypt_obj) },
{ MP_ROM_QSTR(MP_QSTR_decrypt), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_decrypt_obj) },
{ MP_ROM_QSTR(MP_QSTR_auth), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_auth_obj) },
{ MP_ROM_QSTR(MP_QSTR_finish), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_finish_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305___del___obj) },
STATIC const mp_rom_map_elem_t
mod_trezorcrypto_ChaCha20Poly1305_locals_dict_table[] = {
{MP_ROM_QSTR(MP_QSTR_encrypt),
MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_encrypt_obj)},
{MP_ROM_QSTR(MP_QSTR_decrypt),
MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_decrypt_obj)},
{MP_ROM_QSTR(MP_QSTR_auth),
MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_auth_obj)},
{MP_ROM_QSTR(MP_QSTR_finish),
MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_finish_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305___del___obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_ChaCha20Poly1305_locals_dict, mod_trezorcrypto_ChaCha20Poly1305_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(
mod_trezorcrypto_ChaCha20Poly1305_locals_dict,
mod_trezorcrypto_ChaCha20Poly1305_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_ChaCha20Poly1305_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_ChaCha20Poly1305,
.make_new = mod_trezorcrypto_ChaCha20Poly1305_make_new,
.locals_dict = (void*)&mod_trezorcrypto_ChaCha20Poly1305_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_ChaCha20Poly1305_locals_dict,
};

@ -30,15 +30,17 @@ mp_obj_t mod_trezorcrypto_crc_crc32(size_t n_args, const mp_obj_t *args) {
crc = checksum_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff);
return mp_obj_new_int_from_uint(crc ^ 0xffffffff);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_crc_crc32_obj, 1, 2, mod_trezorcrypto_crc_crc32);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_crc_crc32_obj, 1, 2,
mod_trezorcrypto_crc_crc32);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_crc_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_crc) },
{ MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_trezorcrypto_crc_crc32_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_crc)},
{MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_trezorcrypto_crc_crc32_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_crc_globals, mod_trezorcrypto_crc_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_crc_globals,
mod_trezorcrypto_crc_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_crc_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_crc_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_crc_globals,
};

@ -38,7 +38,9 @@ STATIC mp_obj_t mod_trezorcrypto_curve25519_generate_secret() {
out[31] |= 64;
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_curve25519_generate_secret_obj, mod_trezorcrypto_curve25519_generate_secret);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(
mod_trezorcrypto_curve25519_generate_secret_obj,
mod_trezorcrypto_curve25519_generate_secret);
/// def publickey(secret_key: bytes) -> bytes:
/// '''
@ -54,14 +56,16 @@ STATIC mp_obj_t mod_trezorcrypto_curve25519_publickey(mp_obj_t secret_key) {
curve25519_scalarmult_basepoint(out, (const uint8_t *)sk.buf);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_curve25519_publickey_obj, mod_trezorcrypto_curve25519_publickey);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_curve25519_publickey_obj,
mod_trezorcrypto_curve25519_publickey);
/// def multiply(secret_key: bytes, public_key: bytes) -> bytes:
/// '''
/// Multiplies point defined by public_key with scalar defined by secret_key.
/// Useful for ECDH.
/// Multiplies point defined by public_key with scalar defined by
/// secret_key. Useful for ECDH.
/// '''
STATIC mp_obj_t mod_trezorcrypto_curve25519_multiply(mp_obj_t secret_key, mp_obj_t public_key) {
STATIC mp_obj_t mod_trezorcrypto_curve25519_multiply(mp_obj_t secret_key,
mp_obj_t public_key) {
mp_buffer_info_t sk, pk;
mp_get_buffer_raise(secret_key, &sk, MP_BUFFER_READ);
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
@ -75,17 +79,22 @@ STATIC mp_obj_t mod_trezorcrypto_curve25519_multiply(mp_obj_t secret_key, mp_obj
curve25519_scalarmult(out, (const uint8_t *)sk.buf, (const uint8_t *)pk.buf);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_curve25519_multiply_obj, mod_trezorcrypto_curve25519_multiply);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_curve25519_multiply_obj,
mod_trezorcrypto_curve25519_multiply);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_curve25519_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_curve25519) },
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_trezorcrypto_curve25519_generate_secret_obj) },
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_trezorcrypto_curve25519_publickey_obj) },
{ MP_ROM_QSTR(MP_QSTR_multiply), MP_ROM_PTR(&mod_trezorcrypto_curve25519_multiply_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_curve25519)},
{MP_ROM_QSTR(MP_QSTR_generate_secret),
MP_ROM_PTR(&mod_trezorcrypto_curve25519_generate_secret_obj)},
{MP_ROM_QSTR(MP_QSTR_publickey),
MP_ROM_PTR(&mod_trezorcrypto_curve25519_publickey_obj)},
{MP_ROM_QSTR(MP_QSTR_multiply),
MP_ROM_PTR(&mod_trezorcrypto_curve25519_multiply_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_curve25519_globals, mod_trezorcrypto_curve25519_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_curve25519_globals,
mod_trezorcrypto_curve25519_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_curve25519_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_curve25519_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_curve25519_globals,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "ed25519-donna/ed25519.h"
#include "ed25519-donna/ed25519-keccak.h"
#include "ed25519-donna/ed25519.h"
#include "rand.h"
@ -39,7 +39,8 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_generate_secret() {
out[31] |= 64;
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_ed25519_generate_secret_obj, mod_trezorcrypto_ed25519_generate_secret);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_ed25519_generate_secret_obj,
mod_trezorcrypto_ed25519_generate_secret);
/// def publickey(secret_key: bytes) -> bytes:
/// '''
@ -52,16 +53,19 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_publickey(mp_obj_t secret_key) {
mp_raise_ValueError("Invalid length of secret key");
}
uint8_t out[32];
ed25519_publickey(*(const ed25519_secret_key *)sk.buf, *(ed25519_public_key *)out);
ed25519_publickey(*(const ed25519_secret_key *)sk.buf,
*(ed25519_public_key *)out);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ed25519_publickey_obj, mod_trezorcrypto_ed25519_publickey);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ed25519_publickey_obj,
mod_trezorcrypto_ed25519_publickey);
/// def sign(secret_key: bytes, message: bytes, hasher: str='') -> bytes:
/// '''
/// Uses secret key to produce the signature of message.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ed25519_sign(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_ed25519_sign(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t sk, msg;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ);
mp_get_buffer_raise(args[1], &msg, MP_BUFFER_READ);
@ -80,24 +84,30 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_sign(size_t n_args, const mp_obj_t *arg
// if hash_func == 'keccak':
if (memcmp(hash_func.buf, "keccak", sizeof("keccak")) == 0) {
ed25519_publickey_keccak(*(const ed25519_secret_key *)sk.buf, pk);
ed25519_sign_keccak(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf, pk, *(ed25519_signature *)out);
ed25519_sign_keccak(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf,
pk, *(ed25519_signature *)out);
} else {
mp_raise_ValueError("Unknown hash function");
}
} else {
ed25519_publickey(*(const ed25519_secret_key *)sk.buf, pk);
ed25519_sign(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf, pk, *(ed25519_signature *)out);
ed25519_sign(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf, pk,
*(ed25519_signature *)out);
}
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_ed25519_sign_obj, 2, 3, mod_trezorcrypto_ed25519_sign);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_ed25519_sign_obj, 2,
3, mod_trezorcrypto_ed25519_sign);
/// def sign_ext(secret_key: bytes, secret_extension: bytes, message: bytes) -> bytes:
/// def sign_ext(secret_key: bytes, secret_extension: bytes, message: bytes) ->
/// bytes:
/// '''
/// Uses secret key to produce the cardano signature of message.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ed25519_sign_ext(mp_obj_t secret_key, mp_obj_t secret_extension, mp_obj_t message) {
STATIC mp_obj_t mod_trezorcrypto_ed25519_sign_ext(mp_obj_t secret_key,
mp_obj_t secret_extension,
mp_obj_t message) {
mp_buffer_info_t sk, skext, msg;
mp_get_buffer_raise(secret_key, &sk, MP_BUFFER_READ);
mp_get_buffer_raise(secret_extension, &skext, MP_BUFFER_READ);
@ -113,19 +123,25 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_sign_ext(mp_obj_t secret_key, mp_obj_t
}
ed25519_public_key pk;
ed25519_publickey_ext(*(const ed25519_secret_key *)sk.buf, *(const ed25519_secret_key *)skext.buf, pk);
ed25519_publickey_ext(*(const ed25519_secret_key *)sk.buf,
*(const ed25519_secret_key *)skext.buf, pk);
uint8_t out[64];
ed25519_sign_ext(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf, *(const ed25519_secret_key *)skext.buf, pk, *(ed25519_signature *)out);
ed25519_sign_ext(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf,
*(const ed25519_secret_key *)skext.buf, pk,
*(ed25519_signature *)out);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_ed25519_sign_ext_obj, mod_trezorcrypto_ed25519_sign_ext);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_ed25519_sign_ext_obj,
mod_trezorcrypto_ed25519_sign_ext);
/// def verify(public_key: bytes, signature: bytes, message: bytes) -> bool:
/// '''
/// Uses public key to verify the signature of the message.
/// Returns True on success.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ed25519_verify(mp_obj_t public_key, mp_obj_t signature, mp_obj_t message) {
STATIC mp_obj_t mod_trezorcrypto_ed25519_verify(mp_obj_t public_key,
mp_obj_t signature,
mp_obj_t message) {
mp_buffer_info_t pk, sig, msg;
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ);
@ -139,15 +155,21 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_verify(mp_obj_t public_key, mp_obj_t si
if (msg.len == 0) {
mp_raise_ValueError("Empty data to verify");
}
return (0 == ed25519_sign_open(msg.buf, msg.len, *(const ed25519_public_key *)pk.buf, *(const ed25519_signature *)sig.buf)) ? mp_const_true : mp_const_false;
return (0 == ed25519_sign_open(msg.buf, msg.len,
*(const ed25519_public_key *)pk.buf,
*(const ed25519_signature *)sig.buf))
? mp_const_true
: mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_ed25519_verify_obj, mod_trezorcrypto_ed25519_verify);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_ed25519_verify_obj,
mod_trezorcrypto_ed25519_verify);
/// def cosi_combine_publickeys(public_keys: List[bytes]) -> bytes:
/// '''
/// Combines a list of public keys used in COSI cosigning scheme.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_combine_publickeys(mp_obj_t public_keys) {
STATIC mp_obj_t
mod_trezorcrypto_ed25519_cosi_combine_publickeys(mp_obj_t public_keys) {
size_t pklen;
mp_obj_t *pkitems;
mp_obj_get_array(public_keys, &pklen, &pkitems);
@ -164,18 +186,22 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_combine_publickeys(mp_obj_t public
memcpy(pks[i], buf.buf, buf.len);
}
uint8_t out[32];
if (0 != ed25519_cosi_combine_publickeys(*(ed25519_public_key *)out, pks, pklen)) {
if (0 !=
ed25519_cosi_combine_publickeys(*(ed25519_public_key *)out, pks, pklen)) {
mp_raise_ValueError("Error combining public keys");
}
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_ed25519_cosi_combine_publickeys_obj, mod_trezorcrypto_ed25519_cosi_combine_publickeys);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(
mod_trezorcrypto_ed25519_cosi_combine_publickeys_obj,
mod_trezorcrypto_ed25519_cosi_combine_publickeys);
/// def cosi_combine_signatures(R: bytes, signatures: List[bytes]) -> bytes:
/// '''
/// Combines a list of signatures used in COSI cosigning scheme.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_combine_signatures(mp_obj_t R, mp_obj_t signatures) {
STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_combine_signatures(
mp_obj_t R, mp_obj_t signatures) {
mp_buffer_info_t sigR;
mp_get_buffer_raise(R, &sigR, MP_BUFFER_READ);
if (sigR.len != 32) {
@ -197,16 +223,22 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_combine_signatures(mp_obj_t R, mp_
memcpy(sigs[i], buf.buf, buf.len);
}
uint8_t out[64];
ed25519_cosi_combine_signatures(*(ed25519_signature *)out, *(const ed25519_public_key *)sigR.buf, sigs, siglen);
ed25519_cosi_combine_signatures(*(ed25519_signature *)out,
*(const ed25519_public_key *)sigR.buf, sigs,
siglen);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_ed25519_cosi_combine_signatures_obj, mod_trezorcrypto_ed25519_cosi_combine_signatures);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(
mod_trezorcrypto_ed25519_cosi_combine_signatures_obj,
mod_trezorcrypto_ed25519_cosi_combine_signatures);
/// def cosi_sign(secret_key: bytes, message: bytes, nonce: bytes, sigR: bytes, combined_pubkey: bytes) -> bytes:
/// def cosi_sign(secret_key: bytes, message: bytes, nonce: bytes, sigR: bytes,
/// combined_pubkey: bytes) -> bytes:
/// '''
/// Produce signature of message using COSI cosigning scheme.
/// '''
STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_sign(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_sign(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t sk, msg, nonce, sigR, pk;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ);
mp_get_buffer_raise(args[1], &msg, MP_BUFFER_READ);
@ -226,25 +258,39 @@ STATIC mp_obj_t mod_trezorcrypto_ed25519_cosi_sign(size_t n_args, const mp_obj_t
mp_raise_ValueError("Invalid length of aggregated public key");
}
uint8_t out[32];
ed25519_cosi_sign(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf, *(const ed25519_secret_key *)nonce.buf, *(const ed25519_public_key *)sigR.buf, *(const ed25519_secret_key *)pk.buf, *(ed25519_cosi_signature *)out);
ed25519_cosi_sign(msg.buf, msg.len, *(const ed25519_secret_key *)sk.buf,
*(const ed25519_secret_key *)nonce.buf,
*(const ed25519_public_key *)sigR.buf,
*(const ed25519_secret_key *)pk.buf,
*(ed25519_cosi_signature *)out);
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_ed25519_cosi_sign_obj, 5, 5, mod_trezorcrypto_ed25519_cosi_sign);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_ed25519_cosi_sign_obj, 5, 5,
mod_trezorcrypto_ed25519_cosi_sign);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_ed25519_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ed25519) },
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_trezorcrypto_ed25519_generate_secret_obj) },
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_trezorcrypto_ed25519_publickey_obj) },
{ MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_trezorcrypto_ed25519_sign_obj) },
{ MP_ROM_QSTR(MP_QSTR_sign_ext), MP_ROM_PTR(&mod_trezorcrypto_ed25519_sign_ext_obj) },
{ MP_ROM_QSTR(MP_QSTR_verify), MP_ROM_PTR(&mod_trezorcrypto_ed25519_verify_obj) },
{ MP_ROM_QSTR(MP_QSTR_cosi_combine_publickeys), MP_ROM_PTR(&mod_trezorcrypto_ed25519_cosi_combine_publickeys_obj) },
{ MP_ROM_QSTR(MP_QSTR_cosi_combine_signatures), MP_ROM_PTR(&mod_trezorcrypto_ed25519_cosi_combine_signatures_obj) },
{ MP_ROM_QSTR(MP_QSTR_cosi_sign), MP_ROM_PTR(&mod_trezorcrypto_ed25519_cosi_sign_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ed25519)},
{MP_ROM_QSTR(MP_QSTR_generate_secret),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_generate_secret_obj)},
{MP_ROM_QSTR(MP_QSTR_publickey),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_publickey_obj)},
{MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_trezorcrypto_ed25519_sign_obj)},
{MP_ROM_QSTR(MP_QSTR_sign_ext),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_sign_ext_obj)},
{MP_ROM_QSTR(MP_QSTR_verify),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_verify_obj)},
{MP_ROM_QSTR(MP_QSTR_cosi_combine_publickeys),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_cosi_combine_publickeys_obj)},
{MP_ROM_QSTR(MP_QSTR_cosi_combine_signatures),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_cosi_combine_signatures_obj)},
{MP_ROM_QSTR(MP_QSTR_cosi_sign),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_cosi_sign_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_ed25519_globals, mod_trezorcrypto_ed25519_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_ed25519_globals,
mod_trezorcrypto_ed25519_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_ed25519_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_ed25519_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_ed25519_globals,
};

@ -36,13 +36,16 @@ typedef struct _mp_obj_Groestl512_t {
GROESTL512_CTX ctx;
} mp_obj_Groestl512_t;
STATIC mp_obj_t mod_trezorcrypto_Groestl512_update(mp_obj_t self, mp_obj_t data);
STATIC mp_obj_t mod_trezorcrypto_Groestl512_update(mp_obj_t self,
mp_obj_t data);
/// def __init__(self, data: bytes = None) -> None:
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Groestl512_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Groestl512_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Groestl512_t *o = m_new_obj(mp_obj_Groestl512_t);
o->base.type = type;
@ -57,7 +60,8 @@ STATIC mp_obj_t mod_trezorcrypto_Groestl512_make_new(const mp_obj_type_t *type,
/// '''
/// Update the hash context with hashed data.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Groestl512_update(mp_obj_t self, mp_obj_t data) {
STATIC mp_obj_t mod_trezorcrypto_Groestl512_update(mp_obj_t self,
mp_obj_t data) {
mp_obj_Groestl512_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t msg;
mp_get_buffer_raise(data, &msg, MP_BUFFER_READ);
@ -66,7 +70,8 @@ STATIC mp_obj_t mod_trezorcrypto_Groestl512_update(mp_obj_t self, mp_obj_t data)
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Groestl512_update_obj, mod_trezorcrypto_Groestl512_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Groestl512_update_obj,
mod_trezorcrypto_Groestl512_update);
/// def digest(self) -> bytes:
/// '''
@ -81,27 +86,36 @@ STATIC mp_obj_t mod_trezorcrypto_Groestl512_digest(mp_obj_t self) {
memzero(&ctx, sizeof(GROESTL512_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Groestl512_digest_obj, mod_trezorcrypto_Groestl512_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Groestl512_digest_obj,
mod_trezorcrypto_Groestl512_digest);
STATIC mp_obj_t mod_trezorcrypto_Groestl512___del__(mp_obj_t self) {
mp_obj_Groestl512_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(GROESTL512_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Groestl512___del___obj, mod_trezorcrypto_Groestl512___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Groestl512___del___obj,
mod_trezorcrypto_Groestl512___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Groestl512_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Groestl512_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Groestl512_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Groestl512___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(GROESTL512_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(GROESTL512_DIGEST_LENGTH) },
STATIC const mp_rom_map_elem_t
mod_trezorcrypto_Groestl512_locals_dict_table[] = {
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Groestl512_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Groestl512_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Groestl512___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(GROESTL512_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(GROESTL512_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Groestl512_locals_dict, mod_trezorcrypto_Groestl512_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Groestl512_locals_dict,
mod_trezorcrypto_Groestl512_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Groestl512_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Groestl512,
.make_new = mod_trezorcrypto_Groestl512_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Groestl512_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Groestl512_locals_dict,
};

File diff suppressed because it is too large Load Diff

@ -29,21 +29,23 @@
/// '''
/// Validate a NEM address
/// '''
STATIC mp_obj_t mod_trezorcrypto_nem_validate_address(mp_obj_t address, mp_obj_t network) {
STATIC mp_obj_t mod_trezorcrypto_nem_validate_address(mp_obj_t address,
mp_obj_t network) {
mp_buffer_info_t addr;
mp_get_buffer_raise(address, &addr, MP_BUFFER_READ);
uint32_t n = trezor_obj_get_uint(network);
return mp_obj_new_bool(nem_validate_address(addr.buf, n));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nem_validate_address_obj, mod_trezorcrypto_nem_validate_address);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nem_validate_address_obj,
mod_trezorcrypto_nem_validate_address);
/// def compute_address(public_key: bytes, network: int) -> str:
/// '''
/// Compute a NEM address from a public key
/// '''
STATIC mp_obj_t mod_trezorcrypto_nem_compute_address(mp_obj_t public_key, mp_obj_t network) {
STATIC mp_obj_t mod_trezorcrypto_nem_compute_address(mp_obj_t public_key,
mp_obj_t network) {
mp_buffer_info_t p;
mp_get_buffer_raise(public_key, &p, MP_BUFFER_READ);
@ -51,21 +53,27 @@ STATIC mp_obj_t mod_trezorcrypto_nem_compute_address(mp_obj_t public_key, mp_obj
char address[NEM_ADDRESS_SIZE + 1]; // + 1 for the 0 byte
if (!nem_get_address(p.buf, n, address)) {
mp_raise_ValueError("Failed to compute a NEM address from provided public key");
mp_raise_ValueError(
"Failed to compute a NEM address from provided public key");
}
return mp_obj_new_str_of_type(&mp_type_str, (const uint8_t *)address, strlen(address));
return mp_obj_new_str_of_type(&mp_type_str, (const uint8_t *)address,
strlen(address));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nem_compute_address_obj, mod_trezorcrypto_nem_compute_address);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nem_compute_address_obj,
mod_trezorcrypto_nem_compute_address);
// objects definition
STATIC const mp_rom_map_elem_t mod_trezorcrypto_nem_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_validate_address), MP_ROM_PTR(&mod_trezorcrypto_nem_validate_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_compute_address), MP_ROM_PTR(&mod_trezorcrypto_nem_compute_address_obj) },
{MP_ROM_QSTR(MP_QSTR_validate_address),
MP_ROM_PTR(&mod_trezorcrypto_nem_validate_address_obj)},
{MP_ROM_QSTR(MP_QSTR_compute_address),
MP_ROM_PTR(&mod_trezorcrypto_nem_compute_address_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_nem_globals, mod_trezorcrypto_nem_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_nem_globals,
mod_trezorcrypto_nem_globals_table);
// module definition
STATIC const mp_obj_module_t mod_trezorcrypto_nem_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_nem_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_nem_globals,
};

@ -33,19 +33,33 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_generate_secret() {
for (;;) {
random_buffer(out, 32);
// check whether secret > 0 && secret < curve_order
if (0 == memcmp(out, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) continue;
if (0 <= memcmp(out, "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51", 32)) continue;
if (0 ==
memcmp(
out,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
32))
continue;
if (0 <=
memcmp(
out,
"\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
"\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51",
32))
continue;
break;
}
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_nist256p1_generate_secret_obj, mod_trezorcrypto_nist256p1_generate_secret);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_nist256p1_generate_secret_obj,
mod_trezorcrypto_nist256p1_generate_secret);
/// def publickey(secret_key: bytes, compressed: bool = True) -> bytes:
/// '''
/// Computes public key from secret key.
/// '''
STATIC mp_obj_t mod_trezorcrypto_nist256p1_publickey(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_nist256p1_publickey(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t sk;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ);
if (sk.len != 32) {
@ -62,13 +76,17 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_publickey(size_t n_args, const mp_obj
return mp_obj_new_bytes(out, sizeof(out));
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_nist256p1_publickey_obj, 1, 2, mod_trezorcrypto_nist256p1_publickey);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_nist256p1_publickey_obj, 1, 2,
mod_trezorcrypto_nist256p1_publickey);
/// def sign(secret_key: bytes, digest: bytes, compressed: bool = True) -> bytes:
/// def sign(secret_key: bytes, digest: bytes, compressed: bool = True) ->
/// bytes:
/// '''
/// Uses secret key to produce the signature of the digest.
/// '''
STATIC mp_obj_t mod_trezorcrypto_nist256p1_sign(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_nist256p1_sign(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t sk, dig;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ);
mp_get_buffer_raise(args[1], &dig, MP_BUFFER_READ);
@ -80,20 +98,25 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_sign(size_t n_args, const mp_obj_t *a
mp_raise_ValueError("Invalid length of digest");
}
uint8_t out[65], pby;
if (0 != ecdsa_sign_digest(&nist256p1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf, out + 1, &pby, NULL)) {
if (0 != ecdsa_sign_digest(&nist256p1, (const uint8_t *)sk.buf,
(const uint8_t *)dig.buf, out + 1, &pby, NULL)) {
mp_raise_ValueError("Signing failed");
}
out[0] = 27 + pby + compressed * 4;
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_nist256p1_sign_obj, 2, 3, mod_trezorcrypto_nist256p1_sign);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_nist256p1_sign_obj,
2, 3,
mod_trezorcrypto_nist256p1_sign);
/// def verify(public_key: bytes, signature: bytes, digest: bytes) -> bool:
/// '''
/// Uses public key to verify the signature of the digest.
/// Returns True on success.
/// '''
STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify(mp_obj_t public_key, mp_obj_t signature, mp_obj_t digest) {
STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify(mp_obj_t public_key,
mp_obj_t signature,
mp_obj_t digest) {
mp_buffer_info_t pk, sig, dig;
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ);
@ -108,16 +131,21 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify(mp_obj_t public_key, mp_obj_t
if (dig.len != 32) {
mp_raise_ValueError("Invalid length of digest");
}
return mp_obj_new_bool(0 == ecdsa_verify_digest(&nist256p1, (const uint8_t *)pk.buf, (const uint8_t *)sig.buf + offset, (const uint8_t *)dig.buf));
return mp_obj_new_bool(
0 == ecdsa_verify_digest(&nist256p1, (const uint8_t *)pk.buf,
(const uint8_t *)sig.buf + offset,
(const uint8_t *)dig.buf));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_nist256p1_verify_obj, mod_trezorcrypto_nist256p1_verify);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_nist256p1_verify_obj,
mod_trezorcrypto_nist256p1_verify);
/// def verify_recover(signature: bytes, digest: bytes) -> bytes:
/// '''
/// Uses signature of the digest to verify the digest and recover the public key.
/// Returns public key on success, None on failure.
/// Uses signature of the digest to verify the digest and recover the public
/// key. Returns public key on success, None on failure.
/// '''
STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify_recover(mp_obj_t signature, mp_obj_t digest) {
STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify_recover(mp_obj_t signature,
mp_obj_t digest) {
mp_buffer_info_t sig, dig;
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ);
mp_get_buffer_raise(digest, &dig, MP_BUFFER_READ);
@ -134,7 +162,9 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify_recover(mp_obj_t signature, mp
bool compressed = (recid >= 4);
recid &= 3;
uint8_t out[65];
if (0 == ecdsa_recover_pub_from_sig(&nist256p1, out, (const uint8_t *)sig.buf + 1, (const uint8_t *)dig.buf, recid)) {
if (0 == ecdsa_recover_pub_from_sig(&nist256p1, out,
(const uint8_t *)sig.buf + 1,
(const uint8_t *)dig.buf, recid)) {
if (compressed) {
out[0] = 0x02 | (out[64] & 1);
return mp_obj_new_bytes(out, 33);
@ -144,14 +174,16 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_verify_recover(mp_obj_t signature, mp
return mp_const_none;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nist256p1_verify_recover_obj, mod_trezorcrypto_nist256p1_verify_recover);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nist256p1_verify_recover_obj,
mod_trezorcrypto_nist256p1_verify_recover);
/// def multiply(secret_key: bytes, public_key: bytes) -> bytes:
/// '''
/// Multiplies point defined by public_key with scalar defined by secret_key.
/// Useful for ECDH.
/// Multiplies point defined by public_key with scalar defined by
/// secret_key. Useful for ECDH.
/// '''
STATIC mp_obj_t mod_trezorcrypto_nist256p1_multiply(mp_obj_t secret_key, mp_obj_t public_key) {
STATIC mp_obj_t mod_trezorcrypto_nist256p1_multiply(mp_obj_t secret_key,
mp_obj_t public_key) {
mp_buffer_info_t sk, pk;
mp_get_buffer_raise(secret_key, &sk, MP_BUFFER_READ);
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
@ -162,25 +194,34 @@ STATIC mp_obj_t mod_trezorcrypto_nist256p1_multiply(mp_obj_t secret_key, mp_obj_
mp_raise_ValueError("Invalid length of public key");
}
uint8_t out[65];
if (0 != ecdh_multiply(&nist256p1, (const uint8_t *)sk.buf, (const uint8_t *)pk.buf, out)) {
if (0 != ecdh_multiply(&nist256p1, (const uint8_t *)sk.buf,
(const uint8_t *)pk.buf, out)) {
mp_raise_ValueError("Multiply failed");
}
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nist256p1_multiply_obj, mod_trezorcrypto_nist256p1_multiply);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_nist256p1_multiply_obj,
mod_trezorcrypto_nist256p1_multiply);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_nist256p1_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_nist256p1) },
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_generate_secret_obj) },
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_publickey_obj) },
{ MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_sign_obj) },
{ MP_ROM_QSTR(MP_QSTR_verify), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_verify_obj) },
{ MP_ROM_QSTR(MP_QSTR_verify_recover), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_verify_recover_obj) },
{ MP_ROM_QSTR(MP_QSTR_multiply), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_multiply_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_nist256p1)},
{MP_ROM_QSTR(MP_QSTR_generate_secret),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_generate_secret_obj)},
{MP_ROM_QSTR(MP_QSTR_publickey),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_publickey_obj)},
{MP_ROM_QSTR(MP_QSTR_sign),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_sign_obj)},
{MP_ROM_QSTR(MP_QSTR_verify),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_verify_obj)},
{MP_ROM_QSTR(MP_QSTR_verify_recover),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_verify_recover_obj)},
{MP_ROM_QSTR(MP_QSTR_multiply),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_multiply_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_nist256p1_globals, mod_trezorcrypto_nist256p1_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_nist256p1_globals,
mod_trezorcrypto_nist256p1_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_nist256p1_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_nist256p1_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_nist256p1_globals,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "pbkdf2.h"
#include "memzero.h"
#include "pbkdf2.h"
#define PRF_HMAC_SHA256 256
#define PRF_HMAC_SHA512 512
@ -42,11 +42,14 @@ typedef struct _mp_obj_Pbkdf2_t {
STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_update(mp_obj_t self, mp_obj_t data);
/// def __init__(self, prf: int, password: bytes, salt: bytes, iterations: int = None, blocknr: int = 1) -> None:
/// def __init__(self, prf: int, password: bytes, salt: bytes, iterations: int =
/// None, blocknr: int = 1) -> None:
/// '''
/// Create a PBKDF2 context.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 3, 4, false);
mp_obj_Pbkdf2_t *o = m_new_obj(mp_obj_Pbkdf2_t);
o->base.type = type;
@ -70,10 +73,11 @@ STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_make_new(const mp_obj_type_t *type, size
o->prf = trezor_obj_get_uint(args[0]);
if (o->prf == PRF_HMAC_SHA256) {
pbkdf2_hmac_sha256_Init(&(o->ctx256), password.buf, password.len, salt.buf, salt.len, blocknr);
} else
if (o->prf == PRF_HMAC_SHA512) {
pbkdf2_hmac_sha512_Init(&(o->ctx512), password.buf, password.len, salt.buf, salt.len, blocknr);
pbkdf2_hmac_sha256_Init(&(o->ctx256), password.buf, password.len, salt.buf,
salt.len, blocknr);
} else if (o->prf == PRF_HMAC_SHA512) {
pbkdf2_hmac_sha512_Init(&(o->ctx512), password.buf, password.len, salt.buf,
salt.len, blocknr);
} else {
mp_raise_ValueError("Invalid PRF");
}
@ -88,7 +92,8 @@ STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_make_new(const mp_obj_type_t *type, size
/// '''
/// Update a PBKDF2 context.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_update(mp_obj_t self, mp_obj_t iterations) {
STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_update(mp_obj_t self,
mp_obj_t iterations) {
mp_obj_Pbkdf2_t *o = MP_OBJ_TO_PTR(self);
uint32_t iter = trezor_obj_get_uint(iterations);
if (o->prf == PRF_HMAC_SHA256) {
@ -99,7 +104,8 @@ STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_update(mp_obj_t self, mp_obj_t iteration
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Pbkdf2_update_obj, mod_trezorcrypto_Pbkdf2_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Pbkdf2_update_obj,
mod_trezorcrypto_Pbkdf2_update);
/// def key(self) -> bytes:
/// '''
@ -125,7 +131,8 @@ STATIC mp_obj_t mod_trezorcrypto_Pbkdf2_key(mp_obj_t self) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Pbkdf2_key_obj, mod_trezorcrypto_Pbkdf2_key);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Pbkdf2_key_obj,
mod_trezorcrypto_Pbkdf2_key);
STATIC mp_obj_t mod_trezorcrypto_Pbkdf2___del__(mp_obj_t self) {
mp_obj_Pbkdf2_t *o = MP_OBJ_TO_PTR(self);
@ -133,20 +140,24 @@ STATIC mp_obj_t mod_trezorcrypto_Pbkdf2___del__(mp_obj_t self) {
memzero(&(o->ctx512), sizeof(PBKDF2_HMAC_SHA512_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Pbkdf2___del___obj, mod_trezorcrypto_Pbkdf2___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Pbkdf2___del___obj,
mod_trezorcrypto_Pbkdf2___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Pbkdf2_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_key), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_key_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_HMAC_SHA256), MP_OBJ_NEW_SMALL_INT(PRF_HMAC_SHA256) },
{ MP_ROM_QSTR(MP_QSTR_HMAC_SHA512), MP_OBJ_NEW_SMALL_INT(PRF_HMAC_SHA512) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_update_obj)},
{MP_ROM_QSTR(MP_QSTR_key), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_key_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2___del___obj)},
{MP_ROM_QSTR(MP_QSTR_HMAC_SHA256), MP_OBJ_NEW_SMALL_INT(PRF_HMAC_SHA256)},
{MP_ROM_QSTR(MP_QSTR_HMAC_SHA512), MP_OBJ_NEW_SMALL_INT(PRF_HMAC_SHA512)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Pbkdf2_locals_dict, mod_trezorcrypto_Pbkdf2_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Pbkdf2_locals_dict,
mod_trezorcrypto_Pbkdf2_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Pbkdf2_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Pbkdf2,
.make_new = mod_trezorcrypto_Pbkdf2_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Pbkdf2_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Pbkdf2_locals_dict,
};

@ -36,7 +36,8 @@ STATIC mp_obj_t mod_trezorcrypto_random_uniform(mp_obj_t n) {
}
return mp_obj_new_int_from_uint(random_uniform(nn));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_uniform_obj, mod_trezorcrypto_random_uniform);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_uniform_obj,
mod_trezorcrypto_random_uniform);
/// def bytes(len: int) -> bytes:
/// '''
@ -52,7 +53,8 @@ STATIC mp_obj_t mod_trezorcrypto_random_bytes(mp_obj_t len) {
random_buffer((uint8_t *)vstr.buf, l);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_bytes_obj, mod_trezorcrypto_random_bytes);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_bytes_obj,
mod_trezorcrypto_random_bytes);
/// def shuffle(data: list) -> None:
/// '''
@ -78,17 +80,22 @@ STATIC mp_obj_t mod_trezorcrypto_random_shuffle(mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_shuffle_obj, mod_trezorcrypto_random_shuffle);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_random_shuffle_obj,
mod_trezorcrypto_random_shuffle);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_random_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_random) },
{ MP_ROM_QSTR(MP_QSTR_uniform), MP_ROM_PTR(&mod_trezorcrypto_random_uniform_obj) },
{ MP_ROM_QSTR(MP_QSTR_bytes), MP_ROM_PTR(&mod_trezorcrypto_random_bytes_obj) },
{ MP_ROM_QSTR(MP_QSTR_shuffle), MP_ROM_PTR(&mod_trezorcrypto_random_shuffle_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_random)},
{MP_ROM_QSTR(MP_QSTR_uniform),
MP_ROM_PTR(&mod_trezorcrypto_random_uniform_obj)},
{MP_ROM_QSTR(MP_QSTR_bytes),
MP_ROM_PTR(&mod_trezorcrypto_random_bytes_obj)},
{MP_ROM_QSTR(MP_QSTR_shuffle),
MP_ROM_PTR(&mod_trezorcrypto_random_shuffle_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_random_globals, mod_trezorcrypto_random_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_random_globals,
mod_trezorcrypto_random_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_random_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_random_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_random_globals,
};

@ -36,7 +36,9 @@ typedef struct _mp_obj_Rfc6979_t {
/// '''
/// Initialize RFC6979 context from secret key and a hash.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Rfc6979_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Rfc6979_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 2, 2, false);
mp_obj_Rfc6979_t *o = m_new_obj(mp_obj_Rfc6979_t);
o->base.type = type;
@ -63,16 +65,18 @@ STATIC mp_obj_t mod_trezorcrypto_Rfc6979_next(mp_obj_t self) {
generate_rfc6979(out, &(o->rng));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Rfc6979_next_obj, mod_trezorcrypto_Rfc6979_next);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Rfc6979_next_obj,
mod_trezorcrypto_Rfc6979_next);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Rfc6979_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&mod_trezorcrypto_Rfc6979_next_obj) },
{MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&mod_trezorcrypto_Rfc6979_next_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Rfc6979_locals_dict, mod_trezorcrypto_Rfc6979_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Rfc6979_locals_dict,
mod_trezorcrypto_Rfc6979_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Rfc6979_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Rfc6979,
.make_new = mod_trezorcrypto_Rfc6979_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Rfc6979_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Rfc6979_locals_dict,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "ripemd160.h"
#include "memzero.h"
#include "ripemd160.h"
/// package: trezorcrypto.__init__
@ -39,7 +39,9 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Ripemd160_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Ripemd160_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Ripemd160_t *o = m_new_obj(mp_obj_Ripemd160_t);
o->base.type = type;
@ -55,7 +57,8 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_make_new(const mp_obj_type_t *type, s
/// '''
/// Update the hash context with hashed data.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self, mp_obj_t data) {
STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self,
mp_obj_t data) {
mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t msg;
mp_get_buffer_raise(data, &msg, MP_BUFFER_READ);
@ -64,7 +67,8 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_update(mp_obj_t self, mp_obj_t data)
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Ripemd160_update_obj, mod_trezorcrypto_Ripemd160_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Ripemd160_update_obj,
mod_trezorcrypto_Ripemd160_update);
/// def digest(self) -> bytes:
/// '''
@ -79,27 +83,36 @@ STATIC mp_obj_t mod_trezorcrypto_Ripemd160_digest(mp_obj_t self) {
memzero(&ctx, sizeof(RIPEMD160_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160_digest_obj, mod_trezorcrypto_Ripemd160_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160_digest_obj,
mod_trezorcrypto_Ripemd160_digest);
STATIC mp_obj_t mod_trezorcrypto_Ripemd160___del__(mp_obj_t self) {
mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(RIPEMD160_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160___del___obj, mod_trezorcrypto_Ripemd160___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Ripemd160___del___obj,
mod_trezorcrypto_Ripemd160___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Ripemd160_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Ripemd160_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Ripemd160_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Ripemd160___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(RIPEMD160_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(RIPEMD160_DIGEST_LENGTH) },
STATIC const mp_rom_map_elem_t
mod_trezorcrypto_Ripemd160_locals_dict_table[] = {
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Ripemd160_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Ripemd160_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Ripemd160___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(RIPEMD160_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(RIPEMD160_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Ripemd160_locals_dict, mod_trezorcrypto_Ripemd160_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Ripemd160_locals_dict,
mod_trezorcrypto_Ripemd160_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Ripemd160_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Ripemd160,
.make_new = mod_trezorcrypto_Ripemd160_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Ripemd160_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Ripemd160_locals_dict,
};

@ -33,19 +33,33 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_generate_secret() {
for (;;) {
random_buffer(out, 32);
// check whether secret > 0 && secret < curve_order
if (0 == memcmp(out, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32)) continue;
if (0 <= memcmp(out, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41", 32)) continue;
if (0 ==
memcmp(
out,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
32))
continue;
if (0 <=
memcmp(
out,
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE"
"\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41",
32))
continue;
break;
}
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_secp256k1_generate_secret_obj, mod_trezorcrypto_secp256k1_generate_secret);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_secp256k1_generate_secret_obj,
mod_trezorcrypto_secp256k1_generate_secret);
/// def publickey(secret_key: bytes, compressed: bool = True) -> bytes:
/// '''
/// Computes public key from secret key.
/// '''
STATIC mp_obj_t mod_trezorcrypto_secp256k1_publickey(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_secp256k1_publickey(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t sk;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ);
if (sk.len != 32) {
@ -62,10 +76,11 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_publickey(size_t n_args, const mp_obj
return mp_obj_new_bytes(out, sizeof(out));
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_secp256k1_publickey_obj, 1, 2, mod_trezorcrypto_secp256k1_publickey);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(
mod_trezorcrypto_secp256k1_publickey_obj, 1, 2,
mod_trezorcrypto_secp256k1_publickey);
static int ethereum_is_canonical(uint8_t v, uint8_t signature[64])
{
static int ethereum_is_canonical(uint8_t v, uint8_t signature[64]) {
(void)signature;
return (v & 2) == 0;
}
@ -74,11 +89,13 @@ enum {
CANONICAL_SIG_ETHEREUM = 1,
};
/// def sign(secret_key: bytes, digest: bytes, compressed: bool = True, canonical: int = None) -> bytes:
/// def sign(secret_key: bytes, digest: bytes, compressed: bool = True,
/// canonical: int = None) -> bytes:
/// '''
/// Uses secret key to produce the signature of the digest.
/// '''
STATIC mp_obj_t mod_trezorcrypto_secp256k1_sign(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_secp256k1_sign(size_t n_args,
const mp_obj_t *args) {
mp_buffer_info_t sk, dig;
mp_get_buffer_raise(args[0], &sk, MP_BUFFER_READ);
mp_get_buffer_raise(args[1], &dig, MP_BUFFER_READ);
@ -97,20 +114,26 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_sign(size_t n_args, const mp_obj_t *a
mp_raise_ValueError("Invalid length of digest");
}
uint8_t out[65], pby;
if (0 != ecdsa_sign_digest(&secp256k1, (const uint8_t *)sk.buf, (const uint8_t *)dig.buf, out + 1, &pby, is_canonical)) {
if (0 != ecdsa_sign_digest(&secp256k1, (const uint8_t *)sk.buf,
(const uint8_t *)dig.buf, out + 1, &pby,
is_canonical)) {
mp_raise_ValueError("Signing failed");
}
out[0] = 27 + pby + compressed * 4;
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_secp256k1_sign_obj, 2, 4, mod_trezorcrypto_secp256k1_sign);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_secp256k1_sign_obj,
2, 4,
mod_trezorcrypto_secp256k1_sign);
/// def verify(public_key: bytes, signature: bytes, digest: bytes) -> bool:
/// '''
/// Uses public key to verify the signature of the digest.
/// Returns True on success.
/// '''
STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify(mp_obj_t public_key, mp_obj_t signature, mp_obj_t digest) {
STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify(mp_obj_t public_key,
mp_obj_t signature,
mp_obj_t digest) {
mp_buffer_info_t pk, sig, dig;
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ);
@ -125,16 +148,21 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify(mp_obj_t public_key, mp_obj_t
if (dig.len != 32) {
mp_raise_ValueError("Invalid length of digest");
}
return mp_obj_new_bool(0 == ecdsa_verify_digest(&secp256k1, (const uint8_t *)pk.buf, (const uint8_t *)sig.buf + offset, (const uint8_t *)dig.buf));
return mp_obj_new_bool(
0 == ecdsa_verify_digest(&secp256k1, (const uint8_t *)pk.buf,
(const uint8_t *)sig.buf + offset,
(const uint8_t *)dig.buf));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_secp256k1_verify_obj, mod_trezorcrypto_secp256k1_verify);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorcrypto_secp256k1_verify_obj,
mod_trezorcrypto_secp256k1_verify);
/// def verify_recover(signature: bytes, digest: bytes) -> bytes:
/// '''
/// Uses signature of the digest to verify the digest and recover the public key.
/// Returns public key on success, None on failure.
/// Uses signature of the digest to verify the digest and recover the public
/// key. Returns public key on success, None on failure.
/// '''
STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify_recover(mp_obj_t signature, mp_obj_t digest) {
STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify_recover(mp_obj_t signature,
mp_obj_t digest) {
mp_buffer_info_t sig, dig;
mp_get_buffer_raise(signature, &sig, MP_BUFFER_READ);
mp_get_buffer_raise(digest, &dig, MP_BUFFER_READ);
@ -151,7 +179,9 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify_recover(mp_obj_t signature, mp
bool compressed = (recid >= 4);
recid &= 3;
uint8_t out[65];
if (0 == ecdsa_recover_pub_from_sig(&secp256k1, out, (const uint8_t *)sig.buf + 1, (const uint8_t *)dig.buf, recid)) {
if (0 == ecdsa_recover_pub_from_sig(&secp256k1, out,
(const uint8_t *)sig.buf + 1,
(const uint8_t *)dig.buf, recid)) {
if (compressed) {
out[0] = 0x02 | (out[64] & 1);
return mp_obj_new_bytes(out, 33);
@ -161,14 +191,16 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_verify_recover(mp_obj_t signature, mp
return mp_const_none;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_secp256k1_verify_recover_obj, mod_trezorcrypto_secp256k1_verify_recover);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_secp256k1_verify_recover_obj,
mod_trezorcrypto_secp256k1_verify_recover);
/// def multiply(secret_key: bytes, public_key: bytes) -> bytes:
/// '''
/// Multiplies point defined by public_key with scalar defined by secret_key.
/// Useful for ECDH.
/// Multiplies point defined by public_key with scalar defined by
/// secret_key. Useful for ECDH.
/// '''
STATIC mp_obj_t mod_trezorcrypto_secp256k1_multiply(mp_obj_t secret_key, mp_obj_t public_key) {
STATIC mp_obj_t mod_trezorcrypto_secp256k1_multiply(mp_obj_t secret_key,
mp_obj_t public_key) {
mp_buffer_info_t sk, pk;
mp_get_buffer_raise(secret_key, &sk, MP_BUFFER_READ);
mp_get_buffer_raise(public_key, &pk, MP_BUFFER_READ);
@ -179,26 +211,36 @@ STATIC mp_obj_t mod_trezorcrypto_secp256k1_multiply(mp_obj_t secret_key, mp_obj_
mp_raise_ValueError("Invalid length of public key");
}
uint8_t out[65];
if (0 != ecdh_multiply(&secp256k1, (const uint8_t *)sk.buf, (const uint8_t *)pk.buf, out)) {
if (0 != ecdh_multiply(&secp256k1, (const uint8_t *)sk.buf,
(const uint8_t *)pk.buf, out)) {
mp_raise_ValueError("Multiply failed");
}
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_secp256k1_multiply_obj, mod_trezorcrypto_secp256k1_multiply);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_secp256k1_multiply_obj,
mod_trezorcrypto_secp256k1_multiply);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_secp256k1_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_secp256k1) },
{ MP_ROM_QSTR(MP_QSTR_generate_secret), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_generate_secret_obj) },
{ MP_ROM_QSTR(MP_QSTR_publickey), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_publickey_obj) },
{ MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_sign_obj) },
{ MP_ROM_QSTR(MP_QSTR_verify), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_verify_obj) },
{ MP_ROM_QSTR(MP_QSTR_verify_recover), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_verify_recover_obj) },
{ MP_ROM_QSTR(MP_QSTR_multiply), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_multiply_obj) },
{ MP_ROM_QSTR(MP_QSTR_CANONICAL_SIG_ETHEREUM), MP_OBJ_NEW_SMALL_INT(CANONICAL_SIG_ETHEREUM) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_secp256k1)},
{MP_ROM_QSTR(MP_QSTR_generate_secret),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_generate_secret_obj)},
{MP_ROM_QSTR(MP_QSTR_publickey),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_publickey_obj)},
{MP_ROM_QSTR(MP_QSTR_sign),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_sign_obj)},
{MP_ROM_QSTR(MP_QSTR_verify),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_verify_obj)},
{MP_ROM_QSTR(MP_QSTR_verify_recover),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_verify_recover_obj)},
{MP_ROM_QSTR(MP_QSTR_multiply),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_multiply_obj)},
{MP_ROM_QSTR(MP_QSTR_CANONICAL_SIG_ETHEREUM),
MP_OBJ_NEW_SMALL_INT(CANONICAL_SIG_ETHEREUM)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_secp256k1_globals, mod_trezorcrypto_secp256k1_globals_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_secp256k1_globals,
mod_trezorcrypto_secp256k1_globals_table);
STATIC const mp_obj_module_t mod_trezorcrypto_secp256k1_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mod_trezorcrypto_secp256k1_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorcrypto_secp256k1_globals,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "sha2.h"
#include "memzero.h"
#include "sha2.h"
/// package: trezorcrypto.__init__
@ -39,7 +39,9 @@ STATIC mp_obj_t mod_trezorcrypto_Sha1_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha1_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Sha1_t *o = m_new_obj(mp_obj_Sha1_t);
o->base.type = type;
@ -64,7 +66,8 @@ STATIC mp_obj_t mod_trezorcrypto_Sha1_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha1_update_obj, mod_trezorcrypto_Sha1_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha1_update_obj,
mod_trezorcrypto_Sha1_update);
/// def digest(self) -> bytes:
/// '''
@ -79,27 +82,34 @@ STATIC mp_obj_t mod_trezorcrypto_Sha1_digest(mp_obj_t self) {
memzero(&ctx, sizeof(SHA1_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha1_digest_obj, mod_trezorcrypto_Sha1_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha1_digest_obj,
mod_trezorcrypto_Sha1_digest);
STATIC mp_obj_t mod_trezorcrypto_Sha1___del__(mp_obj_t self) {
mp_obj_Sha1_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(SHA1_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha1___del___obj, mod_trezorcrypto_Sha1___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha1___del___obj,
mod_trezorcrypto_Sha1___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Sha1_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Sha1_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Sha1_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Sha1___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SHA1_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(SHA1_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Sha1_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Sha1_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Sha1___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SHA1_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(SHA1_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha1_locals_dict, mod_trezorcrypto_Sha1_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha1_locals_dict,
mod_trezorcrypto_Sha1_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Sha1_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Sha1,
.make_new = mod_trezorcrypto_Sha1_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Sha1_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Sha1_locals_dict,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "sha2.h"
#include "memzero.h"
#include "sha2.h"
/// package: trezorcrypto.__init__
@ -39,7 +39,9 @@ STATIC mp_obj_t mod_trezorcrypto_Sha256_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha256_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Sha256_t *o = m_new_obj(mp_obj_Sha256_t);
o->base.type = type;
@ -64,7 +66,8 @@ STATIC mp_obj_t mod_trezorcrypto_Sha256_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha256_update_obj, mod_trezorcrypto_Sha256_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha256_update_obj,
mod_trezorcrypto_Sha256_update);
/// def digest(self) -> bytes:
/// '''
@ -79,27 +82,35 @@ STATIC mp_obj_t mod_trezorcrypto_Sha256_digest(mp_obj_t self) {
memzero(&ctx, sizeof(SHA256_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha256_digest_obj, mod_trezorcrypto_Sha256_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha256_digest_obj,
mod_trezorcrypto_Sha256_digest);
STATIC mp_obj_t mod_trezorcrypto_Sha256___del__(mp_obj_t self) {
mp_obj_Sha256_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(SHA256_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha256___del___obj, mod_trezorcrypto_Sha256___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha256___del___obj,
mod_trezorcrypto_Sha256___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Sha256_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Sha256_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Sha256_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Sha256___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SHA256_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(SHA256_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Sha256_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Sha256_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Sha256___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(SHA256_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(SHA256_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha256_locals_dict, mod_trezorcrypto_Sha256_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha256_locals_dict,
mod_trezorcrypto_Sha256_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Sha256_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Sha256,
.make_new = mod_trezorcrypto_Sha256_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Sha256_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Sha256_locals_dict,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "sha3.h"
#include "memzero.h"
#include "sha3.h"
/// package: trezorcrypto.__init__
@ -40,7 +40,9 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_256_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha3_256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha3_256_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, true);
mp_obj_Sha3_256_t *o = m_new_obj(mp_obj_Sha3_256_t);
o->base.type = type;
@ -48,16 +50,17 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_256_make_new(const mp_obj_type_t *type, si
sha3_256_Init(&(o->ctx));
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_keccak, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
{MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_none}},
{MP_QSTR_keccak, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
if (vals[1].u_obj != MP_OBJ_NULL){
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
if (vals[1].u_obj != MP_OBJ_NULL) {
o->keccak = mp_obj_is_true(vals[1].u_obj);
}
if (vals[0].u_obj != mp_const_none){
if (vals[0].u_obj != mp_const_none) {
mod_trezorcrypto_Sha3_256_update(MP_OBJ_FROM_PTR(o), vals[0].u_obj);
}
return MP_OBJ_FROM_PTR(o);
@ -76,7 +79,8 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_256_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha3_256_update_obj, mod_trezorcrypto_Sha3_256_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha3_256_update_obj,
mod_trezorcrypto_Sha3_256_update);
/// def digest(self) -> bytes:
/// '''
@ -95,14 +99,15 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_256_digest(mp_obj_t self) {
memzero(&ctx, sizeof(SHA3_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_256_digest_obj, mod_trezorcrypto_Sha3_256_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_256_digest_obj,
mod_trezorcrypto_Sha3_256_digest);
/// def copy(self) -> sha3:
/// '''
/// Returns the copy of the digest object with the current state
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha3_256_copy(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha3_256_copy(size_t n_args,
const mp_obj_t *args) {
mp_obj_Sha3_256_t *o = MP_OBJ_TO_PTR(args[0]);
mp_obj_Sha3_256_t *out = m_new_obj(mp_obj_Sha3_256_t);
out->base.type = o->base.type;
@ -110,28 +115,38 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_256_copy(size_t n_args, const mp_obj_t *ar
memcpy(&(out->ctx), &(o->ctx), sizeof(SHA3_CTX));
return MP_OBJ_FROM_PTR(out);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_Sha3_256_copy_obj, 1, 1, mod_trezorcrypto_Sha3_256_copy);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_Sha3_256_copy_obj,
1, 1,
mod_trezorcrypto_Sha3_256_copy);
STATIC mp_obj_t mod_trezorcrypto_Sha3_256___del__(mp_obj_t self) {
mp_obj_Sha3_256_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(SHA3_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_256___del___obj, mod_trezorcrypto_Sha3_256___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_256___del___obj,
mod_trezorcrypto_Sha3_256___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Sha3_256_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR_copy), MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_copy_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Sha3_256___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SHA3_256_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(SHA3_256_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_digest_obj)},
{MP_ROM_QSTR(MP_QSTR_copy),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_copy_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_256___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(SHA3_256_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(SHA3_256_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha3_256_locals_dict, mod_trezorcrypto_Sha3_256_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha3_256_locals_dict,
mod_trezorcrypto_Sha3_256_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Sha3_256_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Sha3_256,
.make_new = mod_trezorcrypto_Sha3_256_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Sha3_256_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Sha3_256_locals_dict,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "sha3.h"
#include "memzero.h"
#include "sha3.h"
/// package: trezorcrypto.__init__
@ -40,7 +40,9 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_512_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha3_512_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha3_512_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, true);
mp_obj_Sha3_512_t *o = m_new_obj(mp_obj_Sha3_512_t);
o->base.type = type;
@ -48,16 +50,17 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_512_make_new(const mp_obj_type_t *type, si
sha3_512_Init(&(o->ctx));
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_keccak, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
{MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_none}},
{MP_QSTR_keccak, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
if (vals[1].u_obj != MP_OBJ_NULL){
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
if (vals[1].u_obj != MP_OBJ_NULL) {
o->keccak = mp_obj_is_true(vals[1].u_obj);
}
if (vals[0].u_obj != mp_const_none){
if (vals[0].u_obj != mp_const_none) {
mod_trezorcrypto_Sha3_512_update(MP_OBJ_FROM_PTR(o), vals[0].u_obj);
}
return MP_OBJ_FROM_PTR(o);
@ -76,7 +79,8 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_512_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha3_512_update_obj, mod_trezorcrypto_Sha3_512_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha3_512_update_obj,
mod_trezorcrypto_Sha3_512_update);
/// def digest(self) -> bytes:
/// '''
@ -95,14 +99,15 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_512_digest(mp_obj_t self) {
memzero(&ctx, sizeof(SHA3_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_512_digest_obj, mod_trezorcrypto_Sha3_512_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_512_digest_obj,
mod_trezorcrypto_Sha3_512_digest);
/// def copy(self) -> sha3:
/// '''
/// Returns the copy of the digest object with the current state
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha3_512_copy(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha3_512_copy(size_t n_args,
const mp_obj_t *args) {
mp_obj_Sha3_512_t *o = MP_OBJ_TO_PTR(args[0]);
mp_obj_Sha3_512_t *out = m_new_obj(mp_obj_Sha3_512_t);
out->base.type = o->base.type;
@ -110,28 +115,38 @@ STATIC mp_obj_t mod_trezorcrypto_Sha3_512_copy(size_t n_args, const mp_obj_t *ar
memcpy(&(out->ctx), &(o->ctx), sizeof(SHA3_CTX));
return MP_OBJ_FROM_PTR(out);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_Sha3_512_copy_obj, 1, 1, mod_trezorcrypto_Sha3_512_copy);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_Sha3_512_copy_obj,
1, 1,
mod_trezorcrypto_Sha3_512_copy);
STATIC mp_obj_t mod_trezorcrypto_Sha3_512___del__(mp_obj_t self) {
mp_obj_Sha3_512_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(SHA3_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_512___del___obj, mod_trezorcrypto_Sha3_512___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha3_512___del___obj,
mod_trezorcrypto_Sha3_512___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Sha3_512_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR_copy), MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_copy_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Sha3_512___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SHA3_512_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(SHA3_512_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_digest_obj)},
{MP_ROM_QSTR(MP_QSTR_copy),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_copy_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_512___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(SHA3_512_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(SHA3_512_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha3_512_locals_dict, mod_trezorcrypto_Sha3_512_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha3_512_locals_dict,
mod_trezorcrypto_Sha3_512_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Sha3_512_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Sha3_512,
.make_new = mod_trezorcrypto_Sha3_512_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Sha3_512_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Sha3_512_locals_dict,
};

@ -19,8 +19,8 @@
#include "py/objstr.h"
#include "sha2.h"
#include "memzero.h"
#include "sha2.h"
/// package: trezorcrypto.__init__
@ -39,7 +39,9 @@ STATIC mp_obj_t mod_trezorcrypto_Sha512_update(mp_obj_t self, mp_obj_t data);
/// '''
/// Creates a hash context object.
/// '''
STATIC mp_obj_t mod_trezorcrypto_Sha512_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorcrypto_Sha512_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Sha512_t *o = m_new_obj(mp_obj_Sha512_t);
o->base.type = type;
@ -63,7 +65,8 @@ STATIC mp_obj_t mod_trezorcrypto_Sha512_update(mp_obj_t self, mp_obj_t data) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha512_update_obj, mod_trezorcrypto_Sha512_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_Sha512_update_obj,
mod_trezorcrypto_Sha512_update);
/// def digest(self) -> bytes:
/// '''
@ -78,27 +81,35 @@ STATIC mp_obj_t mod_trezorcrypto_Sha512_digest(mp_obj_t self) {
memzero(&ctx, sizeof(SHA512_CTX));
return mp_obj_new_bytes(out, sizeof(out));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha512_digest_obj, mod_trezorcrypto_Sha512_digest);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha512_digest_obj,
mod_trezorcrypto_Sha512_digest);
STATIC mp_obj_t mod_trezorcrypto_Sha512___del__(mp_obj_t self) {
mp_obj_Sha512_t *o = MP_OBJ_TO_PTR(self);
memzero(&(o->ctx), sizeof(SHA512_CTX));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha512___del___obj, mod_trezorcrypto_Sha512___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_Sha512___del___obj,
mod_trezorcrypto_Sha512___del__);
STATIC const mp_rom_map_elem_t mod_trezorcrypto_Sha512_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_trezorcrypto_Sha512_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_trezorcrypto_Sha512_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorcrypto_Sha512___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SHA512_BLOCK_LENGTH) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(SHA512_DIGEST_LENGTH) },
{MP_ROM_QSTR(MP_QSTR_update),
MP_ROM_PTR(&mod_trezorcrypto_Sha512_update_obj)},
{MP_ROM_QSTR(MP_QSTR_digest),
MP_ROM_PTR(&mod_trezorcrypto_Sha512_digest_obj)},
{MP_ROM_QSTR(MP_QSTR___del__),
MP_ROM_PTR(&mod_trezorcrypto_Sha512___del___obj)},
{MP_ROM_QSTR(MP_QSTR_block_size),
MP_OBJ_NEW_SMALL_INT(SHA512_BLOCK_LENGTH)},
{MP_ROM_QSTR(MP_QSTR_digest_size),
MP_OBJ_NEW_SMALL_INT(SHA512_DIGEST_LENGTH)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha512_locals_dict, mod_trezorcrypto_Sha512_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_Sha512_locals_dict,
mod_trezorcrypto_Sha512_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorcrypto_Sha512_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Sha512,
.make_new = mod_trezorcrypto_Sha512_make_new,
.locals_dict = (void*)&mod_trezorcrypto_Sha512_locals_dict,
.locals_dict = (void *)&mod_trezorcrypto_Sha512_locals_dict,
};

@ -17,9 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "py/runtime.h"
@ -35,9 +35,10 @@
#include "modtrezorcrypto-crc.h"
#include "modtrezorcrypto-curve25519.h"
#include "modtrezorcrypto-ed25519.h"
#include "modtrezorcrypto-nist256p1.h"
#include "modtrezorcrypto-groestl.h"
#include "modtrezorcrypto-monero.h"
#include "modtrezorcrypto-nem.h"
#include "modtrezorcrypto-nist256p1.h"
#include "modtrezorcrypto-pbkdf2.h"
#include "modtrezorcrypto-random.h"
#include "modtrezorcrypto-rfc6979.h"
@ -45,42 +46,52 @@
#include "modtrezorcrypto-secp256k1.h"
#include "modtrezorcrypto-sha1.h"
#include "modtrezorcrypto-sha256.h"
#include "modtrezorcrypto-sha512.h"
#include "modtrezorcrypto-sha3-256.h"
#include "modtrezorcrypto-sha3-512.h"
#include "modtrezorcrypto-monero.h"
#include "modtrezorcrypto-sha512.h"
STATIC const mp_rom_map_elem_t mp_module_trezorcrypto_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorcrypto) },
{ MP_ROM_QSTR(MP_QSTR_aes), MP_ROM_PTR(&mod_trezorcrypto_AES_type) },
{ MP_ROM_QSTR(MP_QSTR_bip32), MP_ROM_PTR(&mod_trezorcrypto_bip32_module) },
{ MP_ROM_QSTR(MP_QSTR_bip39), MP_ROM_PTR(&mod_trezorcrypto_bip39_module) },
{ MP_ROM_QSTR(MP_QSTR_blake256), MP_ROM_PTR(&mod_trezorcrypto_Blake256_type) },
{ MP_ROM_QSTR(MP_QSTR_blake2b), MP_ROM_PTR(&mod_trezorcrypto_Blake2b_type) },
{ MP_ROM_QSTR(MP_QSTR_blake2s), MP_ROM_PTR(&mod_trezorcrypto_Blake2s_type) },
{ MP_ROM_QSTR(MP_QSTR_chacha20poly1305), MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_type) },
{ MP_ROM_QSTR(MP_QSTR_crc), MP_ROM_PTR(&mod_trezorcrypto_crc_module) },
{ MP_ROM_QSTR(MP_QSTR_curve25519), MP_ROM_PTR(&mod_trezorcrypto_curve25519_module) },
{ MP_ROM_QSTR(MP_QSTR_ed25519), MP_ROM_PTR(&mod_trezorcrypto_ed25519_module) },
{ MP_ROM_QSTR(MP_QSTR_monero), MP_ROM_PTR(&mod_trezorcrypto_monero_module) },
{ MP_ROM_QSTR(MP_QSTR_nist256p1), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_module) },
{ MP_ROM_QSTR(MP_QSTR_groestl512), MP_ROM_PTR(&mod_trezorcrypto_Groestl512_type) },
{ MP_ROM_QSTR(MP_QSTR_nem), MP_ROM_PTR(&mod_trezorcrypto_nem_module) },
{ MP_ROM_QSTR(MP_QSTR_pbkdf2), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_type) },
{ MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_trezorcrypto_random_module) },
{ MP_ROM_QSTR(MP_QSTR_rfc6979), MP_ROM_PTR(&mod_trezorcrypto_Rfc6979_type) },
{ MP_ROM_QSTR(MP_QSTR_ripemd160), MP_ROM_PTR(&mod_trezorcrypto_Ripemd160_type) },
{ MP_ROM_QSTR(MP_QSTR_secp256k1), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_module) },
{ MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&mod_trezorcrypto_Sha1_type) },
{ MP_ROM_QSTR(MP_QSTR_sha256), MP_ROM_PTR(&mod_trezorcrypto_Sha256_type) },
{ MP_ROM_QSTR(MP_QSTR_sha512), MP_ROM_PTR(&mod_trezorcrypto_Sha512_type) },
{ MP_ROM_QSTR(MP_QSTR_sha3_256), MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_type) },
{ MP_ROM_QSTR(MP_QSTR_sha3_512), MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_type) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorcrypto)},
{MP_ROM_QSTR(MP_QSTR_aes), MP_ROM_PTR(&mod_trezorcrypto_AES_type)},
{MP_ROM_QSTR(MP_QSTR_bip32), MP_ROM_PTR(&mod_trezorcrypto_bip32_module)},
{MP_ROM_QSTR(MP_QSTR_bip39), MP_ROM_PTR(&mod_trezorcrypto_bip39_module)},
{MP_ROM_QSTR(MP_QSTR_blake256),
MP_ROM_PTR(&mod_trezorcrypto_Blake256_type)},
{MP_ROM_QSTR(MP_QSTR_blake2b), MP_ROM_PTR(&mod_trezorcrypto_Blake2b_type)},
{MP_ROM_QSTR(MP_QSTR_blake2s), MP_ROM_PTR(&mod_trezorcrypto_Blake2s_type)},
{MP_ROM_QSTR(MP_QSTR_chacha20poly1305),
MP_ROM_PTR(&mod_trezorcrypto_ChaCha20Poly1305_type)},
{MP_ROM_QSTR(MP_QSTR_crc), MP_ROM_PTR(&mod_trezorcrypto_crc_module)},
{MP_ROM_QSTR(MP_QSTR_curve25519),
MP_ROM_PTR(&mod_trezorcrypto_curve25519_module)},
{MP_ROM_QSTR(MP_QSTR_ed25519),
MP_ROM_PTR(&mod_trezorcrypto_ed25519_module)},
{MP_ROM_QSTR(MP_QSTR_monero), MP_ROM_PTR(&mod_trezorcrypto_monero_module)},
{MP_ROM_QSTR(MP_QSTR_nist256p1),
MP_ROM_PTR(&mod_trezorcrypto_nist256p1_module)},
{MP_ROM_QSTR(MP_QSTR_groestl512),
MP_ROM_PTR(&mod_trezorcrypto_Groestl512_type)},
{MP_ROM_QSTR(MP_QSTR_nem), MP_ROM_PTR(&mod_trezorcrypto_nem_module)},
{MP_ROM_QSTR(MP_QSTR_pbkdf2), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_type)},
{MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_trezorcrypto_random_module)},
{MP_ROM_QSTR(MP_QSTR_rfc6979), MP_ROM_PTR(&mod_trezorcrypto_Rfc6979_type)},
{MP_ROM_QSTR(MP_QSTR_ripemd160),
MP_ROM_PTR(&mod_trezorcrypto_Ripemd160_type)},
{MP_ROM_QSTR(MP_QSTR_secp256k1),
MP_ROM_PTR(&mod_trezorcrypto_secp256k1_module)},
{MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&mod_trezorcrypto_Sha1_type)},
{MP_ROM_QSTR(MP_QSTR_sha256), MP_ROM_PTR(&mod_trezorcrypto_Sha256_type)},
{MP_ROM_QSTR(MP_QSTR_sha512), MP_ROM_PTR(&mod_trezorcrypto_Sha512_type)},
{MP_ROM_QSTR(MP_QSTR_sha3_256),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_256_type)},
{MP_ROM_QSTR(MP_QSTR_sha3_512),
MP_ROM_PTR(&mod_trezorcrypto_Sha3_512_type)},
};
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorcrypto_globals, mp_module_trezorcrypto_globals_table);
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorcrypto_globals,
mp_module_trezorcrypto_globals_table);
const mp_obj_module_t mp_module_trezorcrypto = {
.base = { &mp_type_module },
.base = {&mp_type_module},
.globals = (mp_obj_dict_t*)&mp_module_trezorcrypto_globals,
};

@ -20,7 +20,4 @@
#include "rand.h"
#include "rng.h"
uint32_t random32(void)
{
return rng_get();
}
uint32_t random32(void) { return rng_get(); }

@ -31,7 +31,9 @@ typedef struct _mp_obj_FlashOTP_t {
/// def __init__(self) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_FlashOTP_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_FlashOTP_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 0, false);
mp_obj_FlashOTP_t *o = m_new_obj(mp_obj_FlashOTP_t);
o->base.type = type;
@ -42,7 +44,8 @@ STATIC mp_obj_t mod_trezorio_FlashOTP_make_new(const mp_obj_type_t *type, size_t
/// '''
/// Writes data to OTP flash
/// '''
STATIC mp_obj_t mod_trezorio_FlashOTP_write(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_FlashOTP_write(size_t n_args,
const mp_obj_t *args) {
uint8_t block = trezor_obj_get_uint8(args[1]);
uint8_t offset = trezor_obj_get_uint8(args[2]);
mp_buffer_info_t data;
@ -52,13 +55,15 @@ STATIC mp_obj_t mod_trezorio_FlashOTP_write(size_t n_args, const mp_obj_t *args)
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_FlashOTP_write_obj, 4, 4, mod_trezorio_FlashOTP_write);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_FlashOTP_write_obj, 4,
4, mod_trezorio_FlashOTP_write);
/// def FlashOTP.read(self, block: int, offset: int, data: bytearray) -> None:
/// '''
/// Reads data from OTP flash
/// '''
STATIC mp_obj_t mod_trezorio_FlashOTP_read(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_FlashOTP_read(size_t n_args,
const mp_obj_t *args) {
uint8_t block = trezor_obj_get_uint8(args[1]);
uint8_t offset = trezor_obj_get_uint8(args[2]);
mp_buffer_info_t data;
@ -68,7 +73,8 @@ STATIC mp_obj_t mod_trezorio_FlashOTP_read(size_t n_args, const mp_obj_t *args)
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_FlashOTP_read_obj, 4, 4, mod_trezorio_FlashOTP_read);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_FlashOTP_read_obj, 4, 4,
mod_trezorio_FlashOTP_read);
/// def FlashOTP.lock(self, block: int) -> None:
/// '''
@ -81,7 +87,8 @@ STATIC mp_obj_t mod_trezorio_FlashOTP_lock(mp_obj_t self, mp_obj_t block) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashOTP_lock_obj, mod_trezorio_FlashOTP_lock);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashOTP_lock_obj,
mod_trezorio_FlashOTP_lock);
/// def FlashOTP.is_locked(self, block: int) -> bool:
/// '''
@ -91,19 +98,22 @@ STATIC mp_obj_t mod_trezorio_FlashOTP_is_locked(mp_obj_t self, mp_obj_t block) {
uint8_t b = trezor_obj_get_uint8(block);
return (sectrue == flash_otp_is_locked(b)) ? mp_const_true : mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashOTP_is_locked_obj, mod_trezorio_FlashOTP_is_locked);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FlashOTP_is_locked_obj,
mod_trezorio_FlashOTP_is_locked);
STATIC const mp_rom_map_elem_t mod_trezorio_FlashOTP_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mod_trezorio_FlashOTP_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_FlashOTP_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_lock), MP_ROM_PTR(&mod_trezorio_FlashOTP_lock_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_locked), MP_ROM_PTR(&mod_trezorio_FlashOTP_is_locked_obj) },
{MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mod_trezorio_FlashOTP_read_obj)},
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_FlashOTP_write_obj)},
{MP_ROM_QSTR(MP_QSTR_lock), MP_ROM_PTR(&mod_trezorio_FlashOTP_lock_obj)},
{MP_ROM_QSTR(MP_QSTR_is_locked),
MP_ROM_PTR(&mod_trezorio_FlashOTP_is_locked_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_FlashOTP_locals_dict, mod_trezorio_FlashOTP_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_FlashOTP_locals_dict,
mod_trezorio_FlashOTP_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_FlashOTP_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_FlashOTP,
.make_new = mod_trezorio_FlashOTP_make_new,
.locals_dict = (void*)&mod_trezorio_FlashOTP_locals_dict,
.locals_dict = (void *)&mod_trezorio_FlashOTP_locals_dict,
};

@ -37,20 +37,30 @@ typedef struct _mp_obj_HID_t {
/// max_packet_len: int = 64) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_HID_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_HID_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_iface_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_in, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_out, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_subclass, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_polling_interval, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_max_packet_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
{ MP_QSTR_report_desc, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{MP_QSTR_iface_num,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_in,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_out,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_subclass, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_polling_interval, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1}},
{MP_QSTR_max_packet_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64}},
{MP_QSTR_report_desc,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = MP_OBJ_NULL}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
const mp_int_t iface_num = vals[0].u_int;
const mp_int_t ep_in = vals[1].u_int;
@ -62,7 +72,8 @@ STATIC mp_obj_t mod_trezorio_HID_make_new(const mp_obj_type_t *type, size_t n_ar
mp_buffer_info_t report_desc;
mp_get_buffer_raise(vals[7].u_obj, &report_desc, MP_BUFFER_READ);
if (report_desc.buf == NULL || report_desc.len == 0 || report_desc.len > 255) {
if (report_desc.buf == NULL || report_desc.len == 0 ||
report_desc.len > 255) {
mp_raise_ValueError("report_desc is invalid");
}
CHECK_PARAM_RANGE(iface_num, 0, 32)
@ -98,7 +109,8 @@ STATIC mp_obj_t mod_trezorio_HID_iface_num(mp_obj_t self) {
mp_obj_HID_t *o = MP_OBJ_TO_PTR(self);
return MP_OBJ_NEW_SMALL_INT(o->info.iface_num);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_HID_iface_num_obj, mod_trezorio_HID_iface_num);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_HID_iface_num_obj,
mod_trezorio_HID_iface_num);
/// def write(self, msg: bytes) -> int:
/// '''
@ -111,17 +123,20 @@ STATIC mp_obj_t mod_trezorio_HID_write(mp_obj_t self, mp_obj_t msg) {
ssize_t r = usb_hid_write(o->info.iface_num, buf.buf, buf.len);
return MP_OBJ_NEW_SMALL_INT(r);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_HID_write_obj, mod_trezorio_HID_write);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_HID_write_obj,
mod_trezorio_HID_write);
STATIC const mp_rom_map_elem_t mod_trezorio_HID_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_iface_num), MP_ROM_PTR(&mod_trezorio_HID_iface_num_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_HID_write_obj) },
{MP_ROM_QSTR(MP_QSTR_iface_num),
MP_ROM_PTR(&mod_trezorio_HID_iface_num_obj)},
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_HID_write_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_HID_locals_dict, mod_trezorio_HID_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_HID_locals_dict,
mod_trezorio_HID_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_HID_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_HID,
.make_new = mod_trezorio_HID_make_new,
.locals_dict = (void*)&mod_trezorio_HID_locals_dict,
.locals_dict = (void *)&mod_trezorio_HID_locals_dict,
};

@ -18,21 +18,13 @@
*/
#include <string.h>
#include <unistd.h>
#include "embed/extmod/trezorobj.h"
#include "usb.h"
#define TOUCH_IFACE (255)
#define POLL_READ (0x0000)
#define POLL_WRITE (0x0100)
#define CHECK_PARAM_RANGE(value, minimum, maximum) \
if (value < minimum || value > maximum) { \
mp_raise_ValueError(#value " is out of range"); \
}
/// def poll(ifaces: Iterable[int], list_ref: List, timeout_us: int) -> bool:
/// '''
/// Wait until one of `ifaces` is ready to read or write (using masks
@ -40,12 +32,14 @@
/// `list_ref`:
///
/// `list_ref[0]` - the interface number, including the mask
/// `list_ref[1]` - for touch event, tuple of (event_type, x_position, y_position)
/// `list_ref[1]` - for touch event, tuple of (event_type, x_position,
/// y_position)
/// - for USB read event, received bytes
///
/// If timeout occurs, False is returned, True otherwise.
/// '''
STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref, mp_obj_t timeout_us) {
STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
mp_obj_t timeout_us) {
mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
if (!MP_OBJ_IS_TYPE(list_ref, &mp_type_list) || ret->len < 2) {
mp_raise_TypeError("invalid list_ref");
@ -67,15 +61,16 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref, mp_obj_t t
const uint32_t evt = touch_read();
if (evt) {
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
tuple->items[0] = MP_OBJ_NEW_SMALL_INT((evt >> 24) & 0xFFU); // event type
tuple->items[1] = MP_OBJ_NEW_SMALL_INT((evt >> 12) & 0xFFFU); // x position
tuple->items[0] =
MP_OBJ_NEW_SMALL_INT((evt >> 24) & 0xFFU); // event type
tuple->items[1] =
MP_OBJ_NEW_SMALL_INT((evt >> 12) & 0xFFFU); // x position
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(evt & 0xFFFU); // y position
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true;
}
} else
if (mode == POLL_READ) {
} else if (mode == POLL_READ) {
if (sectrue == usb_hid_can_read(iface)) {
uint8_t buf[64];
int len = usb_hid_read(iface, buf, sizeof(buf));
@ -93,8 +88,7 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref, mp_obj_t t
return mp_const_true;
}
}
} else
if (mode == POLL_WRITE) {
} else if (mode == POLL_WRITE) {
if (sectrue == usb_hid_can_write(iface)) {
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
ret->items[1] = mp_const_none;

@ -29,7 +29,9 @@ typedef struct _mp_obj_SBU_t {
/// def __init__(self) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_SBU_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_SBU_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 0, false);
mp_obj_SBU_t *o = m_new_obj(mp_obj_SBU_t);
o->base.type = type;
@ -41,20 +43,23 @@ STATIC mp_obj_t mod_trezorio_SBU_make_new(const mp_obj_type_t *type, size_t n_ar
/// '''
/// Sets SBU wires to sbu1 and sbu2 values respectively
/// '''
STATIC mp_obj_t mod_trezorio_SBU_set(mp_obj_t self, mp_obj_t sbu1, mp_obj_t sbu2) {
STATIC mp_obj_t mod_trezorio_SBU_set(mp_obj_t self, mp_obj_t sbu1,
mp_obj_t sbu2) {
sbu_set(sectrue * mp_obj_is_true(sbu1), sectrue * mp_obj_is_true(sbu2));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_SBU_set_obj, mod_trezorio_SBU_set);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_SBU_set_obj,
mod_trezorio_SBU_set);
STATIC const mp_rom_map_elem_t mod_trezorio_SBU_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mod_trezorio_SBU_set_obj) },
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mod_trezorio_SBU_set_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_SBU_locals_dict, mod_trezorio_SBU_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_SBU_locals_dict,
mod_trezorio_SBU_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_SBU_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_SBU,
.make_new = mod_trezorio_SBU_make_new,
.locals_dict = (void*)&mod_trezorio_SBU_locals_dict,
.locals_dict = (void *)&mod_trezorio_SBU_locals_dict,
};

@ -31,7 +31,9 @@ typedef struct _mp_obj_SDCard_t {
/// def __init__(self) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_SDCard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_SDCard_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 0, false);
mp_obj_SDCard_t *o = m_new_obj(mp_obj_SDCard_t);
o->base.type = type;
@ -48,7 +50,8 @@ STATIC mp_obj_t mod_trezorio_SDCard_make_new(const mp_obj_type_t *type, size_t n
STATIC mp_obj_t mod_trezorio_SDCard_present(mp_obj_t self) {
return mp_obj_new_bool(sdcard_is_present());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_SDCard_present_obj, mod_trezorio_SDCard_present);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_SDCard_present_obj,
mod_trezorio_SDCard_present);
/// def power(self, state: bool) -> bool:
/// '''
@ -63,7 +66,8 @@ STATIC mp_obj_t mod_trezorio_SDCard_power(mp_obj_t self, mp_obj_t state) {
return mp_const_true;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_SDCard_power_obj, mod_trezorio_SDCard_power);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_SDCard_power_obj,
mod_trezorio_SDCard_power);
/// def capacity(self) -> int:
/// '''
@ -72,49 +76,59 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_SDCard_power_obj, mod_trezorio_SDC
STATIC mp_obj_t mod_trezorio_SDCard_capacity(mp_obj_t self) {
return mp_obj_new_int_from_ull(sdcard_get_capacity_in_bytes());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_SDCard_capacity_obj, mod_trezorio_SDCard_capacity);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_SDCard_capacity_obj,
mod_trezorio_SDCard_capacity);
/// def read(self, block_num: int, buf: bytearray) -> bool:
/// '''
/// Reads blocks starting with block_num from the SD card into buf.
/// Number of bytes read is length of buf rounded down to multiply of SDCARD_BLOCK_SIZE.
/// Returns True if in case of success, False otherwise.
/// Number of bytes read is length of buf rounded down to multiply of
/// SDCARD_BLOCK_SIZE. Returns True if in case of success, False otherwise.
/// '''
STATIC mp_obj_t mod_trezorio_SDCard_read(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
STATIC mp_obj_t mod_trezorio_SDCard_read(mp_obj_t self, mp_obj_t block_num,
mp_obj_t buf) {
uint32_t block = trezor_obj_get_uint(block_num);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_WRITE);
return mp_obj_new_bool(sdcard_read_blocks(bufinfo.buf, block, bufinfo.len / SDCARD_BLOCK_SIZE));
return mp_obj_new_bool(
sdcard_read_blocks(bufinfo.buf, block, bufinfo.len / SDCARD_BLOCK_SIZE));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_SDCard_read_obj, mod_trezorio_SDCard_read);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_SDCard_read_obj,
mod_trezorio_SDCard_read);
/// def write(self, block_num: int, buf: bytes) -> bool:
/// '''
/// Writes blocks starting with block_num from buf to the SD card.
/// Number of bytes written is length of buf rounded down to multiply of SDCARD_BLOCK_SIZE.
/// Returns True if in case of success, False otherwise.
/// Number of bytes written is length of buf rounded down to multiply of
/// SDCARD_BLOCK_SIZE. Returns True if in case of success, False otherwise.
/// '''
STATIC mp_obj_t mod_trezorio_SDCard_write(mp_obj_t self, mp_obj_t block_num, mp_obj_t buf) {
STATIC mp_obj_t mod_trezorio_SDCard_write(mp_obj_t self, mp_obj_t block_num,
mp_obj_t buf) {
uint32_t block = trezor_obj_get_uint(block_num);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ);
return mp_obj_new_bool(sdcard_write_blocks(bufinfo.buf, block, bufinfo.len / SDCARD_BLOCK_SIZE));
return mp_obj_new_bool(
sdcard_write_blocks(bufinfo.buf, block, bufinfo.len / SDCARD_BLOCK_SIZE));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_SDCard_write_obj, mod_trezorio_SDCard_write);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_SDCard_write_obj,
mod_trezorio_SDCard_write);
STATIC const mp_rom_map_elem_t mod_trezorio_SDCard_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_present), MP_ROM_PTR(&mod_trezorio_SDCard_present_obj) },
{ MP_ROM_QSTR(MP_QSTR_power), MP_ROM_PTR(&mod_trezorio_SDCard_power_obj) },
{ MP_ROM_QSTR(MP_QSTR_capacity), MP_ROM_PTR(&mod_trezorio_SDCard_capacity_obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SDCARD_BLOCK_SIZE) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mod_trezorio_SDCard_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_SDCard_write_obj) },
{MP_ROM_QSTR(MP_QSTR_present),
MP_ROM_PTR(&mod_trezorio_SDCard_present_obj)},
{MP_ROM_QSTR(MP_QSTR_power), MP_ROM_PTR(&mod_trezorio_SDCard_power_obj)},
{MP_ROM_QSTR(MP_QSTR_capacity),
MP_ROM_PTR(&mod_trezorio_SDCard_capacity_obj)},
{MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(SDCARD_BLOCK_SIZE)},
{MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mod_trezorio_SDCard_read_obj)},
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_SDCard_write_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_SDCard_locals_dict, mod_trezorio_SDCard_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_SDCard_locals_dict,
mod_trezorio_SDCard_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_SDCard_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_SDCard,
.make_new = mod_trezorio_SDCard_make_new,
.locals_dict = (void*)&mod_trezorio_SDCard_locals_dict,
.locals_dict = (void *)&mod_trezorio_SDCard_locals_dict,
};

@ -64,24 +64,40 @@ static const char *get_0str(mp_obj_t o, size_t min_len, size_t max_len) {
/// usb21_landing: bool=True) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_device_class, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_device_subclass, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_device_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_vendor_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_product_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_release_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_manufacturer, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_product, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_serial_number, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_interface, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_usb21_enabled, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
{ MP_QSTR_usb21_landing, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
{MP_QSTR_device_class, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_device_subclass, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_device_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_vendor_id,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_product_id,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_release_num,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_manufacturer,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_product,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_serial_number,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_interface,
MP_ARG_KW_ONLY | MP_ARG_OBJ,
{.u_obj = mp_const_empty_bytes}},
{MP_QSTR_usb21_enabled, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true}},
{MP_QSTR_usb21_landing, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
const mp_int_t device_class = vals[0].u_int;
const mp_int_t device_subclass = vals[1].u_int;
@ -152,7 +168,8 @@ STATIC mp_obj_t mod_trezorio_USB_add(mp_obj_t self, mp_obj_t iface) {
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_USB_add_obj, mod_trezorio_USB_add);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_USB_add_obj,
mod_trezorio_USB_add);
/// def open(self) -> None:
/// '''
@ -213,7 +230,8 @@ STATIC mp_obj_t mod_trezorio_USB_open(mp_obj_t self) {
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_USB_open_obj, mod_trezorio_USB_open);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_USB_open_obj,
mod_trezorio_USB_open);
/// def close(self) -> None:
/// '''
@ -239,7 +257,8 @@ STATIC mp_obj_t mod_trezorio_USB_close(mp_obj_t self) {
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_USB_close_obj, mod_trezorio_USB_close);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_USB_close_obj,
mod_trezorio_USB_close);
STATIC mp_obj_t mod_trezorio_USB___del__(mp_obj_t self) {
mp_obj_USB_t *o = MP_OBJ_TO_PTR(self);
@ -250,19 +269,21 @@ STATIC mp_obj_t mod_trezorio_USB___del__(mp_obj_t self) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_USB___del___obj, mod_trezorio_USB___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_USB___del___obj,
mod_trezorio_USB___del__);
STATIC const mp_rom_map_elem_t mod_trezorio_USB_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&mod_trezorio_USB_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_trezorio_USB_open_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mod_trezorio_USB_close_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorio_USB___del___obj) },
{MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&mod_trezorio_USB_add_obj)},
{MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_trezorio_USB_open_obj)},
{MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mod_trezorio_USB_close_obj)},
{MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_trezorio_USB___del___obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_USB_locals_dict, mod_trezorio_USB_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_USB_locals_dict,
mod_trezorio_USB_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_USB_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_USB,
.make_new = mod_trezorio_USB_make_new,
.locals_dict = (void*)&mod_trezorio_USB_locals_dict,
.locals_dict = (void *)&mod_trezorio_USB_locals_dict,
};

@ -36,17 +36,29 @@ typedef struct _mp_obj_VCP_t {
/// ep_cmd: int) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_VCP_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_VCP_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_iface_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_data_iface_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_in, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_out, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_cmd, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{MP_QSTR_iface_num,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_data_iface_num,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_in,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_out,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_cmd,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
const mp_int_t iface_num = vals[0].u_int;
const mp_int_t data_iface_num = vals[1].u_int;
@ -93,16 +105,19 @@ STATIC mp_obj_t mod_trezorio_VCP_iface_num(mp_obj_t self) {
mp_obj_VCP_t *o = MP_OBJ_TO_PTR(self);
return MP_OBJ_NEW_SMALL_INT(o->info.iface_num);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_VCP_iface_num_obj, mod_trezorio_VCP_iface_num);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_VCP_iface_num_obj,
mod_trezorio_VCP_iface_num);
STATIC const mp_rom_map_elem_t mod_trezorio_VCP_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_iface_num), MP_ROM_PTR(&mod_trezorio_VCP_iface_num_obj) },
{MP_ROM_QSTR(MP_QSTR_iface_num),
MP_ROM_PTR(&mod_trezorio_VCP_iface_num_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_VCP_locals_dict, mod_trezorio_VCP_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_VCP_locals_dict,
mod_trezorio_VCP_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_VCP_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_VCP,
.make_new = mod_trezorio_VCP_make_new,
.locals_dict = (void*)&mod_trezorio_VCP_locals_dict,
.locals_dict = (void *)&mod_trezorio_VCP_locals_dict,
};

@ -36,19 +36,27 @@ typedef struct _mp_obj_WebUSB_t {
/// max_packet_len: int = 64) -> None:
/// '''
/// '''
STATIC mp_obj_t mod_trezorio_WebUSB_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_WebUSB_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
STATIC const mp_arg_t allowed_args[] = {
{ MP_QSTR_iface_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_in, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_ep_out, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_subclass, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_polling_interval, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_max_packet_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
{MP_QSTR_iface_num,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_in,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_ep_out,
MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT,
{.u_int = 0}},
{MP_QSTR_subclass, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
{MP_QSTR_polling_interval, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1}},
{MP_QSTR_max_packet_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64}},
};
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args),
allowed_args, vals);
const mp_int_t iface_num = vals[0].u_int;
const mp_int_t ep_in = vals[1].u_int;
@ -89,7 +97,8 @@ STATIC mp_obj_t mod_trezorio_WebUSB_iface_num(mp_obj_t self) {
mp_obj_WebUSB_t *o = MP_OBJ_TO_PTR(self);
return MP_OBJ_NEW_SMALL_INT(o->info.iface_num);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_WebUSB_iface_num_obj, mod_trezorio_WebUSB_iface_num);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_WebUSB_iface_num_obj,
mod_trezorio_WebUSB_iface_num);
/// def write(self, msg: bytes) -> int:
/// '''
@ -102,17 +111,20 @@ STATIC mp_obj_t mod_trezorio_WebUSB_write(mp_obj_t self, mp_obj_t msg) {
ssize_t r = usb_webusb_write(o->info.iface_num, buf.buf, buf.len);
return MP_OBJ_NEW_SMALL_INT(r);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_WebUSB_write_obj, mod_trezorio_WebUSB_write);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_WebUSB_write_obj,
mod_trezorio_WebUSB_write);
STATIC const mp_rom_map_elem_t mod_trezorio_WebUSB_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_iface_num), MP_ROM_PTR(&mod_trezorio_WebUSB_iface_num_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_WebUSB_write_obj) },
{MP_ROM_QSTR(MP_QSTR_iface_num),
MP_ROM_PTR(&mod_trezorio_WebUSB_iface_num_obj)},
{MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mod_trezorio_WebUSB_write_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_WebUSB_locals_dict, mod_trezorio_WebUSB_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_WebUSB_locals_dict,
mod_trezorio_WebUSB_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorio_WebUSB_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_WebUSB,
.make_new = mod_trezorio_WebUSB_make_new,
.locals_dict = (void*)&mod_trezorio_WebUSB_locals_dict,
.locals_dict = (void *)&mod_trezorio_WebUSB_locals_dict,
};

@ -17,51 +17,65 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "py/runtime.h"
#include "py/mphal.h"
#include "py/objstr.h"
#include "py/runtime.h"
#if MICROPY_PY_TREZORIO
#include <unistd.h>
#include "touch.h"
#include "usb.h"
#define CHECK_PARAM_RANGE(value, minimum, maximum) \
if (value < minimum || value > maximum) { \
mp_raise_ValueError(#value " is out of range"); \
}
// clang-format off
#include "modtrezorio-flash.h"
#include "modtrezorio-hid.h"
#include "modtrezorio-poll.h"
#include "modtrezorio-sbu.h"
#include "modtrezorio-sdcard.h"
#include "modtrezorio-poll.h"
#include "modtrezorio-hid.h"
#include "modtrezorio-vcp.h"
#include "modtrezorio-webusb.h"
#include "modtrezorio-usb.h"
// clang-format on
STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorio) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorio)},
{ MP_ROM_QSTR(MP_QSTR_FlashOTP), MP_ROM_PTR(&mod_trezorio_FlashOTP_type) },
{MP_ROM_QSTR(MP_QSTR_FlashOTP), MP_ROM_PTR(&mod_trezorio_FlashOTP_type)},
{ MP_ROM_QSTR(MP_QSTR_SBU), MP_ROM_PTR(&mod_trezorio_SBU_type) },
{MP_ROM_QSTR(MP_QSTR_SBU), MP_ROM_PTR(&mod_trezorio_SBU_type)},
{ MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&mod_trezorio_SDCard_type) },
{MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&mod_trezorio_SDCard_type)},
{ MP_ROM_QSTR(MP_QSTR_USB), MP_ROM_PTR(&mod_trezorio_USB_type) },
{ MP_ROM_QSTR(MP_QSTR_HID), MP_ROM_PTR(&mod_trezorio_HID_type) },
{ MP_ROM_QSTR(MP_QSTR_VCP), MP_ROM_PTR(&mod_trezorio_VCP_type) },
{ MP_ROM_QSTR(MP_QSTR_WebUSB), MP_ROM_PTR(&mod_trezorio_WebUSB_type) },
{MP_ROM_QSTR(MP_QSTR_USB), MP_ROM_PTR(&mod_trezorio_USB_type)},
{MP_ROM_QSTR(MP_QSTR_HID), MP_ROM_PTR(&mod_trezorio_HID_type)},
{MP_ROM_QSTR(MP_QSTR_VCP), MP_ROM_PTR(&mod_trezorio_VCP_type)},
{MP_ROM_QSTR(MP_QSTR_WebUSB), MP_ROM_PTR(&mod_trezorio_WebUSB_type)},
{ MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&mod_trezorio_poll_obj) },
{ MP_ROM_QSTR(MP_QSTR_POLL_READ), MP_OBJ_NEW_SMALL_INT(POLL_READ) },
{ MP_ROM_QSTR(MP_QSTR_POLL_WRITE), MP_OBJ_NEW_SMALL_INT(POLL_WRITE) },
{MP_ROM_QSTR(MP_QSTR_poll), MP_ROM_PTR(&mod_trezorio_poll_obj)},
{MP_ROM_QSTR(MP_QSTR_POLL_READ), MP_OBJ_NEW_SMALL_INT(POLL_READ)},
{MP_ROM_QSTR(MP_QSTR_POLL_WRITE), MP_OBJ_NEW_SMALL_INT(POLL_WRITE)},
{ MP_ROM_QSTR(MP_QSTR_TOUCH), MP_OBJ_NEW_SMALL_INT(TOUCH_IFACE) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_START), MP_OBJ_NEW_SMALL_INT((TOUCH_START >> 24) & 0xFFU) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_MOVE), MP_OBJ_NEW_SMALL_INT((TOUCH_MOVE >> 24) & 0xFFU) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_END), MP_OBJ_NEW_SMALL_INT((TOUCH_END >> 24) & 0xFFU) },
{MP_ROM_QSTR(MP_QSTR_TOUCH), MP_OBJ_NEW_SMALL_INT(TOUCH_IFACE)},
{MP_ROM_QSTR(MP_QSTR_TOUCH_START),
MP_OBJ_NEW_SMALL_INT((TOUCH_START >> 24) & 0xFFU)},
{MP_ROM_QSTR(MP_QSTR_TOUCH_MOVE),
MP_OBJ_NEW_SMALL_INT((TOUCH_MOVE >> 24) & 0xFFU)},
{MP_ROM_QSTR(MP_QSTR_TOUCH_END),
MP_OBJ_NEW_SMALL_INT((TOUCH_END >> 24) & 0xFFU)},
};
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorio_globals, mp_module_trezorio_globals_table);
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorio_globals,
mp_module_trezorio_globals_table);
const mp_obj_module_t mp_module_trezorio = {
.base = { &mp_type_module },
.base = {&mp_type_module},
.globals = (mp_obj_dict_t*)&mp_module_trezorio_globals,
};

@ -20,7 +20,7 @@
#include STM32_HAL_H
#define OLED_BUFSIZE (DISPLAY_RESX * DISPLAY_RESY / 8)
#define OLED_OFFSET(x, y) (OLED_BUFSIZE - 1 - (x) - ((y)/8) * DISPLAY_RESX)
#define OLED_OFFSET(x, y) (OLED_BUFSIZE - 1 - (x) - ((y) / 8) * DISPLAY_RESX)
#define OLED_MASK(x, y) (1 << (7 - (y) % 8))
#define OLED_SETCONTRAST 0x81
@ -67,14 +67,17 @@ static struct {
} PIXELWINDOW;
void PIXELDATA(uint16_t c) {
if (PIXELWINDOW.pos.x <= PIXELWINDOW.end.x && PIXELWINDOW.pos.y <= PIXELWINDOW.end.y) {
if (PIXELWINDOW.pos.x <= PIXELWINDOW.end.x &&
PIXELWINDOW.pos.y <= PIXELWINDOW.end.y) {
// set to white if highest bits of all R, G, B values are set to 1
// bin(10000 100000 10000) = hex(0x8410)
// otherwise set to black
if (c & 0x8410) {
OLED_BUFFER[OLED_OFFSET(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y)] |= OLED_MASK(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y);
OLED_BUFFER[OLED_OFFSET(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y)] |=
OLED_MASK(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y);
} else {
OLED_BUFFER[OLED_OFFSET(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y)] &= ~OLED_MASK(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y);
OLED_BUFFER[OLED_OFFSET(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y)] &=
~OLED_MASK(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y);
}
}
PIXELWINDOW.pos.x++;
@ -84,26 +87,23 @@ void PIXELDATA(uint16_t c) {
}
}
static void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
PIXELWINDOW.start.x = x0; PIXELWINDOW.start.y = y0;
PIXELWINDOW.end.x = x1; PIXELWINDOW.end.y = y1;
PIXELWINDOW.pos.x = x0; PIXELWINDOW.pos.y = y0;
static void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
PIXELWINDOW.start.x = x0;
PIXELWINDOW.start.y = y0;
PIXELWINDOW.end.x = x1;
PIXELWINDOW.end.y = y1;
PIXELWINDOW.pos.x = x0;
PIXELWINDOW.pos.y = y0;
}
static void display_set_orientation(int degrees)
{
display_refresh();
}
static void display_set_orientation(int degrees) { display_refresh(); }
static void display_set_backlight(int val)
{
}
static void display_set_backlight(int val) {}
SPI_HandleTypeDef spi_handle;
static inline void spi_send(const uint8_t *data, int len)
{
static inline void spi_send(const uint8_t *data, int len) {
HAL_Delay(1);
if (HAL_OK != HAL_SPI_Transmit(&spi_handle, (uint8_t *)data, len, 1000)) {
// TODO: error
@ -113,8 +113,7 @@ static inline void spi_send(const uint8_t *data, int len)
}
}
void display_init(void)
{
void display_init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
@ -160,8 +159,7 @@ void display_init(void)
// initialize display
static const uint8_t s[25] = {
OLED_DISPLAYOFF,
static const uint8_t s[25] = {OLED_DISPLAYOFF,
OLED_SETDISPLAYCLOCKDIV,
0x80,
OLED_SETMULTIPLEX,
@ -185,8 +183,7 @@ void display_init(void)
0x40,
OLED_DISPLAYALLON_RESUME,
OLED_NORMALDISPLAY,
OLED_DISPLAYON
};
OLED_DISPLAYON};
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); // SPI deselect
@ -214,8 +211,7 @@ static inline uint8_t reverse_byte(uint8_t b) {
return b;
}
static void rotate_oled_buffer(void)
{
static void rotate_oled_buffer(void) {
for (int i = 0; i < OLED_BUFSIZE / 2; i++) {
uint8_t b = OLED_BUFFER[i];
OLED_BUFFER[i] = reverse_byte(OLED_BUFFER[OLED_BUFSIZE - i]);
@ -223,9 +219,10 @@ static void rotate_oled_buffer(void)
}
}
void display_refresh(void)
{
static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00, OLED_SETHIGHCOLUMN | 0x00, OLED_SETSTARTLINE | 0x00};
void display_refresh(void) {
static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00,
OLED_SETHIGHCOLUMN | 0x00,
OLED_SETSTARTLINE | 0x00};
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); // SPI select
spi_send(s, 3);
@ -244,6 +241,4 @@ void display_refresh(void)
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD
}
void display_save(const char *prefix)
{
}
void display_save(const char *prefix) {}

@ -24,29 +24,40 @@
#define DISPLAY_MEMORY_PIN 16
#define CMD(X) (*((__IO uint8_t *)((uint32_t)(DISPLAY_MEMORY_BASE))) = (X))
#define ADDR (*((__IO uint8_t *)((uint32_t)(DISPLAY_MEMORY_BASE | (1 << DISPLAY_MEMORY_PIN)))))
#define ADDR \
(*((__IO uint8_t *)((uint32_t)(DISPLAY_MEMORY_BASE | \
(1 << DISPLAY_MEMORY_PIN)))))
#define DATA(X) (ADDR) = (X)
#define PIXELDATA(X) DATA((X) >> 8); DATA((X) & 0xFF)
#define PIXELDATA(X) \
DATA((X) >> 8); \
DATA((X)&0xFF)
#define LED_PWM_TIM_PERIOD (10000)
#define DISPLAY_ID_ST7789V 0x858552U // section "9.1.3 RDDID (04h): Read Display ID" of ST7789V datasheet
#define DISPLAY_ID_GC9307 0x009307U // section "6.2.1. Read display identification information (04h)" of GC9307 datasheet
#define DISPLAY_ID_ILI9341V 0x009341U // section "8.3.23 Read ID4 (D3h)" of ILI9341V datasheet
#define DISPLAY_ID_ST7789V \
0x858552U // section "9.1.3 RDDID (04h): Read Display ID" of ST7789V
// datasheet
#define DISPLAY_ID_GC9307 \
0x009307U // section "6.2.1. Read display identification information (04h)"
// of GC9307 datasheet
#define DISPLAY_ID_ILI9341V \
0x009341U // section "8.3.23 Read ID4 (D3h)" of ILI9341V datasheet
static uint32_t read_display_id(uint8_t command) {
volatile uint8_t c;
uint32_t id = 0;
CMD(command);
c = ADDR; // first returned value is a dummy value and should be discarded
c = ADDR; id |= (c << 16);
c = ADDR; id |= (c << 8);
c = ADDR; id |= c;
c = ADDR;
id |= (c << 16);
c = ADDR;
id |= (c << 8);
c = ADDR;
id |= c;
return id;
}
static uint32_t display_identify(void)
{
static uint32_t display_identify(void) {
static uint32_t id = 0x000000U;
static char id_set = 0;
@ -56,7 +67,8 @@ static uint32_t display_identify(void)
// the default RDDID for ILI9341 should be 0x8000.
// some display modules return 0x0.
// the ILI9341 has an extra id, let's check it here.
if ((id != DISPLAY_ID_ST7789V) && (id != DISPLAY_ID_GC9307)) { // if not ST7789V and not GC9307
if ((id != DISPLAY_ID_ST7789V) &&
(id != DISPLAY_ID_GC9307)) { // if not ST7789V and not GC9307
uint32_t id4 = read_display_id(0xD3); // Read ID4
if (id4 == DISPLAY_ID_ILI9341V) { // definitely found a ILI9341
id = id4;
@ -66,51 +78,62 @@ static uint32_t display_identify(void)
return id;
}
static void __attribute__((unused)) display_sleep(void)
{
static void __attribute__((unused)) display_sleep(void) {
uint32_t id = display_identify();
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) || (id == DISPLAY_ID_ST7789V)) {
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
(id == DISPLAY_ID_ST7789V)) {
CMD(0x28); // DISPOFF: Display Off
CMD(0x10); // SLPIN: Sleep in
HAL_Delay(5); // need to wait 5 milliseconds after "sleep in" before sending any new commands
HAL_Delay(5); // need to wait 5 milliseconds after "sleep in" before
// sending any new commands
}
}
static void display_unsleep(void)
{
static void display_unsleep(void) {
uint32_t id = display_identify();
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) || (id == DISPLAY_ID_ST7789V)) {
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
(id == DISPLAY_ID_ST7789V)) {
CMD(0x11); // SLPOUT: Sleep Out
HAL_Delay(5); // need to wait 5 milliseconds after "sleep out" before sending any new commands
HAL_Delay(5); // need to wait 5 milliseconds after "sleep out" before
// sending any new commands
CMD(0x29); // DISPON: Display On
}
}
static struct {
uint16_t x, y;
} BUFFER_OFFSET;
static struct { uint16_t x, y; } BUFFER_OFFSET;
static void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
x0 += BUFFER_OFFSET.x; x1 += BUFFER_OFFSET.x;
y0 += BUFFER_OFFSET.y; y1 += BUFFER_OFFSET.y;
static void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
x0 += BUFFER_OFFSET.x;
x1 += BUFFER_OFFSET.x;
y0 += BUFFER_OFFSET.y;
y1 += BUFFER_OFFSET.y;
uint32_t id = display_identify();
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) || (id == DISPLAY_ID_ST7789V)) {
CMD(0x2A); DATA(x0 >> 8); DATA(x0 & 0xFF); DATA(x1 >> 8); DATA(x1 & 0xFF); // column addr set
CMD(0x2B); DATA(y0 >> 8); DATA(y0 & 0xFF); DATA(y1 >> 8); DATA(y1 & 0xFF); // row addr set
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
(id == DISPLAY_ID_ST7789V)) {
CMD(0x2A);
DATA(x0 >> 8);
DATA(x0 & 0xFF);
DATA(x1 >> 8);
DATA(x1 & 0xFF); // column addr set
CMD(0x2B);
DATA(y0 >> 8);
DATA(y0 & 0xFF);
DATA(y1 >> 8);
DATA(y1 & 0xFF); // row addr set
CMD(0x2C);
}
}
static void display_set_orientation(int degrees)
{
static void display_set_orientation(int degrees) {
char BX = 0, BY = 0;
uint32_t id = display_identify();
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) || (id == DISPLAY_ID_ST7789V)) {
#define RGB (1 << 3)
#define MV (1 << 5)
#define MX (1 << 6)
#define MY (1 << 7)
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
(id == DISPLAY_ID_ST7789V)) {
#define RGB (1 << 3)
#define MV (1 << 5)
#define MX (1 << 6)
#define MY (1 << 7)
// MADCTL: Memory Data Access Control - reference:
// section 9.3 in the ILI9341 manual
// section 6.2.18 in the GC9307 manual
@ -137,32 +160,34 @@ static void display_set_orientation(int degrees)
if (id == DISPLAY_ID_GC9307) {
display_command_parameter ^= RGB | MY; // XOR RGB and MY settings
}
CMD(0x36); DATA(display_command_parameter);
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); // reset the column and page extents
CMD(0x36);
DATA(display_command_parameter);
display_set_window(0, 0, DISPLAY_RESX - 1,
DISPLAY_RESY - 1); // reset the column and page extents
}
BUFFER_OFFSET.x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
BUFFER_OFFSET.y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
}
static void display_set_backlight(int val)
{
static void display_set_backlight(int val) {
TIM1->CCR1 = LED_PWM_TIM_PERIOD * val / 255;
}
static void display_hardware_reset(void)
{
static void display_hardware_reset(void) {
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); // LCD_RST/PC14
// wait 10 milliseconds. only needs to be low for 10 microseconds.
// my dev display module ties display reset and touch panel reset together.
// keeping this low for max(display_reset_time, ctpm_reset_time) aids development and does not hurt.
// keeping this low for max(display_reset_time, ctpm_reset_time) aids
// development and does not hurt.
HAL_Delay(10);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET); // LCD_RST/PC14
HAL_Delay(120); // max wait time for hardware reset is 120 milliseconds (experienced display flakiness using only 5ms wait before sending commands)
HAL_Delay(120); // max wait time for hardware reset is 120 milliseconds
// (experienced display flakiness using only 5ms wait before
// sending commands)
// identify the controller we will communicate with
}
void display_init(void)
{
void display_init(void) {
// init peripherials
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_TIM1_CLK_ENABLE();
@ -182,7 +207,8 @@ void display_init(void)
TIM_HandleTypeDef TIM1_Handle;
TIM1_Handle.Instance = TIM1;
TIM1_Handle.Init.Period = LED_PWM_TIM_PERIOD - 1;
// TIM1/APB2 source frequency equals to SystemCoreClock in our configuration, we want 1 MHz
// TIM1/APB2 source frequency equals to SystemCoreClock in our configuration,
// we want 1 MHz
TIM1_Handle.Init.Prescaler = SystemCoreClock / 1000000 - 1;
TIM1_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIM1_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
@ -210,7 +236,8 @@ void display_init(void)
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Alternate = 0;
GPIO_InitStructure.Pin = GPIO_PIN_14;
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); // default to keeping display in reset
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14,
GPIO_PIN_RESET); // default to keeping display in reset
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
// LCD_FMARK/PD12 (tearing effect)
@ -225,33 +252,41 @@ void display_init(void)
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
// LCD_CS/PD7 LCD_RS/PD11 LCD_RD/PD4 LCD_WR/PD5
// LCD_CS/PD7 LCD_RS/PD11 LCD_RD/PD4
// LCD_WR/PD5
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_11 | GPIO_PIN_4 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
// LCD_D0/PD14 LCD_D1/PD15 LCD_D2/PD0 LCD_D3/PD1
// LCD_D0/PD14 LCD_D1/PD15 LCD_D2/PD0
// LCD_D3/PD1
GPIO_InitStructure.Pin = GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_0 | GPIO_PIN_1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
// LCD_D4/PE7 LCD_D5/PE8 LCD_D6/PE9 LCD_D7/PE10
// LCD_D4/PE7 LCD_D5/PE8 LCD_D6/PE9
// LCD_D7/PE10
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
// Reference UM1725 "Description of STM32F4 HAL and LL drivers", section 64.2.1 "How to use this driver"
// Reference UM1725 "Description of STM32F4 HAL and LL drivers",
// section 64.2.1 "How to use this driver"
SRAM_HandleTypeDef external_display_data_sram;
external_display_data_sram.Instance = FMC_NORSRAM_DEVICE;
external_display_data_sram.Init.NSBank = FMC_NORSRAM_BANK1;
external_display_data_sram.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
external_display_data_sram.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
external_display_data_sram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
external_display_data_sram.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
external_display_data_sram.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
external_display_data_sram.Init.BurstAccessMode =
FMC_BURST_ACCESS_MODE_DISABLE;
external_display_data_sram.Init.WaitSignalPolarity =
FMC_WAIT_SIGNAL_POLARITY_LOW;
external_display_data_sram.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
external_display_data_sram.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
external_display_data_sram.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
external_display_data_sram.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
external_display_data_sram.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
external_display_data_sram.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
external_display_data_sram.Init.AsynchronousWait =
FMC_ASYNCHRONOUS_WAIT_DISABLE;
external_display_data_sram.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
external_display_data_sram.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
external_display_data_sram.Init.ContinuousClock =
FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
external_display_data_sram.Init.PageSize = FMC_PAGE_SIZE_NONE;
// reference RM0090 section 37.5 Table 259, 37.5.4, Mode 1 SRAM, and 37.5.6
@ -272,80 +307,195 @@ void display_init(void)
if (id == DISPLAY_ID_GC9307) {
CMD(0xFE); // Inter Register Enable1
CMD(0xEF); // Inter Register Enable2
CMD(0x35); DATA(0x00); // TEON: Tearing Effect Line On; V-blanking only
CMD(0x3A); DATA(0x55); // COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits input)
CMD(0x35);
DATA(0x00); // TEON: Tearing Effect Line On; V-blanking only
CMD(0x3A);
DATA(0x55); // COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB
// 5-6-5 bits input)
// CMD(0xE8); DATA(0x12); DATA(0x00); // Frame Rate
CMD(0xC3); DATA(0x27); // Power Control 2
CMD(0xC4); DATA(0x18); // Power Control 3
CMD(0xC9); DATA(0x1F); // Power Control 4
CMD(0xC5); DATA(0x0F);
CMD(0xC6); DATA(0x00);
CMD(0xC7); DATA(0x10);
CMD(0xC8); DATA(0x01);
CMD(0xFF); DATA(0x62);
CMD(0x99); DATA(0x3E);
CMD(0x9D); DATA(0x4B);
CMD(0x8E); DATA(0x0F);
CMD(0xC3);
DATA(0x27); // Power Control 2
CMD(0xC4);
DATA(0x18); // Power Control 3
CMD(0xC9);
DATA(0x1F); // Power Control 4
CMD(0xC5);
DATA(0x0F);
CMD(0xC6);
DATA(0x00);
CMD(0xC7);
DATA(0x10);
CMD(0xC8);
DATA(0x01);
CMD(0xFF);
DATA(0x62);
CMD(0x99);
DATA(0x3E);
CMD(0x9D);
DATA(0x4B);
CMD(0x8E);
DATA(0x0F);
// SET_GAMMA1
CMD(0xF0); DATA(0x8F); DATA(0x1B); DATA(0x05); DATA(0x06); DATA(0x07); DATA(0x42);
CMD(0xF0);
DATA(0x8F);
DATA(0x1B);
DATA(0x05);
DATA(0x06);
DATA(0x07);
DATA(0x42);
// SET_GAMMA3
CMD(0xF2); DATA(0x5C); DATA(0x1F); DATA(0x12); DATA(0x10); DATA(0x07); DATA(0x43);
CMD(0xF2);
DATA(0x5C);
DATA(0x1F);
DATA(0x12);
DATA(0x10);
DATA(0x07);
DATA(0x43);
// SET_GAMMA2
CMD(0xF1); DATA(0x59); DATA(0xCF); DATA(0xCF); DATA(0x35); DATA(0x37); DATA(0x8F);
CMD(0xF1);
DATA(0x59);
DATA(0xCF);
DATA(0xCF);
DATA(0x35);
DATA(0x37);
DATA(0x8F);
// SET_GAMMA4
CMD(0xF3); DATA(0x58); DATA(0xCF); DATA(0xCF); DATA(0x35); DATA(0x37); DATA(0x8F);
} else
if (id == DISPLAY_ID_ST7789V) {
CMD(0x35); DATA(0x00); // TEON: Tearing Effect Line On; V-blanking only
CMD(0x3A); DATA(0x55); // COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits input)
CMD(0xDF); DATA(0x5A); DATA(0x69); DATA(0x02); DATA(0x01); // CMD2EN: Commands in command table 2 can be executed when EXTC level is Low
CMD(0xC0); DATA(0x20); // LCMCTRL: LCM Control: XOR RGB setting
CMD(0xE4); DATA(0x1D); DATA(0x0A); DATA(0x11); // GATECTRL: Gate Control; NL = 240 gate lines, first scan line is gate 80.; gate scan direction 319 -> 0
CMD(0xF3);
DATA(0x58);
DATA(0xCF);
DATA(0xCF);
DATA(0x35);
DATA(0x37);
DATA(0x8F);
} else if (id == DISPLAY_ID_ST7789V) {
CMD(0x35);
DATA(0x00); // TEON: Tearing Effect Line On; V-blanking only
CMD(0x3A);
DATA(0x55); // COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB
// 5-6-5 bits input)
CMD(0xDF);
DATA(0x5A);
DATA(0x69);
DATA(0x02);
DATA(0x01); // CMD2EN: Commands in command table 2 can be executed when
// EXTC level is Low
CMD(0xC0);
DATA(0x20); // LCMCTRL: LCM Control: XOR RGB setting
CMD(0xE4);
DATA(0x1D);
DATA(0x0A);
DATA(0x11); // GATECTRL: Gate Control; NL = 240 gate lines, first scan line
// is gate 80.; gate scan direction 319 -> 0
// the above config is the most important and definitely necessary
CMD(0xD0); DATA(0xA4); DATA(0xA1); // PWCTRL1: Power Control 1
CMD(0xD0);
DATA(0xA4);
DATA(0xA1); // PWCTRL1: Power Control 1
// gamma curve 1
// CMD(0xE0); DATA(0x70); DATA(0x2C); DATA(0x2E); DATA(0x15); DATA(0x10); DATA(0x09); DATA(0x48); DATA(0x33); DATA(0x53); DATA(0x0B); DATA(0x19); DATA(0x18); DATA(0x20); DATA(0x25);
// gamma curve 2
// CMD(0xE1); DATA(0x70); DATA(0x2C); DATA(0x2E); DATA(0x15); DATA(0x10); DATA(0x09); DATA(0x48); DATA(0x33); DATA(0x53); DATA(0x0B); DATA(0x19); DATA(0x18); DATA(0x20); DATA(0x25);
} else
if (id == DISPLAY_ID_ILI9341V) {
// CMD(0xE0); DATA(0x70); DATA(0x2C); DATA(0x2E); DATA(0x15); DATA(0x10);
// DATA(0x09); DATA(0x48); DATA(0x33); DATA(0x53); DATA(0x0B); DATA(0x19);
// DATA(0x18); DATA(0x20); DATA(0x25); gamma curve 2 CMD(0xE1); DATA(0x70);
// DATA(0x2C); DATA(0x2E); DATA(0x15); DATA(0x10); DATA(0x09); DATA(0x48);
// DATA(0x33); DATA(0x53); DATA(0x0B); DATA(0x19); DATA(0x18); DATA(0x20);
// DATA(0x25);
} else if (id == DISPLAY_ID_ILI9341V) {
// most recent manual: https://www.newhavendisplay.com/app_notes/ILI9341.pdf
CMD(0x35); DATA(0x00); // TEON: Tearing Effect Line On; V-blanking only
CMD(0x3A); DATA(0x55); // COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits input)
CMD(0xB6); DATA(0x0A); DATA(0xC2); DATA(0x27); DATA(0x00); // Display Function Control: gate scan direction 319 -> 0
CMD(0xF6); DATA(0x09); DATA(0x30); DATA(0x00); // Interface Control: XOR BGR as ST7789V does
CMD(0x35);
DATA(0x00); // TEON: Tearing Effect Line On; V-blanking only
CMD(0x3A);
DATA(0x55); // COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB
// 5-6-5 bits input)
CMD(0xB6);
DATA(0x0A);
DATA(0xC2);
DATA(0x27);
DATA(0x00); // Display Function Control: gate scan direction 319 -> 0
CMD(0xF6);
DATA(0x09);
DATA(0x30);
DATA(0x00); // Interface Control: XOR BGR as ST7789V does
// the above config is the most important and definitely necessary
CMD(0xCF); DATA(0x00); DATA(0xC1); DATA(0x30);
CMD(0xED); DATA(0x64); DATA(0x03); DATA(0x12); DATA(0x81);
CMD(0xE8); DATA(0x85); DATA(0x10); DATA(0x7A);
CMD(0xF7); DATA(0x20);
CMD(0xEA); DATA(0x00); DATA(0x00);
CMD(0xC0); DATA(0x23); // power control VRH[5:0]
CMD(0xC1); DATA(0x12); // power control SAP[2:0] BT[3:0]
CMD(0xC5); DATA(0x60); DATA(0x44); // vcm control 1
CMD(0xC7); DATA(0x8A); // vcm control 2
CMD(0xB1); DATA(0x00); DATA(0x18); // framerate
CMD(0xF2); DATA(0x00); // 3 gamma func disable
CMD(0xCF);
DATA(0x00);
DATA(0xC1);
DATA(0x30);
CMD(0xED);
DATA(0x64);
DATA(0x03);
DATA(0x12);
DATA(0x81);
CMD(0xE8);
DATA(0x85);
DATA(0x10);
DATA(0x7A);
CMD(0xF7);
DATA(0x20);
CMD(0xEA);
DATA(0x00);
DATA(0x00);
CMD(0xC0);
DATA(0x23); // power control VRH[5:0]
CMD(0xC1);
DATA(0x12); // power control SAP[2:0] BT[3:0]
CMD(0xC5);
DATA(0x60);
DATA(0x44); // vcm control 1
CMD(0xC7);
DATA(0x8A); // vcm control 2
CMD(0xB1);
DATA(0x00);
DATA(0x18); // framerate
CMD(0xF2);
DATA(0x00); // 3 gamma func disable
// gamma curve 1
CMD(0xE0); DATA(0x0F); DATA(0x2F); DATA(0x2C); DATA(0x0B); DATA(0x0F); DATA(0x09); DATA(0x56); DATA(0xD9); DATA(0x4A); DATA(0x0B); DATA(0x14); DATA(0x05); DATA(0x0C); DATA(0x06); DATA(0x00);
CMD(0xE0);
DATA(0x0F);
DATA(0x2F);
DATA(0x2C);
DATA(0x0B);
DATA(0x0F);
DATA(0x09);
DATA(0x56);
DATA(0xD9);
DATA(0x4A);
DATA(0x0B);
DATA(0x14);
DATA(0x05);
DATA(0x0C);
DATA(0x06);
DATA(0x00);
// gamma curve 2
CMD(0xE1); DATA(0x00); DATA(0x10); DATA(0x13); DATA(0x04); DATA(0x10); DATA(0x06); DATA(0x25); DATA(0x26); DATA(0x3B); DATA(0x04); DATA(0x0B); DATA(0x0A); DATA(0x33); DATA(0x39); DATA(0x0F);
CMD(0xE1);
DATA(0x00);
DATA(0x10);
DATA(0x13);
DATA(0x04);
DATA(0x10);
DATA(0x06);
DATA(0x25);
DATA(0x26);
DATA(0x3B);
DATA(0x04);
DATA(0x0B);
DATA(0x0A);
DATA(0x33);
DATA(0x39);
DATA(0x0F);
}
display_clear();
display_unsleep();
}
void display_refresh(void)
{
void display_refresh(void) {
uint32_t id = display_identify();
if (id && (id != DISPLAY_ID_GC9307)) {
// synchronize with the panel synchronization signal in order to avoid visual tearing effects
while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) { }
while (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) { }
// synchronize with the panel synchronization signal in order to avoid
// visual tearing effects
while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) {
}
while (GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_12)) {
}
}
}
void display_save(const char *prefix)
{
}
void display_save(const char *prefix) {}

@ -78,8 +78,11 @@ void PIXELDATA(uint16_t c) {
if (!RENDERER) {
display_init();
}
if (PIXELWINDOW.pos.x <= PIXELWINDOW.end.x && PIXELWINDOW.pos.y <= PIXELWINDOW.end.y) {
((uint16_t *)BUFFER->pixels)[PIXELWINDOW.pos.x + PIXELWINDOW.pos.y * BUFFER->pitch / sizeof(uint16_t)] = c;
if (PIXELWINDOW.pos.x <= PIXELWINDOW.end.x &&
PIXELWINDOW.pos.y <= PIXELWINDOW.end.y) {
((uint16_t *)
BUFFER->pixels)[PIXELWINDOW.pos.x + PIXELWINDOW.pos.y * BUFFER->pitch /
sizeof(uint16_t)] = c;
}
PIXELWINDOW.pos.x++;
if (PIXELWINDOW.pos.x > PIXELWINDOW.end.x) {
@ -91,15 +94,16 @@ void PIXELDATA(uint16_t c) {
#define PIXELDATA(X) (void)(X)
#endif
void display_init(void)
{
void display_init(void) {
#ifndef TREZOR_EMULATOR_NOUI
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("%s\n", SDL_GetError());
ensure(secfalse, "SDL_Init error");
}
atexit(SDL_Quit);
SDL_Window *win = SDL_CreateWindow("TREZOR Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT,
SDL_Window *win =
SDL_CreateWindow("TREZOR Emulator", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT,
#ifdef TREZOR_EMULATOR_RASPI
SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN
#else
@ -118,8 +122,11 @@ void display_init(void)
}
SDL_SetRenderDrawColor(RENDERER, 0, 0, 0, 255);
SDL_RenderClear(RENDERER);
BUFFER = SDL_CreateRGBSurface(0, MAX_DISPLAY_RESX, MAX_DISPLAY_RESY, 16, 0xF800, 0x07E0, 0x001F, 0x0000);
TEXTURE = SDL_CreateTexture(RENDERER, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, DISPLAY_RESX, DISPLAY_RESY);
BUFFER = SDL_CreateRGBSurface(0, MAX_DISPLAY_RESX, MAX_DISPLAY_RESY, 16,
0xF800, 0x07E0, 0x001F, 0x0000);
TEXTURE = SDL_CreateTexture(RENDERER, SDL_PIXELFORMAT_RGB565,
SDL_TEXTUREACCESS_STREAMING, DISPLAY_RESX,
DISPLAY_RESY);
SDL_SetTextureBlendMode(TEXTURE, SDL_BLENDMODE_BLEND);
#ifdef __APPLE__
// macOS Mojave SDL black screen workaround
@ -130,14 +137,16 @@ void display_init(void)
#ifdef TREZOR_EMULATOR_RASPI
BACKGROUND = IMG_LoadTexture(RENDERER, "../embed/unix/background_raspi.jpg");
#else
BACKGROUND = IMG_LoadTexture(RENDERER, "../embed/unix/background_" XSTR(TREZOR_MODEL) ".jpg");
BACKGROUND = IMG_LoadTexture(
RENDERER, "../embed/unix/background_" XSTR(TREZOR_MODEL) ".jpg");
#endif
if (BACKGROUND) {
SDL_SetTextureBlendMode(BACKGROUND, SDL_BLENDMODE_NONE);
sdl_touch_offset_x = TOUCH_OFFSET_X;
sdl_touch_offset_y = TOUCH_OFFSET_Y;
} else {
SDL_SetWindowSize(win, DISPLAY_RESX + 2 * EMULATOR_BORDER, DISPLAY_RESY + 2 * EMULATOR_BORDER);
SDL_SetWindowSize(win, DISPLAY_RESX + 2 * EMULATOR_BORDER,
DISPLAY_RESY + 2 * EMULATOR_BORDER);
sdl_touch_offset_x = EMULATOR_BORDER;
sdl_touch_offset_y = EMULATOR_BORDER;
}
@ -151,20 +160,22 @@ void display_init(void)
#endif
}
static void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
static void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
#ifndef TREZOR_EMULATOR_NOUI
if (!RENDERER) {
display_init();
}
PIXELWINDOW.start.x = x0; PIXELWINDOW.start.y = y0;
PIXELWINDOW.end.x = x1; PIXELWINDOW.end.y = y1;
PIXELWINDOW.pos.x = x0; PIXELWINDOW.pos.y = y0;
PIXELWINDOW.start.x = x0;
PIXELWINDOW.start.y = y0;
PIXELWINDOW.end.x = x1;
PIXELWINDOW.end.y = y1;
PIXELWINDOW.pos.x = x0;
PIXELWINDOW.pos.y = y0;
#endif
}
void display_refresh(void)
{
void display_refresh(void) {
#ifndef TREZOR_EMULATOR_NOUI
if (!RENDERER) {
display_init();
@ -176,30 +187,26 @@ void display_refresh(void)
}
SDL_UpdateTexture(TEXTURE, NULL, BUFFER->pixels, BUFFER->pitch);
#define BACKLIGHT_NORMAL 150
SDL_SetTextureAlphaMod(TEXTURE, MIN(255, 255 * DISPLAY_BACKLIGHT / BACKLIGHT_NORMAL));
SDL_SetTextureAlphaMod(TEXTURE,
MIN(255, 255 * DISPLAY_BACKLIGHT / BACKLIGHT_NORMAL));
if (BACKGROUND) {
const SDL_Rect r = {TOUCH_OFFSET_X, TOUCH_OFFSET_Y, DISPLAY_RESX, DISPLAY_RESY};
const SDL_Rect r = {TOUCH_OFFSET_X, TOUCH_OFFSET_Y, DISPLAY_RESX,
DISPLAY_RESY};
SDL_RenderCopyEx(RENDERER, TEXTURE, NULL, &r, DISPLAY_ORIENTATION, NULL, 0);
} else {
const SDL_Rect r = {EMULATOR_BORDER, EMULATOR_BORDER, DISPLAY_RESX, DISPLAY_RESY};
const SDL_Rect r = {EMULATOR_BORDER, EMULATOR_BORDER, DISPLAY_RESX,
DISPLAY_RESY};
SDL_RenderCopyEx(RENDERER, TEXTURE, NULL, &r, DISPLAY_ORIENTATION, NULL, 0);
}
SDL_RenderPresent(RENDERER);
#endif
}
static void display_set_orientation(int degrees)
{
display_refresh();
}
static void display_set_orientation(int degrees) { display_refresh(); }
static void display_set_backlight(int val)
{
display_refresh();
}
static void display_set_backlight(int val) { display_refresh(); }
void display_save(const char *prefix)
{
void display_save(const char *prefix) {
#ifndef TREZOR_EMULATOR_NOUI
if (!RENDERER) {
display_init();
@ -208,7 +215,10 @@ void display_save(const char *prefix)
char fname[256];
snprintf(fname, sizeof(fname), "%s%08d.png", prefix, cnt);
const SDL_Rect rect = {0, 0, DISPLAY_RESX, DISPLAY_RESY};
SDL_Surface *crop = SDL_CreateRGBSurface(BUFFER->flags, rect.w, rect.h, BUFFER->format->BitsPerPixel, BUFFER->format->Rmask, BUFFER->format->Gmask, BUFFER->format->Bmask, BUFFER->format->Amask);
SDL_Surface *crop = SDL_CreateRGBSurface(
BUFFER->flags, rect.w, rect.h, BUFFER->format->BitsPerPixel,
BUFFER->format->Rmask, BUFFER->format->Gmask, BUFFER->format->Bmask,
BUFFER->format->Amask);
SDL_BlitSurface(BUFFER, &rect, crop, NULL);
IMG_SavePNG(crop, fname);
SDL_FreeSurface(crop);

@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "inflate.h"
#include "font_bitmap.h"
#include "inflate.h"
#ifdef TREZOR_FONT_NORMAL_ENABLE
#include "font_roboto_regular_20.h"
#endif
@ -37,17 +37,15 @@
#include "common.h"
#include "display.h"
#include <string.h>
#include <stdarg.h>
#include <string.h>
#include "memzero.h"
static int DISPLAY_BACKLIGHT = -1;
static int DISPLAY_ORIENTATION = -1;
static struct {
int x, y;
} DISPLAY_OFFSET;
static struct { int x, y; } DISPLAY_OFFSET;
#ifdef TREZOR_EMULATOR
#include "display-unix.h"
@ -61,44 +59,52 @@ static struct {
// common display functions
static inline uint16_t interpolate_color(uint16_t color0, uint16_t color1, uint8_t step)
{
static inline uint16_t interpolate_color(uint16_t color0, uint16_t color1,
uint8_t step) {
uint8_t cr, cg, cb;
cr = (((color0 & 0xF800) >> 11) * step + ((color1 & 0xF800) >> 11) * (15 - step)) / 15;
cg = (((color0 & 0x07E0) >> 5) * step + ((color1 & 0x07E0) >> 5) * (15 - step)) / 15;
cr = (((color0 & 0xF800) >> 11) * step +
((color1 & 0xF800) >> 11) * (15 - step)) /
15;
cg = (((color0 & 0x07E0) >> 5) * step +
((color1 & 0x07E0) >> 5) * (15 - step)) /
15;
cb = ((color0 & 0x001F) * step + (color1 & 0x001F) * (15 - step)) / 15;
return (cr << 11) | (cg << 5) | cb;
}
static inline void set_color_table(uint16_t colortable[16], uint16_t fgcolor, uint16_t bgcolor)
{
static inline void set_color_table(uint16_t colortable[16], uint16_t fgcolor,
uint16_t bgcolor) {
for (int i = 0; i < 16; i++) {
colortable[i] = interpolate_color(fgcolor, bgcolor, i);
}
}
static inline void clamp_coords(int x, int y, int w, int h, int *x0, int *y0, int *x1, int *y1)
{
static inline void clamp_coords(int x, int y, int w, int h, int *x0, int *y0,
int *x1, int *y1) {
*x0 = MAX(x, 0);
*y0 = MAX(y, 0);
*x1 = MIN(x + w - 1, DISPLAY_RESX - 1);
*y1 = MIN(y + h - 1, DISPLAY_RESY - 1);
}
void display_clear(void)
{
void display_clear(void) {
const int saved_orientation = DISPLAY_ORIENTATION;
display_orientation(0); // set MADCTL first so that we can set the window correctly next
display_set_window(0, 0, MAX_DISPLAY_RESX - 1, MAX_DISPLAY_RESY - 1); // address the complete frame memory
display_orientation(
0); // set MADCTL first so that we can set the window correctly next
display_set_window(
0, 0, MAX_DISPLAY_RESX - 1,
MAX_DISPLAY_RESY - 1); // address the complete frame memory
for (uint32_t i = 0; i < MAX_DISPLAY_RESX * MAX_DISPLAY_RESY; i++) {
PIXELDATA(0x0000); // 2 bytes per pixel because we're using RGB 5-6-5 format
PIXELDATA(
0x0000); // 2 bytes per pixel because we're using RGB 5-6-5 format
}
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1); // go back to restricted window
display_orientation(saved_orientation); // if valid, go back to the saved orientation
display_set_window(0, 0, DISPLAY_RESX - 1,
DISPLAY_RESY - 1); // go back to restricted window
display_orientation(
saved_orientation); // if valid, go back to the saved orientation
}
void display_bar(int x, int y, int w, int h, uint16_t c)
{
void display_bar(int x, int y, int w, int h, uint16_t c) {
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
int x0, y0, x1, y1;
@ -112,26 +118,24 @@ void display_bar(int x, int y, int w, int h, uint16_t c)
#define CORNER_RADIUS 16
static const uint8_t cornertable[CORNER_RADIUS * CORNER_RADIUS] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 9, 12, 14, 15,
0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 15, 15, 15, 15, 15, 15,
0, 0, 0, 0, 0, 0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 0, 0, 0, 3, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 0, 0, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 0, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 0, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 9, 12, 14, 15, 0, 0, 0,
0, 0, 0, 0, 0, 3, 9, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0,
0, 8, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 3, 12, 15, 15,
15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 3, 14, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 0, 0, 0, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 0, 0, 0, 12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0,
8, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 9, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 5, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15,
};
void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b, uint8_t r)
{
void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b,
uint8_t r) {
if (r != 2 && r != 4 && r != 8 && r != 16) {
return;
} else {
@ -151,17 +155,15 @@ void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b, uint
if (rx < CORNER_RADIUS / r && ry < CORNER_RADIUS / r) {
uint8_t c = cornertable[rx * r + ry * r * CORNER_RADIUS];
PIXELDATA(colortable[c]);
} else
if (rx < CORNER_RADIUS / r && ry >= h - CORNER_RADIUS / r) {
} else if (rx < CORNER_RADIUS / r && ry >= h - CORNER_RADIUS / r) {
uint8_t c = cornertable[rx * r + (h - 1 - ry) * r * CORNER_RADIUS];
PIXELDATA(colortable[c]);
} else
if (rx >= w - CORNER_RADIUS / r && ry < CORNER_RADIUS / r) {
} else if (rx >= w - CORNER_RADIUS / r && ry < CORNER_RADIUS / r) {
uint8_t c = cornertable[(w - 1 - rx) * r + ry * r * CORNER_RADIUS];
PIXELDATA(colortable[c]);
} else
if (rx >= w - CORNER_RADIUS / r && ry >= h - CORNER_RADIUS / r) {
uint8_t c = cornertable[(w - 1 - rx) * r + (h - 1 - ry) * r * CORNER_RADIUS];
} else if (rx >= w - CORNER_RADIUS / r && ry >= h - CORNER_RADIUS / r) {
uint8_t c =
cornertable[(w - 1 - rx) * r + (h - 1 - ry) * r * CORNER_RADIUS];
PIXELDATA(colortable[c]);
} else {
PIXELDATA(c);
@ -172,8 +174,8 @@ void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b, uint
#if TREZOR_MODEL == T
static void inflate_callback_image(uint8_t byte1, uint32_t pos, void *userdata)
{
static void inflate_callback_image(uint8_t byte1, uint32_t pos,
void *userdata) {
static uint8_t byte0;
if (pos % 2 == 0) {
byte0 = byte1;
@ -193,8 +195,7 @@ static void inflate_callback_image(uint8_t byte1, uint32_t pos, void *userdata)
#endif
void display_image(int x, int y, int w, int h, const void *data, int datalen)
{
void display_image(int x, int y, int w, int h, const void *data, int datalen) {
#if TREZOR_MODEL == T
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
@ -208,10 +209,12 @@ void display_image(int x, int y, int w, int h, const void *data, int datalen)
#if TREZOR_MODEL == T
static void inflate_callback_avatar(uint8_t byte1, uint32_t pos, void *userdata)
{
static void inflate_callback_avatar(uint8_t byte1, uint32_t pos,
void *userdata) {
#define AVATAR_BORDER_SIZE 4
#define AVATAR_BORDER_LOW (AVATAR_IMAGE_SIZE / 2 - AVATAR_BORDER_SIZE) * (AVATAR_IMAGE_SIZE / 2 - AVATAR_BORDER_SIZE)
#define AVATAR_BORDER_LOW \
(AVATAR_IMAGE_SIZE / 2 - AVATAR_BORDER_SIZE) * \
(AVATAR_IMAGE_SIZE / 2 - AVATAR_BORDER_SIZE)
#define AVATAR_BORDER_HIGH (AVATAR_IMAGE_SIZE / 2) * (AVATAR_IMAGE_SIZE / 2)
#define AVATAR_ANTIALIAS 1
static uint8_t byte0;
@ -240,12 +243,13 @@ static void inflate_callback_avatar(uint8_t byte1, uint32_t pos, void *userdata)
// border area
} else {
#if AVATAR_ANTIALIAS
d = 31 * (d - AVATAR_BORDER_LOW) / (AVATAR_BORDER_HIGH - AVATAR_BORDER_LOW);
d = 31 * (d - AVATAR_BORDER_LOW) /
(AVATAR_BORDER_HIGH - AVATAR_BORDER_LOW);
uint16_t c;
if (d >= 16) {
c = interpolate_color(bgcolor, fgcolor, d - 16);
} else {
c = interpolate_color(fgcolor, (byte0 << 8) | byte1 , d);
c = interpolate_color(fgcolor, (byte0 << 8) | byte1, d);
}
PIXELDATA(c);
#else
@ -257,21 +261,21 @@ static void inflate_callback_avatar(uint8_t byte1, uint32_t pos, void *userdata)
#endif
void display_avatar(int x, int y, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor)
{
void display_avatar(int x, int y, const void *data, int datalen,
uint16_t fgcolor, uint16_t bgcolor) {
#if TREZOR_MODEL == T
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
int x0, y0, x1, y1;
clamp_coords(x, y, AVATAR_IMAGE_SIZE, AVATAR_IMAGE_SIZE, &x0, &y0, &x1, &y1);
display_set_window(x0, y0, x1, y1);
int userdata[7] = {AVATAR_IMAGE_SIZE, x0 - x, x1 - x, y0 - y, y1 - y, fgcolor, bgcolor};
int userdata[7] = {AVATAR_IMAGE_SIZE, x0 - x, x1 - x, y0 - y, y1 - y,
fgcolor, bgcolor};
sinf_inflate(data, datalen, inflate_callback_avatar, userdata);
#endif
}
static void inflate_callback_icon(uint8_t byte, uint32_t pos, void *userdata)
{
static void inflate_callback_icon(uint8_t byte, uint32_t pos, void *userdata) {
const uint16_t *colortable = (const uint16_t *)(((const int *)userdata) + 5);
const int w = ((const int *)userdata)[0];
const int x0 = ((const int *)userdata)[1];
@ -286,15 +290,16 @@ static void inflate_callback_icon(uint8_t byte, uint32_t pos, void *userdata)
}
}
void display_icon(int x, int y, int w, int h, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor)
{
void display_icon(int x, int y, int w, int h, const void *data, int datalen,
uint16_t fgcolor, uint16_t bgcolor) {
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
x &= ~1; // cannot draw at odd coordinate
int x0, y0, x1, y1;
clamp_coords(x, y, w, h, &x0, &y0, &x1, &y1);
display_set_window(x0, y0, x1, y1);
int userdata[5 + 16 * sizeof(uint16_t) / sizeof(int)] = {w, x0 - x, x1 - x, y0 - y, y1 - y};
int userdata[5 + 16 * sizeof(uint16_t) / sizeof(int)] = {w, x0 - x, x1 - x,
y0 - y, y1 - y};
set_color_table((uint16_t *)(userdata + 5), fgcolor, bgcolor);
sinf_inflate(data, datalen, inflate_callback_icon, userdata);
}
@ -303,16 +308,17 @@ void display_icon(int x, int y, int w, int h, const void *data, int datalen, uin
#include "loader.h"
static void inflate_callback_loader(uint8_t byte, uint32_t pos, void *userdata)
{
static void inflate_callback_loader(uint8_t byte, uint32_t pos,
void *userdata) {
uint8_t *out = (uint8_t *)userdata;
out[pos] = byte;
}
#endif
void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor)
{
void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor,
uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen,
uint16_t iconfgcolor) {
#if TREZOR_MODEL == T
uint16_t colortable[16], iconcolortable[16];
set_color_table(colortable, fgcolor, bgcolor);
@ -323,8 +329,14 @@ void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t b
(DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset >= DISPLAY_RESY)) {
return;
}
display_set_window(DISPLAY_RESX / 2 - img_loader_size, DISPLAY_RESY / 2 - img_loader_size + yoffset, DISPLAY_RESX / 2 + img_loader_size - 1, DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset);
if (icon && memcmp(icon, "TOIg", 4) == 0 && LOADER_ICON_SIZE == *(uint16_t *)(icon + 4) && LOADER_ICON_SIZE == *(uint16_t *)(icon + 6) && iconlen == 12 + *(uint32_t *)(icon + 8)) {
display_set_window(DISPLAY_RESX / 2 - img_loader_size,
DISPLAY_RESY / 2 - img_loader_size + yoffset,
DISPLAY_RESX / 2 + img_loader_size - 1,
DISPLAY_RESY / 2 + img_loader_size - 1 + yoffset);
if (icon && memcmp(icon, "TOIg", 4) == 0 &&
LOADER_ICON_SIZE == *(uint16_t *)(icon + 4) &&
LOADER_ICON_SIZE == *(uint16_t *)(icon + 6) &&
iconlen == 12 + *(uint32_t *)(icon + 8)) {
uint8_t icondata[LOADER_ICON_SIZE * LOADER_ICON_SIZE / 2];
sinf_inflate(icon + 12, iconlen - 12, inflate_callback_loader, icondata);
icon = icondata;
@ -339,21 +351,24 @@ void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t b
mx = img_loader_size * 2 - 1 - x;
my = img_loader_size * 2 - 1 - y;
a = 499 - (img_loader[my][mx] >> 8);
} else
if (mx >= img_loader_size) {
} else if (mx >= img_loader_size) {
mx = img_loader_size * 2 - 1 - x;
a = img_loader[my][mx] >> 8;
} else
if (my >= img_loader_size) {
} else if (my >= img_loader_size) {
my = img_loader_size * 2 - 1 - y;
a = 500 + (img_loader[my][mx] >> 8);
} else {
a = 999 - (img_loader[my][mx] >> 8);
}
// inside of circle - draw glyph
#define LOADER_ICON_CORNER_CUT 2
if (icon && mx + my > (((LOADER_ICON_SIZE / 2) + LOADER_ICON_CORNER_CUT) * 2) && mx >= img_loader_size - (LOADER_ICON_SIZE / 2) && my >= img_loader_size - (LOADER_ICON_SIZE / 2)) {
int i = (x - (img_loader_size - (LOADER_ICON_SIZE / 2))) + (y - (img_loader_size - (LOADER_ICON_SIZE / 2))) * LOADER_ICON_SIZE;
// inside of circle - draw glyph
#define LOADER_ICON_CORNER_CUT 2
if (icon &&
mx + my > (((LOADER_ICON_SIZE / 2) + LOADER_ICON_CORNER_CUT) * 2) &&
mx >= img_loader_size - (LOADER_ICON_SIZE / 2) &&
my >= img_loader_size - (LOADER_ICON_SIZE / 2)) {
int i =
(x - (img_loader_size - (LOADER_ICON_SIZE / 2))) +
(y - (img_loader_size - (LOADER_ICON_SIZE / 2))) * LOADER_ICON_SIZE;
uint8_t c;
if (i % 2) {
c = icon[i / 2] & 0x0F;
@ -380,18 +395,17 @@ void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t b
#define DISPLAY_PRINT_COLS (DISPLAY_RESX / 6)
#define DISPLAY_PRINT_ROWS (DISPLAY_RESY / 8)
static char display_print_buf[DISPLAY_PRINT_ROWS][DISPLAY_PRINT_COLS];
static uint16_t display_print_fgcolor = COLOR_WHITE, display_print_bgcolor = COLOR_BLACK;
static uint16_t display_print_fgcolor = COLOR_WHITE,
display_print_bgcolor = COLOR_BLACK;
// set colors for display_print function
void display_print_color(uint16_t fgcolor, uint16_t bgcolor)
{
void display_print_color(uint16_t fgcolor, uint16_t bgcolor) {
display_print_fgcolor = fgcolor;
display_print_bgcolor = bgcolor;
}
// display text using bitmap font
void display_print(const char *text, int textlen)
{
void display_print(const char *text, int textlen) {
static uint8_t row = 0, col = 0;
// determine text length if not provided
@ -401,7 +415,6 @@ void display_print(const char *text, int textlen)
// print characters to internal buffer (display_print_buf)
for (int i = 0; i < textlen; i++) {
switch (text[i]) {
case '\r':
break;
@ -422,12 +435,12 @@ void display_print(const char *text, int textlen)
if (row >= DISPLAY_PRINT_ROWS) {
for (int j = 0; j < DISPLAY_PRINT_ROWS - 1; j++) {
memcpy(display_print_buf[j], display_print_buf[j + 1], DISPLAY_PRINT_COLS);
memcpy(display_print_buf[j], display_print_buf[j + 1],
DISPLAY_PRINT_COLS);
}
memzero(display_print_buf[DISPLAY_PRINT_ROWS - 1], DISPLAY_PRINT_COLS);
row = DISPLAY_PRINT_ROWS - 1;
}
}
// render buffer to display
@ -435,8 +448,10 @@ void display_print(const char *text, int textlen)
for (int i = 0; i < DISPLAY_RESX * DISPLAY_RESY; i++) {
int x = (i % DISPLAY_RESX);
int y = (i / DISPLAY_RESX);
const int j = y % 8; y /= 8;
const int k = x % 6; x /= 6;
const int j = y % 8;
y /= 8;
const int k = x % 6;
x /= 6;
char c;
if (x < DISPLAY_PRINT_COLS && y < DISPLAY_PRINT_ROWS) {
c = display_print_buf[y][x] & 0x7F;
@ -465,8 +480,7 @@ void display_print(const char *text, int textlen)
#endif
// variadic display_print
void display_printf(const char *fmt, ...)
{
void display_printf(const char *fmt, ...) {
if (!strchr(fmt, '%')) {
display_print(fmt, strlen(fmt));
} else {
@ -483,8 +497,7 @@ void display_printf(const char *fmt, ...)
#if TREZOR_MODEL == T
static const uint8_t *get_glyph(int font, uint8_t c)
{
static const uint8_t *get_glyph(int font, uint8_t c) {
if (c >= ' ' && c <= '~') {
// do nothing - valid ASCII
} else
@ -521,8 +534,8 @@ static const uint8_t *get_glyph(int font, uint8_t c)
#if TREZOR_MODEL == T
static void display_text_render(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor)
{
static void display_text_render(int x, int y, const char *text, int textlen,
int font, uint16_t fgcolor, uint16_t bgcolor) {
// determine text length if not provided
if (textlen < 0) {
textlen = strlen(text);
@ -551,13 +564,13 @@ static void display_text_render(int x, int y, const char *text, int textlen, int
const int rx = i - sx;
const int ry = j - sy;
const int a = rx + ry * w;
#if FONT_BPP == 2
#if FONT_BPP == 2
const uint8_t c = ((g[5 + a / 4] >> (6 - (a % 4) * 2)) & 0x03) * 5;
#elif FONT_BPP == 4
#elif FONT_BPP == 4
const uint8_t c = (g[5 + a / 2] >> (4 - (a % 2) * 4)) & 0x0F;
#else
#error Unsupported FONT_BPP value
#endif
#else
#error Unsupported FONT_BPP value
#endif
PIXELDATA(colortable[c]);
}
}
@ -568,8 +581,8 @@ static void display_text_render(int x, int y, const char *text, int textlen, int
#endif
void display_text(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor)
{
void display_text(int x, int y, const char *text, int textlen, int font,
uint16_t fgcolor, uint16_t bgcolor) {
#if TREZOR_MODEL == T
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
@ -577,8 +590,8 @@ void display_text(int x, int y, const char *text, int textlen, int font, uint16_
#endif
}
void display_text_center(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor)
{
void display_text_center(int x, int y, const char *text, int textlen, int font,
uint16_t fgcolor, uint16_t bgcolor) {
#if TREZOR_MODEL == T
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
@ -587,8 +600,8 @@ void display_text_center(int x, int y, const char *text, int textlen, int font,
#endif
}
void display_text_right(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor)
{
void display_text_right(int x, int y, const char *text, int textlen, int font,
uint16_t fgcolor, uint16_t bgcolor) {
#if TREZOR_MODEL == T
x += DISPLAY_OFFSET.x;
y += DISPLAY_OFFSET.y;
@ -598,8 +611,7 @@ void display_text_right(int x, int y, const char *text, int textlen, int font, u
}
// compute the width of the text (in pixels)
int display_text_width(const char *text, int textlen, int font)
{
int display_text_width(const char *text, int textlen, int font) {
int width = 0;
#if TREZOR_MODEL == T
// determine text length if not provided
@ -628,30 +640,25 @@ int display_text_width(const char *text, int textlen, int font)
#define QR_MAX_VERSION 9
void display_qrcode(int x, int y, const char *data, int datalen, uint8_t scale)
{
void display_qrcode(int x, int y, const char *data, int datalen,
uint8_t scale) {
if (scale < 1 || scale > 10) return;
uint8_t codedata[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_MAX_VERSION)];
uint8_t tempdata[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_MAX_VERSION)];
int side = 0;
if (qrcodegen_encodeText(
data,
tempdata,
codedata,
qrcodegen_Ecc_MEDIUM,
qrcodegen_VERSION_MIN,
QR_MAX_VERSION,
qrcodegen_Mask_AUTO,
true)) {
if (qrcodegen_encodeText(data, tempdata, codedata, qrcodegen_Ecc_MEDIUM,
qrcodegen_VERSION_MIN, QR_MAX_VERSION,
qrcodegen_Mask_AUTO, true)) {
side = qrcodegen_getSize(codedata);
}
x += DISPLAY_OFFSET.x - (side + 2) * scale / 2;
y += DISPLAY_OFFSET.y - (side + 2) * scale / 2;
int x0, y0, x1, y1;
clamp_coords(x, y, (side + 2) * scale, (side + 2) * scale, &x0, &y0, &x1, &y1);
clamp_coords(x, y, (side + 2) * scale, (side + 2) * scale, &x0, &y0, &x1,
&y1);
display_set_window(x0, y0, x1, y1);
for (int j = y0; j <= y1; j++) {
for (int i = x0; i <= x1; i++) {
@ -671,8 +678,7 @@ void display_qrcode(int x, int y, const char *data, int datalen, uint8_t scale)
}
}
void display_offset(int set_xy[2], int *get_x, int *get_y)
{
void display_offset(int set_xy[2], int *get_x, int *get_y) {
if (set_xy) {
DISPLAY_OFFSET.x = set_xy[0];
DISPLAY_OFFSET.y = set_xy[1];
@ -681,8 +687,7 @@ void display_offset(int set_xy[2], int *get_x, int *get_y)
*get_y = DISPLAY_OFFSET.y;
}
int display_orientation(int degrees)
{
int display_orientation(int degrees) {
if (degrees != DISPLAY_ORIENTATION) {
#if TREZOR_MODEL == T
if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) {
@ -698,8 +703,7 @@ int display_orientation(int degrees)
return DISPLAY_ORIENTATION;
}
int display_backlight(int val)
{
int display_backlight(int val) {
#if TREZOR_MODEL == 1
val = 255;
#endif
@ -710,8 +714,7 @@ int display_backlight(int val)
return DISPLAY_BACKLIGHT;
}
void display_fade(int start, int end, int delay)
{
void display_fade(int start, int end, int delay) {
for (int i = 0; i < 100; i++) {
display_backlight(start + i * (end - start) / 100);
hal_delay(delay / 100);

@ -74,22 +74,31 @@ void display_save(const char *prefix);
void display_clear(void);
void display_bar(int x, int y, int w, int h, uint16_t c);
void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b, uint8_t r);
void display_bar_radius(int x, int y, int w, int h, uint16_t c, uint16_t b,
uint8_t r);
void display_image(int x, int y, int w, int h, const void *data, int datalen);
void display_avatar(int x, int y, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor);
void display_icon(int x, int y, int w, int h, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor);
void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor);
void display_avatar(int x, int y, const void *data, int datalen,
uint16_t fgcolor, uint16_t bgcolor);
void display_icon(int x, int y, int w, int h, const void *data, int datalen,
uint16_t fgcolor, uint16_t bgcolor);
void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor,
uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen,
uint16_t iconfgcolor);
#ifndef TREZOR_PRINT_DISABLE
void display_print_color(uint16_t fgcolor, uint16_t bgcolor);
void display_print(const char *text, int textlen);
void display_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
void display_printf(const char *fmt, ...)
__attribute__((__format__(__printf__, 1, 2)));
#endif
void display_text(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor);
void display_text_center(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor);
void display_text_right(int x, int y, const char *text, int textlen, int font, uint16_t fgcolor, uint16_t bgcolor);
void display_text(int x, int y, const char *text, int textlen, int font,
uint16_t fgcolor, uint16_t bgcolor);
void display_text_center(int x, int y, const char *text, int textlen, int font,
uint16_t fgcolor, uint16_t bgcolor);
void display_text_right(int x, int y, const char *text, int textlen, int font,
uint16_t fgcolor, uint16_t bgcolor);
int display_text_width(const char *text, int textlen, int font);
void display_qrcode(int x, int y, const char *data, int datalen, uint8_t scale);

@ -1,5 +1,7 @@
#include "font_bitmap.h"
// clang-format off
const uint8_t * const Font_Bitmap = (const uint8_t * const)
"\x00\x00\x00\x00\x00"
"\x00\x00\x5f\x00\x00"

@ -1,3 +1,3 @@
#include <stdint.h>
extern const uint8_t * const Font_Bitmap;
extern const uint8_t* const Font_Bitmap;

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// clang-format off
/*
* stream_inflate - tiny inflate library with output streaming
*

@ -22,6 +22,9 @@
#include <stdint.h>
int sinf_inflate(const uint8_t *data, uint32_t datalen, void (*write_callback)(uint8_t byte, uint32_t pos, void *userdata), void *userdata);
int sinf_inflate(const uint8_t *data, uint32_t datalen,
void (*write_callback)(uint8_t byte, uint32_t pos,
void *userdata),
void *userdata);
#endif

@ -1,3 +1,4 @@
// clang-format off
static const int img_loader_size = 60;
static const uint16_t img_loader[60][60] = {
{31744,31488,30976,30720,30208,29952,29696,29184,28672,28416,27904,27648,27136,26624,26368,25856,25344,25088,24576,24064,23552,23040,22528,22016,21504,20992,20480,19968,19456,18944,18432,17920,17408,16640,16128,15616,14848,14336,13824,13056,12544,11776,11264,10496,9984,9216,8704,7936,7424,6656,5888,5376,4624,4128,3393,2641,2146,1378,626,114,},

@ -33,7 +33,9 @@ typedef struct _mp_obj_Display_t {
/// '''
/// Initialize the display.
/// '''
STATIC mp_obj_t mod_trezorui_Display_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 0, false);
mp_obj_Display_t *o = m_new_obj(mp_obj_Display_t);
o->base.type = type;
@ -48,7 +50,8 @@ STATIC mp_obj_t mod_trezorui_Display_clear(mp_obj_t self) {
display_clear();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorui_Display_clear_obj, mod_trezorui_Display_clear);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorui_Display_clear_obj,
mod_trezorui_Display_clear);
/// def refresh(self) -> None:
/// '''
@ -58,11 +61,13 @@ STATIC mp_obj_t mod_trezorui_Display_refresh(mp_obj_t self) {
display_refresh();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorui_Display_refresh_obj, mod_trezorui_Display_refresh);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorui_Display_refresh_obj,
mod_trezorui_Display_refresh);
/// def bar(self, x: int, y: int, w: int, h: int, color: int) -> None:
/// '''
/// Renders a bar at position (x,y = upper left corner) with width w and height h of color color.
/// Renders a bar at position (x,y = upper left corner) with width w and
/// height h of color color.
/// '''
STATIC mp_obj_t mod_trezorui_Display_bar(size_t n_args, const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
@ -73,14 +78,18 @@ STATIC mp_obj_t mod_trezorui_Display_bar(size_t n_args, const mp_obj_t *args) {
display_bar(x, y, w, h, c);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_bar_obj, 6, 6, mod_trezorui_Display_bar);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_bar_obj, 6, 6,
mod_trezorui_Display_bar);
/// def bar_radius(self, x: int, y: int, w: int, h: int, fgcolor: int, bgcolor: int = None, radius: int = None) -> None:
/// def bar_radius(self, x: int, y: int, w: int, h: int, fgcolor: int, bgcolor:
/// int = None, radius: int = None) -> None:
/// '''
/// Renders a rounded bar at position (x,y = upper left corner) with width w and height h of color fgcolor.
/// Background is set to bgcolor and corners are drawn with radius radius.
/// Renders a rounded bar at position (x,y = upper left corner) with width w
/// and height h of color fgcolor. Background is set to bgcolor and corners
/// are drawn with radius radius.
/// '''
STATIC mp_obj_t mod_trezorui_Display_bar_radius(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_bar_radius(size_t n_args,
const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_int_t w = mp_obj_get_int(args[3]);
@ -91,14 +100,18 @@ STATIC mp_obj_t mod_trezorui_Display_bar_radius(size_t n_args, const mp_obj_t *a
display_bar_radius(x, y, w, h, c, b, r);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_bar_radius_obj, 8, 8, mod_trezorui_Display_bar_radius);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_bar_radius_obj,
8, 8,
mod_trezorui_Display_bar_radius);
/// def image(self, x: int, y: int, image: bytes) -> None:
/// '''
/// Renders an image at position (x,y).
/// The image needs to be in TREZOR Optimized Image Format (TOIF) - full-color mode.
/// The image needs to be in TREZOR Optimized Image Format (TOIF) -
/// full-color mode.
/// '''
STATIC mp_obj_t mod_trezorui_Display_image(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_image(size_t n_args,
const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_buffer_info_t image;
@ -116,15 +129,19 @@ STATIC mp_obj_t mod_trezorui_Display_image(size_t n_args, const mp_obj_t *args)
display_image(x, y, w, h, data + 12, datalen);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_image_obj, 4, 4, mod_trezorui_Display_image);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_image_obj, 4, 4,
mod_trezorui_Display_image);
/// def avatar(self, x: int, y: int, image: bytes, fgcolor: int, bgcolor: int) -> None:
/// def avatar(self, x: int, y: int, image: bytes, fgcolor: int, bgcolor: int)
/// -> None:
/// '''
/// Renders an avatar at position (x,y).
/// The image needs to be in TREZOR Optimized Image Format (TOIF) - full-color mode.
/// Image needs to be of exactly AVATAR_IMAGE_SIZE x AVATAR_IMAGE_SIZE pixels size.
/// The image needs to be in TREZOR Optimized Image Format (TOIF) -
/// full-color mode. Image needs to be of exactly AVATAR_IMAGE_SIZE x
/// AVATAR_IMAGE_SIZE pixels size.
/// '''
STATIC mp_obj_t mod_trezorui_Display_avatar(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_avatar(size_t n_args,
const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_buffer_info_t image;
@ -147,12 +164,15 @@ STATIC mp_obj_t mod_trezorui_Display_avatar(size_t n_args, const mp_obj_t *args)
display_avatar(x, y, data + 12, datalen, fgcolor, bgcolor);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_avatar_obj, 6, 6, mod_trezorui_Display_avatar);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_avatar_obj, 6,
6, mod_trezorui_Display_avatar);
/// def icon(self, x: int, y: int, icon: bytes, fgcolor: int, bgcolor: int) -> None:
/// def icon(self, x: int, y: int, icon: bytes, fgcolor: int, bgcolor: int) ->
/// None:
/// '''
/// Renders an icon at position (x,y), fgcolor is used as foreground color, bgcolor as background.
/// The icon needs to be in TREZOR Optimized Image Format (TOIF) - gray-scale mode.
/// Renders an icon at position (x,y), fgcolor is used as foreground color,
/// bgcolor as background. The icon needs to be in TREZOR Optimized Image
/// Format (TOIF) - gray-scale mode.
/// '''
STATIC mp_obj_t mod_trezorui_Display_icon(size_t n_args, const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
@ -175,15 +195,20 @@ STATIC mp_obj_t mod_trezorui_Display_icon(size_t n_args, const mp_obj_t *args) {
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_icon_obj, 6, 6, mod_trezorui_Display_icon);
/// def loader(self, progress: int, yoffset: int, fgcolor: int, bgcolor: int, icon: bytes = None, iconfgcolor: int = None) -> None:
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_icon_obj, 6, 6,
mod_trezorui_Display_icon);
/// def loader(self, progress: int, yoffset: int, fgcolor: int, bgcolor: int,
/// icon: bytes = None, iconfgcolor: int = None) -> None:
/// '''
/// Renders a rotating loader graphic.
/// Progress determines its position (0-1000), fgcolor is used as foreground color, bgcolor as background.
/// When icon and iconfgcolor are provided, an icon is drawn in the middle using the color specified in iconfgcolor.
/// Icon needs to be of exactly LOADER_ICON_SIZE x LOADER_ICON_SIZE pixels size.
/// '''
STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args, const mp_obj_t *args) {
/// Progress determines its position (0-1000), fgcolor is used as foreground
/// color, bgcolor as background. When icon and iconfgcolor are provided, an
/// icon is drawn in the middle using the color specified in iconfgcolor.
/// Icon needs to be of exactly LOADER_ICON_SIZE x LOADER_ICON_SIZE pixels
/// size.
/// '''
STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args,
const mp_obj_t *args) {
mp_int_t progress = mp_obj_get_int(args[1]);
mp_int_t yoffset = mp_obj_get_int(args[2]);
mp_int_t fgcolor = mp_obj_get_int(args[3]);
@ -210,13 +235,15 @@ STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args, const mp_obj_t *args)
} else {
iconfgcolor = ~bgcolor; // invert
}
display_loader(progress, yoffset, fgcolor, bgcolor, icon.buf, icon.len, iconfgcolor);
display_loader(progress, yoffset, fgcolor, bgcolor, icon.buf, icon.len,
iconfgcolor);
} else {
display_loader(progress, yoffset, fgcolor, bgcolor, NULL, 0, 0);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_loader_obj, 5, 7, mod_trezorui_Display_loader);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_loader_obj, 5,
7, mod_trezorui_Display_loader);
/// def print(self, text: str) -> None:
/// '''
@ -230,14 +257,16 @@ STATIC mp_obj_t mod_trezorui_Display_print(mp_obj_t self, mp_obj_t text) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorui_Display_print_obj, mod_trezorui_Display_print);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorui_Display_print_obj,
mod_trezorui_Display_print);
/// def text(self, x: int, y: int, text: str, font: int, fgcolor: int, bgcolor: int, minwidth: int=None) -> int:
/// def text(self, x: int, y: int, text: str, font: int, fgcolor: int, bgcolor:
/// int, minwidth: int=None) -> int:
/// '''
/// Renders left-aligned text at position (x,y) where x is left position and y is baseline.
/// Font font is used for rendering, fgcolor is used as foreground color, bgcolor as background.
/// Fills at least minwidth pixels with bgcolor.
/// Returns width of rendered text in pixels.
/// Renders left-aligned text at position (x,y) where x is left position and
/// y is baseline. Font font is used for rendering, fgcolor is used as
/// foreground color, bgcolor as background. Fills at least minwidth pixels
/// with bgcolor. Returns width of rendered text in pixels.
/// '''
STATIC mp_obj_t mod_trezorui_Display_text(size_t n_args, const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
@ -256,16 +285,19 @@ STATIC mp_obj_t mod_trezorui_Display_text(size_t n_args, const mp_obj_t *args) {
display_text(x, y, text.buf, text.len, font, fgcolor, bgcolor);
return mp_obj_new_int(w);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_obj, 7, 8, mod_trezorui_Display_text);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_obj, 7, 8,
mod_trezorui_Display_text);
/// def text_center(self, x: int, y: int, text: str, font: int, fgcolor: int, bgcolor: int, minwidth: int=None) -> int:
/// def text_center(self, x: int, y: int, text: str, font: int, fgcolor: int,
/// bgcolor: int, minwidth: int=None) -> int:
/// '''
/// Renders text centered at position (x,y) where x is text center and y is baseline.
/// Font font is used for rendering, fgcolor is used as foreground color, bgcolor as background.
/// Fills at least minwidth pixels with bgcolor.
/// Returns width of rendered text in pixels.
/// Renders text centered at position (x,y) where x is text center and y is
/// baseline. Font font is used for rendering, fgcolor is used as foreground
/// color, bgcolor as background. Fills at least minwidth pixels with
/// bgcolor. Returns width of rendered text in pixels.
/// '''
STATIC mp_obj_t mod_trezorui_Display_text_center(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_text_center(size_t n_args,
const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_buffer_info_t text;
@ -282,16 +314,20 @@ STATIC mp_obj_t mod_trezorui_Display_text_center(size_t n_args, const mp_obj_t *
display_text_center(x, y, text.buf, text.len, font, fgcolor, bgcolor);
return mp_obj_new_int(w);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_center_obj, 7, 8, mod_trezorui_Display_text_center);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_center_obj,
7, 8,
mod_trezorui_Display_text_center);
/// def text_right(self, x: int, y: int, text: str, font: int, fgcolor: int, bgcolor: int, minwidth: int=None) -> int:
/// def text_right(self, x: int, y: int, text: str, font: int, fgcolor: int,
/// bgcolor: int, minwidth: int=None) -> int:
/// '''
/// Renders right-aligned text at position (x,y) where x is right position and y is baseline.
/// Font font is used for rendering, fgcolor is used as foreground color, bgcolor as background.
/// Fills at least minwidth pixels with bgcolor.
/// Returns width of rendered text in pixels.
/// Renders right-aligned text at position (x,y) where x is right position
/// and y is baseline. Font font is used for rendering, fgcolor is used as
/// foreground color, bgcolor as background. Fills at least minwidth pixels
/// with bgcolor. Returns width of rendered text in pixels.
/// '''
STATIC mp_obj_t mod_trezorui_Display_text_right(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_text_right(size_t n_args,
const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_buffer_info_t text;
@ -308,27 +344,32 @@ STATIC mp_obj_t mod_trezorui_Display_text_right(size_t n_args, const mp_obj_t *a
display_text_right(x, y, text.buf, text.len, font, fgcolor, bgcolor);
return mp_obj_new_int(w);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_right_obj, 7, 8, mod_trezorui_Display_text_right);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_text_right_obj,
7, 8,
mod_trezorui_Display_text_right);
/// def text_width(self, text: str, font: int) -> int:
/// '''
/// Returns a width of text in pixels. Font font is used for rendering.
/// '''
STATIC mp_obj_t mod_trezorui_Display_text_width(mp_obj_t self, mp_obj_t text, mp_obj_t font) {
STATIC mp_obj_t mod_trezorui_Display_text_width(mp_obj_t self, mp_obj_t text,
mp_obj_t font) {
mp_buffer_info_t txt;
mp_get_buffer_raise(text, &txt, MP_BUFFER_READ);
mp_int_t f = mp_obj_get_int(font);
int w = display_text_width(txt.buf, txt.len, f);
return mp_obj_new_int(w);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorui_Display_text_width_obj, mod_trezorui_Display_text_width);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorui_Display_text_width_obj,
mod_trezorui_Display_text_width);
/// def qrcode(self, x: int, y: int, data: bytes, scale: int) -> None:
/// '''
/// Renders data encoded as a QR code centered at position (x,y).
/// Scale determines a zoom factor.
/// '''
STATIC mp_obj_t mod_trezorui_Display_qrcode(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_qrcode(size_t n_args,
const mp_obj_t *args) {
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_int_t scale = mp_obj_get_int(args[4]);
@ -342,15 +383,18 @@ STATIC mp_obj_t mod_trezorui_Display_qrcode(size_t n_args, const mp_obj_t *args)
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_qrcode_obj, 5, 5, mod_trezorui_Display_qrcode);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_qrcode_obj, 5,
5, mod_trezorui_Display_qrcode);
/// def orientation(self, degrees: int = None) -> int:
/// '''
/// Sets display orientation to 0, 90, 180 or 270 degrees.
/// Everything needs to be redrawn again when this function is used.
/// Call without the degrees parameter to just perform the read of the value.
/// Call without the degrees parameter to just perform the read of the
/// value.
/// '''
STATIC mp_obj_t mod_trezorui_Display_orientation(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_orientation(size_t n_args,
const mp_obj_t *args) {
mp_int_t deg;
if (n_args > 1) {
deg = mp_obj_get_int(args[1]);
@ -363,14 +407,17 @@ STATIC mp_obj_t mod_trezorui_Display_orientation(size_t n_args, const mp_obj_t *
}
return MP_OBJ_NEW_SMALL_INT(deg);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_orientation_obj, 1, 2, mod_trezorui_Display_orientation);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_orientation_obj,
1, 2,
mod_trezorui_Display_orientation);
/// def backlight(self, val: int = None) -> int:
/// '''
/// Sets backlight intensity to the value specified in val.
/// Call without the val parameter to just perform the read of the value.
/// '''
STATIC mp_obj_t mod_trezorui_Display_backlight(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_backlight(size_t n_args,
const mp_obj_t *args) {
mp_int_t val;
if (n_args > 1) {
val = mp_obj_get_int(args[1]);
@ -383,14 +430,17 @@ STATIC mp_obj_t mod_trezorui_Display_backlight(size_t n_args, const mp_obj_t *ar
}
return MP_OBJ_NEW_SMALL_INT(val);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_backlight_obj, 1, 2, mod_trezorui_Display_backlight);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_backlight_obj,
1, 2,
mod_trezorui_Display_backlight);
/// def offset(self, xy: Tuple[int, int] = None) -> Tuple[int, int]:
/// '''
/// Sets offset (x, y) for all subsequent drawing calls.
/// Call without the xy parameter to just perform the read of the value.
/// '''
STATIC mp_obj_t mod_trezorui_Display_offset(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorui_Display_offset(size_t n_args,
const mp_obj_t *args) {
int xy[2], x, y;
if (n_args > 1) {
size_t xy_cnt;
@ -414,7 +464,8 @@ STATIC mp_obj_t mod_trezorui_Display_offset(size_t n_args, const mp_obj_t *args)
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(y);
return MP_OBJ_FROM_PTR(tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_offset_obj, 1, 2, mod_trezorui_Display_offset);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_offset_obj, 1,
2, mod_trezorui_Display_offset);
/// def save(self, prefix: str) -> None:
/// '''
@ -428,40 +479,49 @@ STATIC mp_obj_t mod_trezorui_Display_save(mp_obj_t self, mp_obj_t prefix) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorui_Display_save_obj, mod_trezorui_Display_save);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorui_Display_save_obj,
mod_trezorui_Display_save);
STATIC const mp_rom_map_elem_t mod_trezorui_Display_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&mod_trezorui_Display_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&mod_trezorui_Display_refresh_obj) },
{ MP_ROM_QSTR(MP_QSTR_bar), MP_ROM_PTR(&mod_trezorui_Display_bar_obj) },
{ MP_ROM_QSTR(MP_QSTR_bar_radius), MP_ROM_PTR(&mod_trezorui_Display_bar_radius_obj) },
{ MP_ROM_QSTR(MP_QSTR_image), MP_ROM_PTR(&mod_trezorui_Display_image_obj) },
{ MP_ROM_QSTR(MP_QSTR_avatar), MP_ROM_PTR(&mod_trezorui_Display_avatar_obj) },
{ MP_ROM_QSTR(MP_QSTR_icon), MP_ROM_PTR(&mod_trezorui_Display_icon_obj) },
{ MP_ROM_QSTR(MP_QSTR_loader), MP_ROM_PTR(&mod_trezorui_Display_loader_obj) },
{ MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mod_trezorui_Display_print_obj) },
{ MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&mod_trezorui_Display_text_obj) },
{ MP_ROM_QSTR(MP_QSTR_text_center), MP_ROM_PTR(&mod_trezorui_Display_text_center_obj) },
{ MP_ROM_QSTR(MP_QSTR_text_right), MP_ROM_PTR(&mod_trezorui_Display_text_right_obj) },
{ MP_ROM_QSTR(MP_QSTR_text_width), MP_ROM_PTR(&mod_trezorui_Display_text_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_qrcode), MP_ROM_PTR(&mod_trezorui_Display_qrcode_obj) },
{ MP_ROM_QSTR(MP_QSTR_orientation), MP_ROM_PTR(&mod_trezorui_Display_orientation_obj) },
{ MP_ROM_QSTR(MP_QSTR_backlight), MP_ROM_PTR(&mod_trezorui_Display_backlight_obj) },
{ MP_ROM_QSTR(MP_QSTR_offset), MP_ROM_PTR(&mod_trezorui_Display_offset_obj) },
{ MP_ROM_QSTR(MP_QSTR_save), MP_ROM_PTR(&mod_trezorui_Display_save_obj) },
{ MP_ROM_QSTR(MP_QSTR_WIDTH), MP_OBJ_NEW_SMALL_INT(DISPLAY_RESX) },
{ MP_ROM_QSTR(MP_QSTR_HEIGHT), MP_OBJ_NEW_SMALL_INT(DISPLAY_RESY) },
{ MP_ROM_QSTR(MP_QSTR_FONT_SIZE), MP_OBJ_NEW_SMALL_INT(FONT_SIZE) },
{ MP_ROM_QSTR(MP_QSTR_FONT_NORMAL), MP_OBJ_NEW_SMALL_INT(FONT_NORMAL) },
{ MP_ROM_QSTR(MP_QSTR_FONT_BOLD), MP_OBJ_NEW_SMALL_INT(FONT_BOLD) },
{ MP_ROM_QSTR(MP_QSTR_FONT_MONO), MP_OBJ_NEW_SMALL_INT(FONT_MONO) },
{ MP_ROM_QSTR(MP_QSTR_FONT_MONO_BOLD), MP_OBJ_NEW_SMALL_INT(FONT_MONO_BOLD) },
{MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&mod_trezorui_Display_clear_obj)},
{MP_ROM_QSTR(MP_QSTR_refresh),
MP_ROM_PTR(&mod_trezorui_Display_refresh_obj)},
{MP_ROM_QSTR(MP_QSTR_bar), MP_ROM_PTR(&mod_trezorui_Display_bar_obj)},
{MP_ROM_QSTR(MP_QSTR_bar_radius),
MP_ROM_PTR(&mod_trezorui_Display_bar_radius_obj)},
{MP_ROM_QSTR(MP_QSTR_image), MP_ROM_PTR(&mod_trezorui_Display_image_obj)},
{MP_ROM_QSTR(MP_QSTR_avatar), MP_ROM_PTR(&mod_trezorui_Display_avatar_obj)},
{MP_ROM_QSTR(MP_QSTR_icon), MP_ROM_PTR(&mod_trezorui_Display_icon_obj)},
{MP_ROM_QSTR(MP_QSTR_loader), MP_ROM_PTR(&mod_trezorui_Display_loader_obj)},
{MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mod_trezorui_Display_print_obj)},
{MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&mod_trezorui_Display_text_obj)},
{MP_ROM_QSTR(MP_QSTR_text_center),
MP_ROM_PTR(&mod_trezorui_Display_text_center_obj)},
{MP_ROM_QSTR(MP_QSTR_text_right),
MP_ROM_PTR(&mod_trezorui_Display_text_right_obj)},
{MP_ROM_QSTR(MP_QSTR_text_width),
MP_ROM_PTR(&mod_trezorui_Display_text_width_obj)},
{MP_ROM_QSTR(MP_QSTR_qrcode), MP_ROM_PTR(&mod_trezorui_Display_qrcode_obj)},
{MP_ROM_QSTR(MP_QSTR_orientation),
MP_ROM_PTR(&mod_trezorui_Display_orientation_obj)},
{MP_ROM_QSTR(MP_QSTR_backlight),
MP_ROM_PTR(&mod_trezorui_Display_backlight_obj)},
{MP_ROM_QSTR(MP_QSTR_offset), MP_ROM_PTR(&mod_trezorui_Display_offset_obj)},
{MP_ROM_QSTR(MP_QSTR_save), MP_ROM_PTR(&mod_trezorui_Display_save_obj)},
{MP_ROM_QSTR(MP_QSTR_WIDTH), MP_OBJ_NEW_SMALL_INT(DISPLAY_RESX)},
{MP_ROM_QSTR(MP_QSTR_HEIGHT), MP_OBJ_NEW_SMALL_INT(DISPLAY_RESY)},
{MP_ROM_QSTR(MP_QSTR_FONT_SIZE), MP_OBJ_NEW_SMALL_INT(FONT_SIZE)},
{MP_ROM_QSTR(MP_QSTR_FONT_NORMAL), MP_OBJ_NEW_SMALL_INT(FONT_NORMAL)},
{MP_ROM_QSTR(MP_QSTR_FONT_BOLD), MP_OBJ_NEW_SMALL_INT(FONT_BOLD)},
{MP_ROM_QSTR(MP_QSTR_FONT_MONO), MP_OBJ_NEW_SMALL_INT(FONT_MONO)},
{MP_ROM_QSTR(MP_QSTR_FONT_MONO_BOLD), MP_OBJ_NEW_SMALL_INT(FONT_MONO_BOLD)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorui_Display_locals_dict, mod_trezorui_Display_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorui_Display_locals_dict,
mod_trezorui_Display_locals_dict_table);
STATIC const mp_obj_type_t mod_trezorui_Display_type = {
{ &mp_type_type },
{&mp_type_type},
.name = MP_QSTR_Display,
.make_new = mod_trezorui_Display_make_new,
.locals_dict = (void*)&mod_trezorui_Display_locals_dict,
.locals_dict = (void *)&mod_trezorui_Display_locals_dict,
};

@ -17,9 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "py/runtime.h"
@ -28,14 +28,15 @@
#include "modtrezorui-display.h"
STATIC const mp_rom_map_elem_t mp_module_trezorui_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorui) },
{ MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&mod_trezorui_Display_type) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorui)},
{MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&mod_trezorui_Display_type)},
};
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorui_globals, mp_module_trezorui_globals_table);
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorui_globals,
mp_module_trezorui_globals_table);
const mp_obj_module_t mp_module_trezorui = {
.base = { &mp_type_module },
.base = {&mp_type_module},
.globals = (mp_obj_dict_t*)&mp_module_trezorui_globals,
};

@ -54,7 +54,8 @@ STATIC mp_obj_t mod_trezorutils_consteq(mp_obj_t sec, mp_obj_t pub) {
return mp_const_false;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorutils_consteq_obj, mod_trezorutils_consteq);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorutils_consteq_obj,
mod_trezorutils_consteq);
/// def memcpy(dst: bytearray, dst_ofs: int,
/// src: bytearray, src_ofs: int,
@ -81,11 +82,12 @@ STATIC mp_obj_t mod_trezorutils_memcpy(size_t n_args, const mp_obj_t *args) {
size_t src_rem = (src_ofs < src.len) ? src.len - src_ofs : 0;
size_t ncpy = MIN(n, MIN(src_rem, dst_rem));
memmove(((char*)dst.buf) + dst_ofs, ((const char*)src.buf) + src_ofs, ncpy);
memmove(((char *)dst.buf) + dst_ofs, ((const char *)src.buf) + src_ofs, ncpy);
return mp_obj_new_int(ncpy);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_memcpy_obj, 5, 5, mod_trezorutils_memcpy);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_memcpy_obj, 5, 5,
mod_trezorutils_memcpy);
/// def halt(msg: str = None) -> None:
/// '''
@ -100,7 +102,8 @@ STATIC mp_obj_t mod_trezorutils_halt(size_t n_args, const mp_obj_t *args) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1, mod_trezorutils_halt);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1,
mod_trezorutils_halt);
/// def set_mode_unprivileged() -> None:
/// '''
@ -108,40 +111,43 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorutils_halt_obj, 0, 1, mod_t
/// '''
STATIC mp_obj_t mod_trezorutils_set_mode_unprivileged(void) {
#ifndef TREZOR_EMULATOR
__asm__ volatile("msr control, %0" :: "r" (0x1));
__asm__ volatile("msr control, %0" ::"r"(0x1));
__asm__ volatile("isb");
#endif
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_set_mode_unprivileged_obj, mod_trezorutils_set_mode_unprivileged);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_set_mode_unprivileged_obj,
mod_trezorutils_set_mode_unprivileged);
#define PASTER(s) MP_QSTR_ ## s
#define PASTER(s) MP_QSTR_##s
#define MP_QSTR(s) PASTER(s)
STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorutils) },
{ MP_ROM_QSTR(MP_QSTR_consteq), MP_ROM_PTR(&mod_trezorutils_consteq_obj) },
{ MP_ROM_QSTR(MP_QSTR_memcpy), MP_ROM_PTR(&mod_trezorutils_memcpy_obj) },
{ MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&mod_trezorutils_halt_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_mode_unprivileged), MP_ROM_PTR(&mod_trezorutils_set_mode_unprivileged_obj) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorutils)},
{MP_ROM_QSTR(MP_QSTR_consteq), MP_ROM_PTR(&mod_trezorutils_consteq_obj)},
{MP_ROM_QSTR(MP_QSTR_memcpy), MP_ROM_PTR(&mod_trezorutils_memcpy_obj)},
{MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&mod_trezorutils_halt_obj)},
{MP_ROM_QSTR(MP_QSTR_set_mode_unprivileged),
MP_ROM_PTR(&mod_trezorutils_set_mode_unprivileged_obj)},
// various built-in constants
{ MP_ROM_QSTR(MP_QSTR_GITREV), MP_ROM_QSTR(MP_QSTR(GITREV)) },
{ MP_ROM_QSTR(MP_QSTR_VERSION_MAJOR), MP_OBJ_NEW_SMALL_INT(VERSION_MAJOR) },
{ MP_ROM_QSTR(MP_QSTR_VERSION_MINOR), MP_OBJ_NEW_SMALL_INT(VERSION_MINOR) },
{ MP_ROM_QSTR(MP_QSTR_VERSION_PATCH), MP_OBJ_NEW_SMALL_INT(VERSION_PATCH) },
{ MP_ROM_QSTR(MP_QSTR_MODEL), MP_ROM_QSTR(MP_QSTR(TREZOR_MODEL)) },
{MP_ROM_QSTR(MP_QSTR_GITREV), MP_ROM_QSTR(MP_QSTR(GITREV))},
{MP_ROM_QSTR(MP_QSTR_VERSION_MAJOR), MP_OBJ_NEW_SMALL_INT(VERSION_MAJOR)},
{MP_ROM_QSTR(MP_QSTR_VERSION_MINOR), MP_OBJ_NEW_SMALL_INT(VERSION_MINOR)},
{MP_ROM_QSTR(MP_QSTR_VERSION_PATCH), MP_OBJ_NEW_SMALL_INT(VERSION_PATCH)},
{MP_ROM_QSTR(MP_QSTR_MODEL), MP_ROM_QSTR(MP_QSTR(TREZOR_MODEL))},
#ifdef TREZOR_EMULATOR
{ MP_ROM_QSTR(MP_QSTR_EMULATOR), mp_const_true },
{MP_ROM_QSTR(MP_QSTR_EMULATOR), mp_const_true},
#else
{ MP_ROM_QSTR(MP_QSTR_EMULATOR), mp_const_false },
{MP_ROM_QSTR(MP_QSTR_EMULATOR), mp_const_false},
#endif
};
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorutils_globals, mp_module_trezorutils_globals_table);
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorutils_globals,
mp_module_trezorutils_globals_table);
const mp_obj_module_t mp_module_trezorutils = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_trezorutils_globals,
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mp_module_trezorutils_globals,
};
#endif // MICROPY_PY_TREZORUTILS

@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "py/runtime.h"
#include "py/objint.h"
#include "py/runtime.h"
#ifndef __TREZOROBJ_H__
#define __TREZOROBJ_H__
@ -33,16 +33,15 @@ static inline mp_int_t trezor_obj_get_int(mp_obj_t obj) {
if (MP_OBJ_IS_SMALL_INT(obj)) {
mp_int_t i = MP_OBJ_SMALL_INT_VALUE(obj);
return i;
}
else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) {
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) {
mp_int_t i = 0;
mp_obj_int_t *self = MP_OBJ_TO_PTR(obj);
if (!mpz_as_int_checked(&self->mpz, &i)) {
mp_raise_msg(&mp_type_OverflowError, "value does not fit into signed int type");
mp_raise_msg(&mp_type_OverflowError,
"value does not fit into signed int type");
}
return i;
}
else {
} else {
mp_raise_TypeError("value is not int");
}
}
@ -55,16 +54,15 @@ static inline mp_uint_t trezor_obj_get_uint(mp_obj_t obj) {
mp_int_t i = MP_OBJ_SMALL_INT_VALUE(obj);
mp_uint_t u = i;
return u;
}
else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) {
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_int)) {
mp_uint_t u = 0;
mp_obj_int_t *self = MP_OBJ_TO_PTR(obj);
if (!mpz_as_uint_checked(&self->mpz, &u)) {
mp_raise_msg(&mp_type_OverflowError, "value does not fit into unsigned int type");
mp_raise_msg(&mp_type_OverflowError,
"value does not fit into unsigned int type");
}
return u;
}
else {
} else {
mp_raise_TypeError("value is not int");
}
}

@ -19,9 +19,9 @@
#include <stdint.h>
#include <string.h>
#include "blake2s.h"
#include "common.h"
#include "flash.h"
#include "blake2s.h"
// symbols from bootloader.bin => bootloader.o
extern const uint32_t _binary_embed_firmware_bootloader_bin_start;
@ -31,32 +31,52 @@ extern const uint32_t _binary_embed_firmware_bootloader_bin_size;
static secbool known_bootloader(const uint8_t *hash, int len) {
if (len != 32) return secfalse;
// bootloader-2.0.1.bin (padded with 0x00)
if (0 == memcmp(hash, "\x91\x37\x46\xd0\x2d\xa7\xc4\xbe\x1d\xae\xef\xb0\x9b\x4e\x31\x88\xed\x38\x23\x5e\x0e\x31\xa7\x8c\x01\xde\x4e\xcc\xc2\xd6\x36\xb3", 32)) return sectrue;
if (0 == memcmp(hash,
"\x91\x37\x46\xd0\x2d\xa7\xc4\xbe\x1d\xae\xef\xb0\x9b\x4e\x31\x88\xed\x38\x23\x5e\x0e\x31\xa7\x8c\x01\xde\x4e\xcc\xc2\xd6\x36\xb3",
32)) return sectrue;
// bootloader-2.0.1.bin (padded with 0xff)
if (0 == memcmp(hash, "\x2f\xdb\xde\x94\x0a\xd8\x91\x1c\xbd\x07\xb0\xba\x06\x2c\x90\x84\x02\xec\x95\x19\xde\x52\x8d\x4b\xe9\xb9\xed\x30\x71\x91\xb4\xd3", 32)) return sectrue;
if (0 == memcmp(hash,
"\x2f\xdb\xde\x94\x0a\xd8\x91\x1c\xbd\x07\xb0\xba\x06\x2c\x90\x84\x02\xec\x95\x19\xde\x52\x8d\x4b\xe9\xb9\xed\x30\x71\x91\xb4\xd3",
32)) return sectrue;
// bootloader-2.0.2.bin (padded with 0x00)
if (0 == memcmp(hash, "\x2e\xf7\x47\xf8\x49\x87\x1e\xc8\xc6\x01\x35\xd6\x32\xe5\x5a\xd1\x56\x18\xf8\x64\x87\xb7\xaa\x7c\x62\x0e\xc3\x0d\x25\x69\x4e\x18", 32)) return sectrue;
if (0 == memcmp(hash,
"\x2e\xf7\x47\xf8\x49\x87\x1e\xc8\xc6\x01\x35\xd6\x32\xe5\x5a\xd1\x56\x18\xf8\x64\x87\xb7\xaa\x7c\x62\x0e\xc3\x0d\x25\x69\x4e\x18",
32)) return sectrue;
// bootloader-2.0.2.bin (padded with 0xff)
if (0 == memcmp(hash, "\xcc\x6b\x35\xc3\x8f\x29\x5c\xbd\x7d\x31\x69\xaf\xae\xf1\x61\x01\xef\xbe\x9f\x3b\x0a\xfd\xc5\x91\x70\x9b\xf5\xa0\xd5\xa4\xc5\xe0", 32)) return sectrue;
if (0 == memcmp(hash,
"\xcc\x6b\x35\xc3\x8f\x29\x5c\xbd\x7d\x31\x69\xaf\xae\xf1\x61\x01\xef\xbe\x9f\x3b\x0a\xfd\xc5\x91\x70\x9b\xf5\xa0\xd5\xa4\xc5\xe0",
32)) return sectrue;
// bootloader-2.0.3.bin (padded with 0x00)
if (0 == memcmp(hash, "\xb1\x83\xd3\x31\xc7\xff\x3d\xcf\x54\x1e\x7e\x40\xf4\x9e\xc3\x53\x4c\xcc\xf3\x8c\x35\x39\x88\x81\x65\xc0\x5c\x25\xbd\xfc\xea\x14", 32)) return sectrue;
if (0 == memcmp(hash,
"\xb1\x83\xd3\x31\xc7\xff\x3d\xcf\x54\x1e\x7e\x40\xf4\x9e\xc3\x53\x4c\xcc\xf3\x8c\x35\x39\x88\x81\x65\xc0\x5c\x25\xbd\xfc\xea\x14",
32)) return sectrue;
// bootloader-2.0.3.bin (padded with 0xff)
if (0 == memcmp(hash, "\xab\xdb\x7d\xe2\xef\x44\x66\xa7\xb7\x1f\x2b\x02\xf3\xe1\x40\xe7\xcd\xf2\x8e\xc0\xbb\x33\x04\xce\x0d\xa5\xca\x02\x57\xb6\xd4\x30", 32)) return sectrue;
return secfalse;
if (0 == memcmp(hash,
"\xab\xdb\x7d\xe2\xef\x44\x66\xa7\xb7\x1f\x2b\x02\xf3\xe1\x40\xe7\xcd\xf2\x8e\xc0\xbb\x33\x04\xce\x0d\xa5\xca\x02\x57\xb6\xd4\x30",
32)) return sectrue; return secfalse;
}
*/
static secbool latest_bootloader(const uint8_t *hash, int len) {
if (len != 32) return secfalse;
// bootloader.bin (padded with 0x00)
if (0 == memcmp(hash, "\xb1\x83\xd3\x31\xc7\xff\x3d\xcf\x54\x1e\x7e\x40\xf4\x9e\xc3\x53\x4c\xcc\xf3\x8c\x35\x39\x88\x81\x65\xc0\x5c\x25\xbd\xfc\xea\x14", 32)) return sectrue;
if (0 ==
memcmp(hash,
"\xb1\x83\xd3\x31\xc7\xff\x3d\xcf\x54\x1e\x7e\x40\xf4\x9e\xc3\x53"
"\x4c\xcc\xf3\x8c\x35\x39\x88\x81\x65\xc0\x5c\x25\xbd\xfc\xea\x14",
32))
return sectrue;
// bootloader.bin (padded with 0xff)
if (0 == memcmp(hash, "\xab\xdb\x7d\xe2\xef\x44\x66\xa7\xb7\x1f\x2b\x02\xf3\xe1\x40\xe7\xcd\xf2\x8e\xc0\xbb\x33\x04\xce\x0d\xa5\xca\x02\x57\xb6\xd4\x30", 32)) return sectrue;
if (0 ==
memcmp(hash,
"\xab\xdb\x7d\xe2\xef\x44\x66\xa7\xb7\x1f\x2b\x02\xf3\xe1\x40\xe7"
"\xcd\xf2\x8e\xc0\xbb\x33\x04\xce\x0d\xa5\xca\x02\x57\xb6\xd4\x30",
32))
return sectrue;
return secfalse;
}
void check_and_replace_bootloader(void)
{
void check_and_replace_bootloader(void) {
// compute current bootloader hash
uint8_t hash[BLAKE2S_DIGEST_LENGTH];
const uint32_t bl_len = 128 * 1024;
@ -64,7 +84,8 @@ void check_and_replace_bootloader(void)
blake2s(bl_data, bl_len, hash, BLAKE2S_DIGEST_LENGTH);
// don't whitelist the valid bootloaders for now
// ensure(known_bootloader(hash, BLAKE2S_DIGEST_LENGTH), "Unknown bootloader detected");
// ensure(known_bootloader(hash, BLAKE2S_DIGEST_LENGTH), "Unknown bootloader
// detected");
// do we have the latest bootloader?
if (sectrue == latest_bootloader(hash, BLAKE2S_DIGEST_LENGTH)) {
@ -72,15 +93,21 @@ void check_and_replace_bootloader(void)
}
// replace bootloader with the latest one
const uint32_t *data = (const uint32_t *)&_binary_embed_firmware_bootloader_bin_start;
const uint32_t len = (const uint32_t)&_binary_embed_firmware_bootloader_bin_size;
const uint32_t *data =
(const uint32_t *)&_binary_embed_firmware_bootloader_bin_start;
const uint32_t len =
(const uint32_t)&_binary_embed_firmware_bootloader_bin_size;
ensure(flash_erase(FLASH_SECTOR_BOOTLOADER), NULL);
ensure(flash_unlock_write(), NULL);
for (int i = 0; i < len / sizeof(uint32_t); i++) {
ensure(flash_write_word(FLASH_SECTOR_BOOTLOADER, i * sizeof(uint32_t), data[i]), NULL);
ensure(flash_write_word(FLASH_SECTOR_BOOTLOADER, i * sizeof(uint32_t),
data[i]),
NULL);
}
for (int i = len / sizeof(uint32_t); i < 128 * 1024 / sizeof(uint32_t); i++) {
ensure(flash_write_word(FLASH_SECTOR_BOOTLOADER, i * sizeof(uint32_t), 0x00000000), NULL);
ensure(flash_write_word(FLASH_SECTOR_BOOTLOADER, i * sizeof(uint32_t),
0x00000000),
NULL);
}
ensure(flash_lock_write(), NULL);
}

@ -21,18 +21,19 @@
#include <stdio.h>
#include <string.h>
#include "py/nlr.h"
#include "lib/utils/pyexec.h"
#include "py/compile.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/repl.h"
#include "py/gc.h"
#include "py/mperrno.h"
#include "lib/utils/pyexec.h"
#include "py/nlr.h"
#include "py/repl.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "ports/stm32/gccollect.h"
#include "ports/stm32/pendsv.h"
#include "bl_check.h"
#include "common.h"
#include "display.h"
#include "flash.h"
@ -40,10 +41,8 @@
#include "rng.h"
#include "sdcard.h"
#include "touch.h"
#include "bl_check.h"
int main(void)
{
int main(void) {
// reinitialize HAL for Trezor One
#if TREZOR_MODEL == 1
HAL_Init();
@ -77,7 +76,7 @@ int main(void)
// Stack limit should be less than real stack size, so we have a chance
// to recover from limit hit.
mp_stack_set_top(&_estack);
mp_stack_set_limit((char*)&_estack - (char*)&_heap_end - 1024);
mp_stack_set_limit((char *)&_estack - (char *)&_heap_end - 1024);
// GC init
printf("CORE: Starting GC\n");
@ -88,7 +87,9 @@ int main(void)
mp_init();
mp_obj_list_init(mp_sys_argv, 0);
mp_obj_list_init(mp_sys_path, 0);
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
mp_obj_list_append(
mp_sys_path,
MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
// Execute the main script
printf("CORE: Executing main script\n");
@ -107,9 +108,7 @@ void __attribute__((noreturn)) nlr_jump_fail(void *val) {
ensure(secfalse, "uncaught exception");
}
void PendSV_Handler(void) {
pendsv_isr_handler();
}
void PendSV_Handler(void) { pendsv_isr_handler(); }
// MicroPython builtin stubs

@ -27,21 +27,21 @@
#include "extmod/utime_mphal.h"
STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) },
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime)},
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj) },
{ MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) },
{ MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj)},
{MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj)},
{MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj)},
{MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj)},
{MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj)},
{MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj)},
{MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj)},
{MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj)},
};
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
const mp_obj_module_t mp_module_utime = {
.base = { &mp_type_module },
.base = {&mp_type_module},
.globals = (mp_obj_dict_t*)&time_module_globals,
};

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

@ -17,9 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common.h"
#include "py/mphal.h"
#include "usb.h"
#include "common.h"
static int vcp_iface_num = -1;
@ -38,6 +38,4 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
}
}
void mp_hal_set_vcp_iface(int iface_num) {
vcp_iface_num = iface_num;
}
void mp_hal_set_vcp_iface(int iface_num) { vcp_iface_num = iface_num; }

@ -19,8 +19,6 @@
#include "lib/utils/interrupt_char.h"
static inline mp_uint_t mp_hal_ticks_cpu(void) {
return 0;
}
static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; }
void mp_hal_set_vcp_iface(int iface_num);

@ -1,3 +1,5 @@
// clang-format off
/*
* This file is part of the TREZOR project, https://trezor.io/
*

@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include STM32_HAL_H
@ -38,28 +38,24 @@
enum { VCP_IFACE = 0x00 };
static void vcp_intr(void)
{
static void vcp_intr(void) {
display_clear();
ensure(secfalse, "vcp_intr");
}
static void vcp_puts(const char *s, size_t len)
{
int r = usb_vcp_write_blocking(VCP_IFACE, (const uint8_t *) s, len, -1);
static void vcp_puts(const char *s, size_t len) {
int r = usb_vcp_write_blocking(VCP_IFACE, (const uint8_t *)s, len, -1);
(void)r;
}
static char vcp_getchar(void)
{
static char vcp_getchar(void) {
uint8_t c = 0;
int r = usb_vcp_read_blocking(VCP_IFACE, &c, 1, -1);
(void)r;
return (char)c;
}
static void vcp_readline(char *buf, size_t len)
{
static void vcp_readline(char *buf, size_t len) {
for (;;) {
char c = vcp_getchar();
if (c == '\r') {
@ -81,8 +77,7 @@ static void vcp_readline(char *buf, size_t len)
}
}
static void vcp_printf(const char *fmt, ...)
{
static void vcp_printf(const char *fmt, ...) {
static char buf[128];
va_list va;
va_start(va, fmt);
@ -92,8 +87,7 @@ static void vcp_printf(const char *fmt, ...)
vcp_puts("\r\n", 2);
}
static void usb_init_all(void)
{
static void usb_init_all(void) {
enum {
VCP_PACKET_LEN = 64,
VCP_BUFFER_LEN = 1024,
@ -142,8 +136,7 @@ static void usb_init_all(void)
usb_start();
}
static void draw_border(int width, int padding)
{
static void draw_border(int width, int padding) {
const int W = width, P = padding, RX = DISPLAY_RESX, RY = DISPLAY_RESY;
display_clear();
display_bar(P, P, RX - 2 * P, RY - 2 * P, 0xFFFF);
@ -151,14 +144,12 @@ static void draw_border(int width, int padding)
display_refresh();
}
static void test_border(void)
{
static void test_border(void) {
draw_border(2, 0);
vcp_printf("OK");
}
static void test_display(const char *colors)
{
static void test_display(const char *colors) {
display_clear();
size_t l = strlen(colors);
@ -167,10 +158,18 @@ static void test_display(const char *colors)
for (size_t i = 0; i < l; i++) {
uint16_t c = 0x0000; // black
switch (colors[i]) {
case 'R': c = 0xF800; break;
case 'G': c = 0x07E0; break;
case 'B': c = 0x001F; break;
case 'W': c = 0xFFFF; break;
case 'R':
c = 0xF800;
break;
case 'G':
c = 0x07E0;
break;
case 'B':
c = 0x001F;
break;
case 'W':
c = 0xFFFF;
break;
}
display_bar(i * w, 0, i * w + w, 240, c);
}
@ -178,35 +177,43 @@ static void test_display(const char *colors)
vcp_printf("OK");
}
static secbool touch_click_timeout(uint32_t *touch, uint32_t timeout_ms)
{
static secbool touch_click_timeout(uint32_t *touch, uint32_t timeout_ms) {
uint32_t deadline = HAL_GetTick() + timeout_ms;
uint32_t r = 0;
while (touch_read());
while (touch_read())
;
while ((touch_read() & TOUCH_START) == 0) {
if (HAL_GetTick() > deadline) return secfalse;
}
while (((r = touch_read()) & TOUCH_END) == 0) {
if (HAL_GetTick() > deadline) return secfalse;
}
while (touch_read());
while (touch_read())
;
*touch = r;
return sectrue;
}
static void test_touch(const char *args)
{
static void test_touch(const char *args) {
int column = args[0] - '0';
int timeout = args[1] - '0';
display_clear();
switch (column) {
case 1: display_bar(0, 0, 120, 120, 0xFFFF); break;
case 2: display_bar(120, 0, 120, 120, 0xFFFF); break;
case 3: display_bar(120, 120, 120, 120, 0xFFFF); break;
default: display_bar(0, 120, 120, 120, 0xFFFF); break;
case 1:
display_bar(0, 0, 120, 120, 0xFFFF);
break;
case 2:
display_bar(120, 0, 120, 120, 0xFFFF);
break;
case 3:
display_bar(120, 120, 120, 120, 0xFFFF);
break;
default:
display_bar(0, 120, 120, 120, 0xFFFF);
break;
}
display_refresh();
@ -226,8 +233,7 @@ static void test_touch(const char *args)
touch_power_off();
}
static void test_sensitivity(const char *args)
{
static void test_sensitivity(const char *args) {
int v = atoi(args);
touch_power_on();
@ -253,8 +259,7 @@ static void test_sensitivity(const char *args)
touch_power_off();
}
static void test_pwm(const char *args)
{
static void test_pwm(const char *args) {
int v = atoi(args);
display_backlight(v);
@ -262,8 +267,7 @@ static void test_pwm(const char *args)
vcp_printf("OK");
}
static void test_sd(void)
{
static void test_sd(void) {
#define BLOCK_SIZE (32 * 1024)
static uint32_t buf1[BLOCK_SIZE / sizeof(uint32_t)];
static uint32_t buf2[BLOCK_SIZE / sizeof(uint32_t)];
@ -282,12 +286,14 @@ static void test_sd(void)
for (int i = 0; i < BLOCK_SIZE / sizeof(uint32_t); i++) {
buf1[i] ^= 0xFFFFFFFF;
}
if (sectrue != sdcard_write_blocks(buf1, 0, BLOCK_SIZE / SDCARD_BLOCK_SIZE)) {
if (sectrue !=
sdcard_write_blocks(buf1, 0, BLOCK_SIZE / SDCARD_BLOCK_SIZE)) {
vcp_printf("ERROR sdcard_write_blocks (%d)", j);
goto power_off;
}
HAL_Delay(1000);
if (sectrue != sdcard_read_blocks(buf2, 0, BLOCK_SIZE / SDCARD_BLOCK_SIZE)) {
if (sectrue !=
sdcard_read_blocks(buf2, 0, BLOCK_SIZE / SDCARD_BLOCK_SIZE)) {
vcp_printf("ERROR sdcard_read_blocks (%d)", j);
goto power_off;
}
@ -302,30 +308,30 @@ power_off:
sdcard_power_off();
}
static void test_wipe(void)
{
static void test_wipe(void) {
// erase start of the firmware (metadata) -> invalidate FW
ensure(flash_unlock_write(), NULL);
for (int i = 0; i < 1024 / sizeof(uint32_t); i++) {
ensure(flash_write_word(FLASH_SECTOR_FIRMWARE_START, i * sizeof(uint32_t), 0x00000000), NULL);
ensure(flash_write_word(FLASH_SECTOR_FIRMWARE_START, i * sizeof(uint32_t),
0x00000000),
NULL);
}
ensure(flash_lock_write(), NULL);
display_clear();
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2 + 10, "WIPED", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2 + 10, "WIPED", -1,
FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
display_refresh();
vcp_printf("OK");
}
static void test_sbu(const char *args)
{
static void test_sbu(const char *args) {
secbool sbu1 = sectrue * (args[0] == '1');
secbool sbu2 = sectrue * (args[1] == '1');
sbu_set(sbu1, sbu2);
vcp_printf("OK");
}
static void test_otp_read(void)
{
static void test_otp_read(void) {
uint8_t data[32];
memzero(data, sizeof(data));
ensure(flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, data, sizeof(data)), NULL);
@ -342,29 +348,28 @@ static void test_otp_read(void)
if (data[0] == 0x00) {
vcp_printf("OK (null)");
} else {
vcp_printf("OK %s", (const char *) data);
vcp_printf("OK %s", (const char *)data);
}
}
static void test_otp_write(const char *args)
{
static void test_otp_write(const char *args) {
char data[32];
memzero(data, sizeof(data));
strncpy(data, args, sizeof(data) - 1);
ensure(flash_otp_write(FLASH_OTP_BLOCK_BATCH, 0, (const uint8_t *) data, sizeof(data)), NULL);
ensure(flash_otp_write(FLASH_OTP_BLOCK_BATCH, 0, (const uint8_t *)data,
sizeof(data)),
NULL);
ensure(flash_otp_lock(FLASH_OTP_BLOCK_BATCH), NULL);
vcp_printf("OK");
}
static secbool startswith(const char *s, const char *prefix)
{
static secbool startswith(const char *s, const char *prefix) {
return sectrue * (0 == strncmp(s, prefix, strlen(prefix)));
}
#define BACKLIGHT_NORMAL 150
int main(void)
{
int main(void) {
display_orientation(0);
sdcard_init();
touch_init();
@ -376,9 +381,11 @@ int main(void)
char dom[32];
// format: TREZOR2-YYMMDD
if (sectrue == flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, (uint8_t *)dom, 32) && 0 == memcmp(dom, "TREZOR2-", 8) && dom[31] == 0) {
if (sectrue == flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, (uint8_t *)dom, 32) &&
0 == memcmp(dom, "TREZOR2-", 8) && dom[31] == 0) {
display_qrcode(DISPLAY_RESX / 2, DISPLAY_RESY / 2, dom, strlen(dom), 4);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 30, dom + 8, -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 30, dom + 8, -1,
FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
}
display_fade(0, BACKLIGHT_NORMAL, 1000);

@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include STM32_HAL_H
@ -33,37 +33,32 @@
#include "secbool.h"
#include "touch.h"
static void progress_callback(int pos, int len)
{
display_printf(".");
}
static void progress_callback(int pos, int len) { display_printf("."); }
static void flash_from_sdcard(uint8_t sector, uint32_t source, uint32_t length)
{
static void flash_from_sdcard(uint8_t sector, uint32_t source,
uint32_t length) {
static uint32_t buf[SDCARD_BLOCK_SIZE / sizeof(uint32_t)];
ensure(
sectrue * (source % SDCARD_BLOCK_SIZE == 0),
ensure(sectrue * (source % SDCARD_BLOCK_SIZE == 0),
"source not a multiple of block size");
ensure(
sectrue * (length % SDCARD_BLOCK_SIZE == 0),
ensure(sectrue * (length % SDCARD_BLOCK_SIZE == 0),
"length not a multiple of block size");
for (uint32_t i = 0; i < length / SDCARD_BLOCK_SIZE; i++) {
display_printf("read %d\n", (unsigned int)(i + source / SDCARD_BLOCK_SIZE));
ensure(
sdcard_read_blocks(buf, i + source / SDCARD_BLOCK_SIZE, 1),
ensure(sdcard_read_blocks(buf, i + source / SDCARD_BLOCK_SIZE, 1),
"sdcard_read_blocks");
for (uint32_t j = 0; j < SDCARD_BLOCK_SIZE / sizeof(uint32_t); j++) {
ensure(flash_write_word(sector, i * SDCARD_BLOCK_SIZE + j * sizeof(uint32_t), buf[j]), NULL);
ensure(flash_write_word(
sector, i * SDCARD_BLOCK_SIZE + j * sizeof(uint32_t), buf[j]),
NULL);
}
}
}
int main(void)
{
int main(void) {
sdcard_init();
touch_init();
@ -71,9 +66,7 @@ int main(void)
display_clear();
display_backlight(255);
ensure(
sdcard_is_present(),
"sdcard_is_present");
ensure(sdcard_is_present(), "sdcard_is_present");
display_printf("updating boardloader + bootloader\n");
@ -84,7 +77,8 @@ int main(void)
FLASH_SECTOR_BOOTLOADER,
};
display_printf("erasing sectors");
ensure(flash_erase_sectors(sectors, sizeof(sectors), progress_callback), "flash_erase_sectors");
ensure(flash_erase_sectors(sectors, sizeof(sectors), progress_callback),
"flash_erase_sectors");
display_printf("\n");
display_printf("erased\n");
@ -96,10 +90,13 @@ int main(void)
#define BOARDLOADER_TOTAL_SIZE (3 * BOARDLOADER_CHUNK_SIZE)
#define BOOTLOADER_TOTAL_SIZE (128 * 1024)
flash_from_sdcard(FLASH_SECTOR_BOARDLOADER_START, 0 * BOARDLOADER_CHUNK_SIZE, BOARDLOADER_CHUNK_SIZE);
flash_from_sdcard(FLASH_SECTOR_BOARDLOADER_START, 0 * BOARDLOADER_CHUNK_SIZE,
BOARDLOADER_CHUNK_SIZE);
flash_from_sdcard(1, 1 * BOARDLOADER_CHUNK_SIZE, BOARDLOADER_CHUNK_SIZE);
flash_from_sdcard(FLASH_SECTOR_BOARDLOADER_END, 2 * BOARDLOADER_CHUNK_SIZE, BOARDLOADER_CHUNK_SIZE);
flash_from_sdcard(FLASH_SECTOR_BOOTLOADER, BOARDLOADER_TOTAL_SIZE, BOOTLOADER_TOTAL_SIZE);
flash_from_sdcard(FLASH_SECTOR_BOARDLOADER_END, 2 * BOARDLOADER_CHUNK_SIZE,
BOARDLOADER_CHUNK_SIZE);
flash_from_sdcard(FLASH_SECTOR_BOOTLOADER, BOARDLOADER_TOTAL_SIZE,
BOOTLOADER_TOTAL_SIZE);
display_printf("done\n");
sdcard_power_off();

@ -23,9 +23,9 @@
#include "common.h"
#include "display.h"
#include "rng.h"
#include "rand.h"
#include "flash.h"
#include "rand.h"
#include "rng.h"
#include "stm32f4xx_ll_utils.h"
@ -34,7 +34,9 @@ extern void shutdown(void);
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func) {
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func) {
display_orientation(0);
display_backlight(255);
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
@ -56,11 +58,13 @@ void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg,
#endif
display_printf("\nPlease contact TREZOR support.\n");
shutdown();
for (;;);
for (;;)
;
}
void __attribute__((noreturn)) error_shutdown(const char *line1, const char *line2, const char *line3, const char *line4)
{
void __attribute__((noreturn))
error_shutdown(const char *line1, const char *line2, const char *line3,
const char *line4) {
display_orientation(0);
#ifdef TREZOR_FONT_NORMAL_ENABLE
display_clear();
@ -83,7 +87,8 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin
y += 32;
}
y += 32;
display_text(8, y, "Please unplug the device.", -1, FONT_NORMAL, COLOR_WHITE, COLOR_FATAL_ERROR);
display_text(8, y, "Please unplug the device.", -1, FONT_NORMAL, COLOR_WHITE,
COLOR_FATAL_ERROR);
#else
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
if (line1) {
@ -102,22 +107,20 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin
#endif
display_backlight(255);
shutdown();
for (;;);
for (;;)
;
}
#ifndef NDEBUG
void __assert_func(const char *file, int line, const char *func, const char *expr) {
void __assert_func(const char *file, int line, const char *func,
const char *expr) {
__fatal_error(expr, "assert failed", file, line, func);
}
#endif
void hal_delay(uint32_t ms)
{
HAL_Delay(ms);
}
void hal_delay(uint32_t ms) { HAL_Delay(ms); }
void delay_random(void)
{
void delay_random(void) {
int wait = rng_get() & 0xff;
volatile int i = 0;
volatile int j = wait;
@ -138,25 +141,28 @@ void delay_random(void)
#define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U)
#define USB_OTG_HS_DATA_FIFO_SIZE (4096U)
void clear_otg_hs_memory(void)
{
void clear_otg_hs_memory(void) {
// use the HAL version due to section 2.1.6 of STM32F42xx Errata sheet
__HAL_RCC_USB_OTG_HS_CLK_ENABLE(); // enable USB_OTG_HS peripheral clock so that the peripheral memory is accessible
memset_reg((volatile void *) USB_OTG_HS_DATA_FIFO_RAM, (volatile void *) (USB_OTG_HS_DATA_FIFO_RAM + USB_OTG_HS_DATA_FIFO_SIZE), 0);
__HAL_RCC_USB_OTG_HS_CLK_DISABLE(); // disable USB OTG_HS peripheral clock as the peripheral is not needed right now
__HAL_RCC_USB_OTG_HS_CLK_ENABLE(); // enable USB_OTG_HS peripheral clock so
// that the peripheral memory is
// accessible
memset_reg(
(volatile void *)USB_OTG_HS_DATA_FIFO_RAM,
(volatile void *)(USB_OTG_HS_DATA_FIFO_RAM + USB_OTG_HS_DATA_FIFO_SIZE),
0);
__HAL_RCC_USB_OTG_HS_CLK_DISABLE(); // disable USB OTG_HS peripheral clock as
// the peripheral is not needed right now
}
uint32_t __stack_chk_guard = 0;
void __attribute__((noreturn)) __stack_chk_fail(void)
{
void __attribute__((noreturn)) __stack_chk_fail(void) {
ensure(secfalse, "Stack smashing detected");
}
uint8_t HW_ENTROPY_DATA[HW_ENTROPY_LEN];
void collect_hw_entropy(void)
{
void collect_hw_entropy(void) {
// collect entropy from UUID
uint32_t w = LL_GetUID_Word0();
memcpy(HW_ENTROPY_DATA, &w, 4);
@ -169,9 +175,13 @@ void collect_hw_entropy(void)
if (secfalse == flash_otp_is_locked(FLASH_OTP_BLOCK_RANDOMNESS)) {
uint8_t entropy[FLASH_OTP_BLOCK_SIZE];
random_buffer(entropy, FLASH_OTP_BLOCK_SIZE);
ensure(flash_otp_write(FLASH_OTP_BLOCK_RANDOMNESS, 0, entropy, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_write(FLASH_OTP_BLOCK_RANDOMNESS, 0, entropy,
FLASH_OTP_BLOCK_SIZE),
NULL);
ensure(flash_otp_lock(FLASH_OTP_BLOCK_RANDOMNESS), NULL);
}
// collect entropy from OTP randomness block
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, HW_ENTROPY_DATA + 12, FLASH_OTP_BLOCK_SIZE), NULL);
ensure(flash_otp_read(FLASH_OTP_BLOCK_RANDOMNESS, 0, HW_ENTROPY_DATA + 12,
FLASH_OTP_BLOCK_SIZE),
NULL);
}

@ -27,19 +27,41 @@
#define STR(s) #s
#ifndef MIN_8bits
#define MIN_8bits(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? (_a & 0xFF) : (_b & 0xFF); })
#define MIN_8bits(a, b) \
({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a < _b ? (_a & 0xFF) : (_b & 0xFF); \
})
#endif
#ifndef MIN
#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
#define MIN(a, b) \
({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a < _b ? _a : _b; \
})
#endif
#ifndef MAX
#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
#define MAX(a, b) \
({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})
#endif
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
void __attribute__((noreturn)) error_shutdown(const char *line1, const char *line2, const char *line3, const char *line4);
void __attribute__((noreturn))
__fatal_error(const char *expr, const char *msg, const char *file, int line,
const char *func);
void __attribute__((noreturn))
error_shutdown(const char *line1, const char *line2, const char *line3,
const char *line4);
#define ensure(expr, msg) (((expr) == sectrue) ? (void)0 : __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
#define ensure(expr, msg) \
(((expr) == sectrue) \
? (void)0 \
: __fatal_error(#expr, msg, __FILE__, __LINE__, __func__))
void hal_delay(uint32_t ms);

@ -27,16 +27,16 @@
// see docs/memory.md for more information
static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = {
[ 0] = 0x08000000, // - 0x08003FFF | 16 KiB
[ 1] = 0x08004000, // - 0x08007FFF | 16 KiB
[ 2] = 0x08008000, // - 0x0800BFFF | 16 KiB
[ 3] = 0x0800C000, // - 0x0800FFFF | 16 KiB
[ 4] = 0x08010000, // - 0x0801FFFF | 64 KiB
[ 5] = 0x08020000, // - 0x0803FFFF | 128 KiB
[ 6] = 0x08040000, // - 0x0805FFFF | 128 KiB
[ 7] = 0x08060000, // - 0x0807FFFF | 128 KiB
[ 8] = 0x08080000, // - 0x0809FFFF | 128 KiB
[ 9] = 0x080A0000, // - 0x080BFFFF | 128 KiB
[0] = 0x08000000, // - 0x08003FFF | 16 KiB
[1] = 0x08004000, // - 0x08007FFF | 16 KiB
[2] = 0x08008000, // - 0x0800BFFF | 16 KiB
[3] = 0x0800C000, // - 0x0800FFFF | 16 KiB
[4] = 0x08010000, // - 0x0801FFFF | 64 KiB
[5] = 0x08020000, // - 0x0803FFFF | 128 KiB
[6] = 0x08040000, // - 0x0805FFFF | 128 KiB
[7] = 0x08060000, // - 0x0807FFFF | 128 KiB
[8] = 0x08080000, // - 0x0809FFFF | 128 KiB
[9] = 0x080A0000, // - 0x080BFFFF | 128 KiB
[10] = 0x080C0000, // - 0x080DFFFF | 128 KiB
[11] = 0x080E0000, // - 0x080FFFFF | 128 KiB
[12] = 0x08100000, // - 0x08103FFF | 16 KiB
@ -54,7 +54,7 @@ static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = {
[24] = 0x08200000, // last element - not a valid sector
};
const uint8_t FIRMWARE_SECTORS [FIRMWARE_SECTORS_COUNT] = {
const uint8_t FIRMWARE_SECTORS[FIRMWARE_SECTORS_COUNT] = {
FLASH_SECTOR_FIRMWARE_START,
7,
8,
@ -75,25 +75,20 @@ const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT] = {
FLASH_SECTOR_STORAGE_2,
};
void flash_init(void)
{
}
void flash_init(void) {}
secbool flash_unlock_write(void)
{
secbool flash_unlock_write(void) {
HAL_FLASH_Unlock();
FLASH->SR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
return sectrue;
}
secbool flash_lock_write(void)
{
secbool flash_lock_write(void) {
HAL_FLASH_Lock();
return sectrue;
}
const void *flash_get_address(uint8_t sector, uint32_t offset, uint32_t size)
{
const void *flash_get_address(uint8_t sector, uint32_t offset, uint32_t size) {
if (sector >= FLASH_SECTOR_COUNT) {
return NULL;
}
@ -105,8 +100,8 @@ const void *flash_get_address(uint8_t sector, uint32_t offset, uint32_t size)
return (const void *)addr;
}
secbool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int pos, int len))
{
secbool flash_erase_sectors(const uint8_t *sectors, int len,
void (*progress)(int pos, int len)) {
ensure(flash_unlock_write(), NULL);
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
@ -123,7 +118,8 @@ secbool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(in
return secfalse;
}
// check whether the sector was really deleted (contains only 0xFF)
const uint32_t addr_start = FLASH_SECTOR_TABLE[sectors[i]], addr_end = FLASH_SECTOR_TABLE[sectors[i] + 1];
const uint32_t addr_start = FLASH_SECTOR_TABLE[sectors[i]],
addr_end = FLASH_SECTOR_TABLE[sectors[i] + 1];
for (uint32_t addr = addr_start; addr < addr_end; addr += 4) {
if (*((const uint32_t *)addr) != 0xFFFFFFFF) {
ensure(flash_lock_write(), NULL);
@ -138,8 +134,7 @@ secbool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(in
return sectrue;
}
secbool flash_write_byte(uint8_t sector, uint32_t offset, uint8_t data)
{
secbool flash_write_byte(uint8_t sector, uint32_t offset, uint8_t data) {
uint32_t address = (uint32_t)flash_get_address(sector, offset, 1);
if (address == 0) {
return secfalse;
@ -156,8 +151,7 @@ secbool flash_write_byte(uint8_t sector, uint32_t offset, uint8_t data)
return sectrue;
}
secbool flash_write_word(uint8_t sector, uint32_t offset, uint32_t data)
{
secbool flash_write_word(uint8_t sector, uint32_t offset, uint32_t data) {
uint32_t address = (uint32_t)flash_get_address(sector, offset, 4);
if (address == 0) {
return secfalse;
@ -179,43 +173,48 @@ secbool flash_write_word(uint8_t sector, uint32_t offset, uint32_t data)
#define FLASH_OTP_LOCK_BASE 0x1FFF7A00U
secbool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data, uint8_t datalen)
{
if (block >= FLASH_OTP_NUM_BLOCKS || offset + datalen > FLASH_OTP_BLOCK_SIZE) {
secbool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data,
uint8_t datalen) {
if (block >= FLASH_OTP_NUM_BLOCKS ||
offset + datalen > FLASH_OTP_BLOCK_SIZE) {
return secfalse;
}
for (uint8_t i = 0; i < datalen; i++) {
data[i] = *(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE + offset + i);
data[i] = *(__IO uint8_t *)(FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE +
offset + i);
}
return sectrue;
}
secbool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data, uint8_t datalen)
{
if (block >= FLASH_OTP_NUM_BLOCKS || offset + datalen > FLASH_OTP_BLOCK_SIZE) {
secbool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data,
uint8_t datalen) {
if (block >= FLASH_OTP_NUM_BLOCKS ||
offset + datalen > FLASH_OTP_BLOCK_SIZE) {
return secfalse;
}
ensure(flash_unlock_write(), NULL);
for (uint8_t i = 0; i < datalen; i++) {
uint32_t address = FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE + offset + i;
ensure(sectrue * (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, data[i])), NULL);
uint32_t address =
FLASH_OTP_BASE + block * FLASH_OTP_BLOCK_SIZE + offset + i;
ensure(sectrue * (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
address, data[i])),
NULL);
}
ensure(flash_lock_write(), NULL);
return sectrue;
}
secbool flash_otp_lock(uint8_t block)
{
secbool flash_otp_lock(uint8_t block) {
if (block >= FLASH_OTP_NUM_BLOCKS) {
return secfalse;
}
ensure(flash_unlock_write(), NULL);
HAL_StatusTypeDef ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, FLASH_OTP_LOCK_BASE + block, 0x00);
HAL_StatusTypeDef ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE,
FLASH_OTP_LOCK_BASE + block, 0x00);
ensure(flash_lock_write(), NULL);
return sectrue * (ret == HAL_OK);
}
secbool flash_otp_is_locked(uint8_t block)
{
secbool flash_otp_is_locked(uint8_t block) {
return sectrue * (0x00 == *(__IO uint8_t *)(FLASH_OTP_LOCK_BASE + block));
}

@ -67,12 +67,15 @@
extern const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT];
extern const uint8_t FIRMWARE_SECTORS[FIRMWARE_SECTORS_COUNT];
// note: FLASH_SR_RDERR is STM32F42xxx and STM32F43xxx specific (STM32F427) (reference RM0090 section 3.7.5)
// note: FLASH_SR_RDERR is STM32F42xxx and STM32F43xxx specific (STM32F427)
// (reference RM0090 section 3.7.5)
#ifndef STM32F427xx
#define FLASH_SR_RDERR 0
#endif
#define FLASH_STATUS_ALL_FLAGS (FLASH_SR_RDERR | FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR | FLASH_SR_WRPERR | FLASH_SR_SOP | FLASH_SR_EOP)
#define FLASH_STATUS_ALL_FLAGS \
(FLASH_SR_RDERR | FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR | \
FLASH_SR_WRPERR | FLASH_SR_SOP | FLASH_SR_EOP)
void flash_init(void);
@ -81,8 +84,11 @@ secbool __wur flash_lock_write(void);
const void *flash_get_address(uint8_t sector, uint32_t offset, uint32_t size);
secbool __wur flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int pos, int len));
static inline secbool flash_erase(uint8_t sector) { return flash_erase_sectors(&sector, 1, NULL); }
secbool __wur flash_erase_sectors(const uint8_t *sectors, int len,
void (*progress)(int pos, int len));
static inline secbool flash_erase(uint8_t sector) {
return flash_erase_sectors(&sector, 1, NULL);
}
secbool __wur flash_write_byte(uint8_t sector, uint32_t offset, uint8_t data);
secbool __wur flash_write_word(uint8_t sector, uint32_t offset, uint32_t data);
@ -95,8 +101,10 @@ secbool __wur flash_write_word(uint8_t sector, uint32_t offset, uint32_t data);
#define FLASH_OTP_BLOCK_VENDOR_KEYS_LOCK 2
#define FLASH_OTP_BLOCK_RANDOMNESS 3
secbool __wur flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data, uint8_t datalen);
secbool __wur flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data, uint8_t datalen);
secbool __wur flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data,
uint8_t datalen);
secbool __wur flash_otp_write(uint8_t block, uint8_t offset,
const uint8_t *data, uint8_t datalen);
secbool __wur flash_otp_lock(uint8_t block);
secbool __wur flash_otp_is_locked(uint8_t block);

@ -26,8 +26,9 @@
#include "flash.h"
#include "image.h"
static secbool compute_pubkey(uint8_t sig_m, uint8_t sig_n, const uint8_t * const *pub, uint8_t sigmask, ed25519_public_key res)
{
static secbool compute_pubkey(uint8_t sig_m, uint8_t sig_n,
const uint8_t *const *pub, uint8_t sigmask,
ed25519_public_key res) {
if (0 == sig_m || 0 == sig_n) return secfalse;
if (sig_m > sig_n) return secfalse;
@ -49,8 +50,9 @@ static secbool compute_pubkey(uint8_t sig_m, uint8_t sig_n, const uint8_t * cons
return sectrue * (0 == ed25519_cosi_combine_publickeys(res, keys, sig_m));
}
secbool load_image_header(const uint8_t * const data, const uint32_t magic, const uint32_t maxsize, uint8_t key_m, uint8_t key_n, const uint8_t * const *keys, image_header * const hdr)
{
secbool load_image_header(const uint8_t *const data, const uint32_t magic,
const uint32_t maxsize, uint8_t key_m, uint8_t key_n,
const uint8_t *const *keys, image_header *const hdr) {
memcpy(&hdr->magic, data, 4);
if (hdr->magic != magic) return secfalse;
@ -59,7 +61,8 @@ secbool load_image_header(const uint8_t * const data, const uint32_t magic, cons
memcpy(&hdr->expiry, data + 8, 4);
// TODO: expiry mechanism needs to be ironed out before production or those
// devices won't accept expiring bootloaders (due to boardloader write protection).
// devices won't accept expiring bootloaders (due to boardloader write
// protection).
if (hdr->expiry != 0) return secfalse;
memcpy(&hdr->codelen, data + 12, 4);
@ -74,7 +77,8 @@ secbool load_image_header(const uint8_t * const data, const uint32_t magic, cons
memcpy(&hdr->sigmask, data + IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE, 1);
memcpy(hdr->sig, data + IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE + 1, IMAGE_SIG_SIZE - 1);
memcpy(hdr->sig, data + IMAGE_HEADER_SIZE - IMAGE_SIG_SIZE + 1,
IMAGE_SIG_SIZE - 1);
// check header signature
@ -87,13 +91,17 @@ secbool load_image_header(const uint8_t * const data, const uint32_t magic, cons
blake2s_Final(&ctx, hdr->fingerprint, BLAKE2S_DIGEST_LENGTH);
ed25519_public_key pub;
if (sectrue != compute_pubkey(key_m, key_n, keys, hdr->sigmask, pub)) return secfalse;
if (sectrue != compute_pubkey(key_m, key_n, keys, hdr->sigmask, pub))
return secfalse;
return sectrue * (0 == ed25519_sign_open(hdr->fingerprint, BLAKE2S_DIGEST_LENGTH, pub, *(const ed25519_signature *)hdr->sig));
return sectrue *
(0 == ed25519_sign_open(hdr->fingerprint, BLAKE2S_DIGEST_LENGTH, pub,
*(const ed25519_signature *)hdr->sig));
}
secbool load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t key_n, const uint8_t * const *keys, vendor_header * const vhdr)
{
secbool load_vendor_header(const uint8_t *const data, uint8_t key_m,
uint8_t key_n, const uint8_t *const *keys,
vendor_header *const vhdr) {
memcpy(&vhdr->magic, data, 4);
if (vhdr->magic != 0x565A5254) return secfalse; // TRZV
@ -130,7 +138,8 @@ secbool load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t ke
memcpy(&vhdr->sigmask, data + vhdr->hdrlen - IMAGE_SIG_SIZE, 1);
memcpy(vhdr->sig, data + vhdr->hdrlen - IMAGE_SIG_SIZE + 1, IMAGE_SIG_SIZE - 1);
memcpy(vhdr->sig, data + vhdr->hdrlen - IMAGE_SIG_SIZE + 1,
IMAGE_SIG_SIZE - 1);
// check header signature
@ -144,13 +153,15 @@ secbool load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t ke
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
ed25519_public_key pub;
if (sectrue != compute_pubkey(key_m, key_n, keys, vhdr->sigmask, pub)) return secfalse;
if (sectrue != compute_pubkey(key_m, key_n, keys, vhdr->sigmask, pub))
return secfalse;
return sectrue * (0 == ed25519_sign_open(hash, BLAKE2S_DIGEST_LENGTH, pub, *(const ed25519_signature *)vhdr->sig));
return sectrue *
(0 == ed25519_sign_open(hash, BLAKE2S_DIGEST_LENGTH, pub,
*(const ed25519_signature *)vhdr->sig));
}
void vendor_keys_hash(const vendor_header * const vhdr, uint8_t *hash)
{
void vendor_keys_hash(const vendor_header *const vhdr, uint8_t *hash) {
BLAKE2S_CTX ctx;
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
blake2s_Update(&ctx, &(vhdr->vsig_m), sizeof(vhdr->vsig_m));
@ -159,30 +170,37 @@ void vendor_keys_hash(const vendor_header * const vhdr, uint8_t *hash)
if (vhdr->vpub[i] != 0) {
blake2s_Update(&ctx, vhdr->vpub[i], 32);
} else {
blake2s_Update(&ctx, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32);
blake2s_Update(
&ctx,
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
32);
}
}
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
}
secbool check_single_hash(const uint8_t * const hash, const uint8_t * const data, int len)
{
secbool check_single_hash(const uint8_t *const hash, const uint8_t *const data,
int len) {
uint8_t h[BLAKE2S_DIGEST_LENGTH];
blake2s(data, len, h, BLAKE2S_DIGEST_LENGTH);
return sectrue * (0 == memcmp(h, hash, BLAKE2S_DIGEST_LENGTH));
}
secbool check_image_contents(const image_header * const hdr, uint32_t firstskip, const uint8_t *sectors, int blocks)
{
secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
const uint8_t *sectors, int blocks) {
if (0 == sectors || blocks < 1) {
return secfalse;
}
const void *data = flash_get_address(sectors[0], firstskip, IMAGE_CHUNK_SIZE - firstskip);
const void *data =
flash_get_address(sectors[0], firstskip, IMAGE_CHUNK_SIZE - firstskip);
if (!data) {
return secfalse;
}
int remaining = hdr->codelen;
if (sectrue != check_single_hash(hdr->hashes, data, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) {
if (sectrue !=
check_single_hash(hdr->hashes, data,
MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) {
return secfalse;
}
int block = 1;
@ -195,7 +213,8 @@ secbool check_image_contents(const image_header * const hdr, uint32_t firstskip,
if (!data) {
return secfalse;
}
if (sectrue != check_single_hash(hdr->hashes + block * 32, data, MIN(remaining, IMAGE_CHUNK_SIZE))) {
if (sectrue != check_single_hash(hdr->hashes + block * 32, data,
MIN(remaining, IMAGE_CHUNK_SIZE))) {
return secfalse;
}
block++;

@ -77,14 +77,22 @@ typedef struct {
uint8_t sig[64];
} vendor_header;
secbool __wur load_image_header(const uint8_t * const data, const uint32_t magic, const uint32_t maxsize, uint8_t key_m, uint8_t key_n, const uint8_t * const *keys, image_header * const hdr);
secbool __wur load_image_header(const uint8_t *const data, const uint32_t magic,
const uint32_t maxsize, uint8_t key_m,
uint8_t key_n, const uint8_t *const *keys,
image_header *const hdr);
secbool __wur load_vendor_header(const uint8_t * const data, uint8_t key_m, uint8_t key_n, const uint8_t * const *keys, vendor_header * const vhdr);
secbool __wur load_vendor_header(const uint8_t *const data, uint8_t key_m,
uint8_t key_n, const uint8_t *const *keys,
vendor_header *const vhdr);
void vendor_keys_hash(const vendor_header * const vhdr, uint8_t *hash);
void vendor_keys_hash(const vendor_header *const vhdr, uint8_t *hash);
secbool __wur check_single_hash(const uint8_t * const hash, const uint8_t * const data, int len);
secbool __wur check_single_hash(const uint8_t *const hash,
const uint8_t *const data, int len);
secbool __wur check_image_contents(const image_header * const hdr, uint32_t firstskip, const uint8_t *sectors, int blocks);
secbool __wur check_image_contents(const image_header *const hdr,
uint32_t firstskip, const uint8_t *sectors,
int blocks);
#endif

@ -19,74 +19,84 @@
#include STM32_HAL_H
#include "flash.h"
#include "lowlevel.h"
#include "flash.h"
#pragma GCC optimize("no-stack-protector") // applies to all functions in this file
#pragma GCC optimize( \
"no-stack-protector") // applies to all functions in this file
#if PRODUCTION
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_2)
#define WANT_WRP_SECTORS (OB_WRP_SECTOR_0 | OB_WRP_SECTOR_1 | OB_WRP_SECTOR_2)
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_2)
#define WANT_WRP_SECTORS (OB_WRP_SECTOR_0 | OB_WRP_SECTOR_1 | OB_WRP_SECTOR_2)
#else
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_0)
#define WANT_WRP_SECTORS (0)
#define WANT_RDP_LEVEL (OB_RDP_LEVEL_0)
#define WANT_WRP_SECTORS (0)
#endif
// BOR LEVEL 3: Reset level threshold is around 2.5 V
#define WANT_BOR_LEVEL (OB_BOR_LEVEL3)
// reference RM0090 section 3.9.10; SPRMOD is 0 meaning PCROP disabled.; DB1M is 0 because we use 2MB dual-bank; BFB2 is 0 allowing boot from flash;
#define FLASH_OPTCR_VALUE ( (((~WANT_WRP_SECTORS) << FLASH_OPTCR_nWRP_Pos) & FLASH_OPTCR_nWRP_Msk) | \
(WANT_RDP_LEVEL << FLASH_OPTCR_RDP_Pos) | FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_nRST_STOP | FLASH_OPTCR_WDG_SW | WANT_BOR_LEVEL )
// reference RM0090 section 3.9.10; SPRMOD is 0 meaning PCROP disabled.; DB1M is
// 0 because we use 2MB dual-bank; BFB2 is 0 allowing boot from flash;
#define FLASH_OPTCR_VALUE \
((((~WANT_WRP_SECTORS) << FLASH_OPTCR_nWRP_Pos) & FLASH_OPTCR_nWRP_Msk) | \
(WANT_RDP_LEVEL << FLASH_OPTCR_RDP_Pos) | FLASH_OPTCR_nRST_STDBY | \
FLASH_OPTCR_nRST_STOP | FLASH_OPTCR_WDG_SW | WANT_BOR_LEVEL)
// reference RM0090 section 3.7.1 table 16
#define OPTION_BYTES_RDP_USER_VALUE ((uint16_t) ((WANT_RDP_LEVEL << FLASH_OPTCR_RDP_Pos) | FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_nRST_STOP | FLASH_OPTCR_WDG_SW | WANT_BOR_LEVEL))
#define OPTION_BYTES_BANK1_WRP_VALUE ((uint16_t) ((~WANT_WRP_SECTORS) & 0xFFFU))
#define OPTION_BYTES_BANK2_WRP_VALUE ((uint16_t) 0xFFFU)
// reference RM0090 section 3.7.1 table 16. use 16 bit pointers because the top 48 bits are all reserved.
#define OPTION_BYTES_RDP_USER (*(volatile uint16_t * const) 0x1FFFC000U)
#define OPTION_BYTES_BANK1_WRP (*(volatile uint16_t * const) 0x1FFFC008U)
#define OPTION_BYTES_BANK2_WRP (*(volatile uint16_t * const) 0x1FFEC008U)
uint32_t flash_wait_and_clear_status_flags(void)
{
while(FLASH->SR & FLASH_SR_BSY); // wait for all previous flash operations to complete
const uint32_t result = FLASH->SR & FLASH_STATUS_ALL_FLAGS; // get the current status flags
#define OPTION_BYTES_RDP_USER_VALUE \
((uint16_t)((WANT_RDP_LEVEL << FLASH_OPTCR_RDP_Pos) | \
FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_nRST_STOP | \
FLASH_OPTCR_WDG_SW | WANT_BOR_LEVEL))
#define OPTION_BYTES_BANK1_WRP_VALUE ((uint16_t)((~WANT_WRP_SECTORS) & 0xFFFU))
#define OPTION_BYTES_BANK2_WRP_VALUE ((uint16_t)0xFFFU)
// reference RM0090 section 3.7.1 table 16. use 16 bit pointers because the top
// 48 bits are all reserved.
#define OPTION_BYTES_RDP_USER (*(volatile uint16_t* const)0x1FFFC000U)
#define OPTION_BYTES_BANK1_WRP (*(volatile uint16_t* const)0x1FFFC008U)
#define OPTION_BYTES_BANK2_WRP (*(volatile uint16_t* const)0x1FFEC008U)
uint32_t flash_wait_and_clear_status_flags(void) {
while (FLASH->SR & FLASH_SR_BSY)
; // wait for all previous flash operations to complete
const uint32_t result =
FLASH->SR & FLASH_STATUS_ALL_FLAGS; // get the current status flags
FLASH->SR |= FLASH_STATUS_ALL_FLAGS; // clear all status flags
return result;
}
secbool flash_check_option_bytes(void)
{
secbool flash_check_option_bytes(void) {
flash_wait_and_clear_status_flags();
// check values stored in flash interface registers
if ((FLASH->OPTCR & ~3) != FLASH_OPTCR_VALUE) { // ignore bits 0 and 1 because they are control bits
if ((FLASH->OPTCR & ~3) !=
FLASH_OPTCR_VALUE) { // ignore bits 0 and 1 because they are control bits
return secfalse;
}
if (FLASH->OPTCR1 != FLASH_OPTCR1_nWRP) {
return secfalse;
}
// check values stored in flash memory
if ((OPTION_BYTES_RDP_USER & ~3) != OPTION_BYTES_RDP_USER_VALUE) { // bits 0 and 1 are unused
if ((OPTION_BYTES_RDP_USER & ~3) !=
OPTION_BYTES_RDP_USER_VALUE) { // bits 0 and 1 are unused
return secfalse;
}
if ((OPTION_BYTES_BANK1_WRP & 0xCFFFU) != OPTION_BYTES_BANK1_WRP_VALUE) { // bits 12 and 13 are unused
if ((OPTION_BYTES_BANK1_WRP & 0xCFFFU) !=
OPTION_BYTES_BANK1_WRP_VALUE) { // bits 12 and 13 are unused
return secfalse;
}
if ((OPTION_BYTES_BANK2_WRP & 0xFFFU) != OPTION_BYTES_BANK2_WRP_VALUE) { // bits 12, 13, 14, and 15 are unused
if ((OPTION_BYTES_BANK2_WRP & 0xFFFU) !=
OPTION_BYTES_BANK2_WRP_VALUE) { // bits 12, 13, 14, and 15 are unused
return secfalse;
}
return sectrue;
}
void flash_lock_option_bytes(void)
{
void flash_lock_option_bytes(void) {
FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; // lock the option bytes
}
void flash_unlock_option_bytes(void)
{
void flash_unlock_option_bytes(void) {
if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) == 0) {
return; // already unlocked
}
@ -94,38 +104,40 @@ void flash_unlock_option_bytes(void)
// write the special sequence to unlock
FLASH->OPTKEYR = FLASH_OPT_KEY1;
FLASH->OPTKEYR = FLASH_OPT_KEY2;
while (FLASH->OPTCR & FLASH_OPTCR_OPTLOCK); // wait until the flash option control register is unlocked
while (FLASH->OPTCR & FLASH_OPTCR_OPTLOCK)
; // wait until the flash option control register is unlocked
}
uint32_t flash_set_option_bytes(void)
{
uint32_t flash_set_option_bytes(void) {
// reference RM0090 section 3.7.2
flash_wait_and_clear_status_flags();
flash_unlock_option_bytes();
flash_wait_and_clear_status_flags();
FLASH->OPTCR1 = FLASH_OPTCR1_nWRP; // no write protection on any sectors in bank 2
FLASH->OPTCR = FLASH_OPTCR_VALUE; // WARNING: dev board safe unless you compile for PRODUCTION or change this value!!!
FLASH->OPTCR1 =
FLASH_OPTCR1_nWRP; // no write protection on any sectors in bank 2
FLASH->OPTCR =
FLASH_OPTCR_VALUE; // WARNING: dev board safe unless you compile for
// PRODUCTION or change this value!!!
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT; // begin committing changes to flash
const uint32_t result = flash_wait_and_clear_status_flags(); // wait until changes are committed
const uint32_t result =
flash_wait_and_clear_status_flags(); // wait until changes are committed
flash_lock_option_bytes();
return result;
}
secbool flash_configure_option_bytes(void)
{
secbool flash_configure_option_bytes(void) {
if (sectrue == flash_check_option_bytes()) {
return sectrue; // we DID NOT have to change the option bytes
}
do {
flash_set_option_bytes();
} while(sectrue != flash_check_option_bytes());
} while (sectrue != flash_check_option_bytes());
return secfalse; // notify that we DID have to change the option bytes
}
void periph_init(void)
{
void periph_init(void) {
// STM32F4xx HAL library initialization:
// - configure the Flash prefetch, instruction and data caches
// - configure the Systick to generate an interrupt each 1 msec
@ -152,13 +164,15 @@ void periph_init(void)
NVIC_EnableIRQ(PVD_IRQn);
}
secbool reset_flags_check(void)
{
secbool reset_flags_check(void) {
#if PRODUCTION
// this is effective enough that it makes development painful, so only use it for production.
// check the reset flags to assure that we arrive here due to a regular full power-on event,
// and not as a result of a lesser reset.
if ((RCC->CSR & (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF | RCC_CSR_PINRSTF | RCC_CSR_BORRSTF)) != (RCC_CSR_PORRSTF | RCC_CSR_PINRSTF | RCC_CSR_BORRSTF)) {
// this is effective enough that it makes development painful, so only use it
// for production. check the reset flags to assure that we arrive here due to
// a regular full power-on event, and not as a result of a lesser reset.
if ((RCC->CSR & (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_IWDGRSTF |
RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF | RCC_CSR_PINRSTF |
RCC_CSR_BORRSTF)) !=
(RCC_CSR_PORRSTF | RCC_CSR_PINRSTF | RCC_CSR_BORRSTF)) {
return secfalse;
}
#endif

@ -1,3 +1,5 @@
// clang-format off
/*
* The Minimal snprintf() implementation
*

@ -1,3 +1,5 @@
// clang-format off
/*
* The Minimal snprintf() implementation
*

@ -27,14 +27,12 @@
#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos)
void mpu_config_off(void)
{
void mpu_config_off(void) {
// Disable MPU
HAL_MPU_Disable();
}
void mpu_config_bootloader(void)
{
void mpu_config_bootloader(void) {
// Disable MPU
HAL_MPU_Disable();
@ -43,34 +41,44 @@ void mpu_config_bootloader(void)
// Everything (0x00000000 - 0xFFFFFFFF, 4 GiB, read-write)
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = 0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS;
// Flash (0x0800C000 - 0x0800FFFF, 16 KiB, no access)
MPU->RNR = MPU_REGION_NUMBER1;
MPU->RBAR = FLASH_BASE + 0xC000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
// Flash (0x0810C000 - 0x0810FFFF, 16 KiB, no access)
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = FLASH_BASE + 0x10C000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never)
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end,
// read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER3;
MPU->RBAR = SRAM_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM |
LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
// External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER4;
MPU->RBAR = PERIPH_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH |
LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
#ifdef STM32F427xx
// CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR = CCMDATARAM_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
#elif STM32F405xx
// no CCMRAM
#else
@ -81,60 +89,77 @@ void mpu_config_bootloader(void)
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
void mpu_config_firmware(void)
{
void mpu_config_firmware(void) {
// Disable MPU
HAL_MPU_Disable();
// Note: later entries overwrite previous ones
/*
/*
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
MPU->RBAR = FLASH_BASE | MPU_REGION_NUMBER0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk;
*/
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk;
*/
// Bootloader (0x08020000 - 0x0803FFFF, 64 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER0;
MPU->RBAR = FLASH_BASE + 0x20000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO;
// Storage#1 (0x08010000 - 0x0801FFFF, 64 KiB, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER1;
MPU->RBAR = FLASH_BASE + 0x10000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
// Storage#2 (0x08110000 - 0x0811FFFF, 64 KiB, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER2;
MPU->RBAR = FLASH_BASE + 0x110000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
// Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at start = 768 KiB, read-only)
// Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at
// start = 768 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER3;
MPU->RBAR = FLASH_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x03);
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO |
MPU_SUBREGION_DISABLE(0x03);
// Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8 at start = 896 KiB, read-only)
// Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8
// at start = 896 KiB, read-only)
MPU->RNR = MPU_REGION_NUMBER4;
MPU->RBAR = FLASH_BASE + 0x100000;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x01);
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH |
LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO |
MPU_SUBREGION_DISABLE(0x01);
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never)
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end,
// read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER5;
MPU->RBAR = SRAM_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM |
LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
// External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER6;
MPU->RBAR = PERIPH_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH |
LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
#ifdef STM32F427xx
// CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never)
MPU->RNR = MPU_REGION_NUMBER7;
MPU->RBAR = CCMDATARAM_BASE;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM |
LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS |
MPU_RASR_XN_Msk;
#elif STM32F405xx
// no CCMRAM
#else

@ -21,10 +21,10 @@
#include "rng.h"
#pragma GCC optimize("no-stack-protector") // applies to all functions in this file
#pragma GCC optimize( \
"no-stack-protector") // applies to all functions in this file
void rng_init(void)
{
void rng_init(void) {
// enable TRNG peripheral clock
// use the HAL version due to section 2.1.6 of STM32F42xx Errata sheet
// "Delay after an RCC peripheral clock enabling"
@ -32,19 +32,21 @@ void rng_init(void)
RNG->CR = RNG_CR_RNGEN; // enable TRNG
}
uint32_t rng_read(const uint32_t previous, const uint32_t compare_previous)
{
uint32_t rng_read(const uint32_t previous, const uint32_t compare_previous) {
uint32_t temp = previous;
do {
while ((RNG->SR & (RNG_SR_SECS | RNG_SR_CECS | RNG_SR_DRDY)) != RNG_SR_DRDY); // wait until TRNG is ready
while ((RNG->SR & (RNG_SR_SECS | RNG_SR_CECS | RNG_SR_DRDY)) != RNG_SR_DRDY)
; // wait until TRNG is ready
temp = RNG->DR; // read the data from the TRNG
} while (compare_previous && (temp == previous)); // RM0090 section 24.3.1 FIPS continuous random number generator test
} while (compare_previous &&
(temp == previous)); // RM0090 section 24.3.1 FIPS continuous random
// number generator test
return temp;
}
uint32_t rng_get(void)
{
// reason for keeping history: RM0090 section 24.3.1 FIPS continuous random number generator test
uint32_t rng_get(void) {
// reason for keeping history: RM0090 section 24.3.1 FIPS continuous random
// number generator test
static uint32_t previous = 0, current = 0;
if (previous == current) {
previous = rng_read(previous, 0);

@ -36,6 +36,8 @@ void sbu_init(void) {
}
void sbu_set(secbool sbu1, secbool sbu2) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, sbu1 == sectrue ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, sbu2 == sectrue ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2,
sbu1 == sectrue ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,
sbu2 == sectrue ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

@ -73,7 +73,8 @@ static inline void sdcard_default_pin_state(void) {
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStructure.Pin =
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
@ -97,15 +98,14 @@ static inline void sdcard_active_pin_state(void) {
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStructure.Alternate = GPIO_AF12_SDIO;
GPIO_InitStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStructure.Pin =
GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void sdcard_init(void) {
sdcard_default_pin_state();
}
void sdcard_init(void) { sdcard_default_pin_state(); }
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
// enable SDIO clock
@ -113,9 +113,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
// GPIO have already been initialised by sdcard_init
}
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
__HAL_RCC_SDIO_CLK_DISABLE();
}
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) { __HAL_RCC_SDIO_CLK_DISABLE(); }
secbool sdcard_power_on(void) {
if (sectrue != sdcard_is_present()) {
@ -182,7 +180,8 @@ uint64_t sdcard_get_capacity_in_bytes(void) {
return (uint64_t)cardinfo.LogBlockNbr * (uint64_t)cardinfo.LogBlockSize;
}
static HAL_StatusTypeDef sdcard_wait_finished(SD_HandleTypeDef *sd, uint32_t timeout) {
static HAL_StatusTypeDef sdcard_wait_finished(SD_HandleTypeDef *sd,
uint32_t timeout) {
// Wait for HAL driver to be ready (eg for DMA to finish)
uint32_t start = HAL_GetTick();
while (sd->State == HAL_SD_STATE_BUSY) {
@ -196,7 +195,8 @@ static HAL_StatusTypeDef sdcard_wait_finished(SD_HandleTypeDef *sd, uint32_t tim
if (state == HAL_SD_CARD_TRANSFER) {
return HAL_OK;
}
if (!(state == HAL_SD_CARD_SENDING || state == HAL_SD_CARD_RECEIVING || state == HAL_SD_CARD_PROGRAMMING)) {
if (!(state == HAL_SD_CARD_SENDING || state == HAL_SD_CARD_RECEIVING ||
state == HAL_SD_CARD_PROGRAMMING)) {
return HAL_ERROR;
}
if (HAL_GetTick() - start >= timeout) {
@ -206,7 +206,8 @@ static HAL_StatusTypeDef sdcard_wait_finished(SD_HandleTypeDef *sd, uint32_t tim
return HAL_OK;
}
secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num, uint32_t num_blocks) {
secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num,
uint32_t num_blocks) {
// check that SD card is initialised
if (sd_handle.Instance == NULL) {
return secfalse;
@ -219,7 +220,8 @@ secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num, uint32_t num_bloc
HAL_StatusTypeDef err = HAL_OK;
err = HAL_SD_ReadBlocks(&sd_handle, (uint8_t *)dest, block_num, num_blocks, 60000);
err = HAL_SD_ReadBlocks(&sd_handle, (uint8_t *)dest, block_num, num_blocks,
60000);
if (err == HAL_OK) {
err = sdcard_wait_finished(&sd_handle, 60000);
}
@ -227,7 +229,8 @@ secbool sdcard_read_blocks(uint32_t *dest, uint32_t block_num, uint32_t num_bloc
return sectrue * (err == HAL_OK);
}
secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num, uint32_t num_blocks) {
secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num,
uint32_t num_blocks) {
// check that SD card is initialised
if (sd_handle.Instance == NULL) {
return secfalse;
@ -240,7 +243,8 @@ secbool sdcard_write_blocks(const uint32_t *src, uint32_t block_num, uint32_t nu
HAL_StatusTypeDef err = HAL_OK;
err = HAL_SD_WriteBlocks(&sd_handle, (uint8_t *)src, block_num, num_blocks, 60000);
err = HAL_SD_WriteBlocks(&sd_handle, (uint8_t *)src, block_num, num_blocks,
60000);
if (err == HAL_OK) {
err = sdcard_wait_finished(&sd_handle, 60000);
}

@ -56,7 +56,9 @@ secbool __wur sdcard_power_on(void);
void sdcard_power_off(void);
secbool __wur sdcard_is_present(void);
uint64_t sdcard_get_capacity_in_bytes(void);
secbool __wur sdcard_read_blocks(uint32_t *dest, uint32_t block_num, uint32_t num_blocks);
secbool __wur sdcard_write_blocks(const uint32_t *src, uint32_t block_num, uint32_t num_blocks);
secbool __wur sdcard_read_blocks(uint32_t *dest, uint32_t block_num,
uint32_t num_blocks);
secbool __wur sdcard_write_blocks(const uint32_t *src, uint32_t block_num,
uint32_t num_blocks);
#endif

@ -27,7 +27,7 @@ typedef uint32_t secbool;
#define secfalse 0x00000000U
#ifndef __wur
#define __wur __attribute__ ((warn_unused_result))
#define __wur __attribute__((warn_unused_result))
#endif
#endif

@ -21,7 +21,8 @@
#include "rng.h"
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
#ifdef STM32F427xx
@ -34,46 +35,60 @@ const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
uint32_t SystemCoreClock = CORE_CLOCK_MHZ * 1000000U;
#pragma GCC optimize("no-stack-protector") // applies to all functions in this file
#pragma GCC optimize( \
"no-stack-protector") // applies to all functions in this file
void SystemInit(void)
{
// set flash wait states for an increasing HCLK frequency -- reference RM0090 section 3.5.1
void SystemInit(void) {
// set flash wait states for an increasing HCLK frequency -- reference RM0090
// section 3.5.1
FLASH->ACR = FLASH_ACR_LATENCY_5WS;
// wait until the new wait state config takes effect -- per section 3.5.1 guidance
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS);
// configure main PLL; assumes HSE is 8 MHz; this should evaluate to 0x27402a04 -- reference RM0090 section 7.3.2
RCC->PLLCFGR = (RCC_PLLCFGR_RST_VALUE & ~RCC_PLLCFGR_PLLQ & ~RCC_PLLCFGR_PLLSRC & ~RCC_PLLCFGR_PLLP & ~RCC_PLLCFGR_PLLN & ~RCC_PLLCFGR_PLLM)
| (7U << RCC_PLLCFGR_PLLQ_Pos) // Q = 7
// wait until the new wait state config takes effect -- per section 3.5.1
// guidance
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS)
;
// configure main PLL; assumes HSE is 8 MHz; this should evaluate to
// 0x27402a04 -- reference RM0090 section 7.3.2
RCC->PLLCFGR =
(RCC_PLLCFGR_RST_VALUE & ~RCC_PLLCFGR_PLLQ & ~RCC_PLLCFGR_PLLSRC &
~RCC_PLLCFGR_PLLP & ~RCC_PLLCFGR_PLLN & ~RCC_PLLCFGR_PLLM) |
(7U << RCC_PLLCFGR_PLLQ_Pos) // Q = 7
| RCC_PLLCFGR_PLLSRC_HSE // PLLSRC = HSE
| (0U << RCC_PLLCFGR_PLLP_Pos) // P = 2 (two bits, 00 means PLLP = 2)
| (CORE_CLOCK_MHZ << RCC_PLLCFGR_PLLN_Pos) // N = CORE_CLOCK_MHZ
| (4U << RCC_PLLCFGR_PLLM_Pos); // M = 4
// enable spread spectrum clock for main PLL
RCC->SSCGR = RCC_SSCGR_SSCGEN | (44 << RCC_SSCGR_INCSTEP_Pos) | (250 << RCC_SSCGR_MODPER_Pos);
RCC->SSCGR = RCC_SSCGR_SSCGEN | (44 << RCC_SSCGR_INCSTEP_Pos) |
(250 << RCC_SSCGR_MODPER_Pos);
// enable clock security system, HSE clock, and main PLL
RCC->CR |= RCC_CR_CSSON | RCC_CR_HSEON | RCC_CR_PLLON;
// wait until PLL and HSE ready
while((RCC->CR & (RCC_CR_PLLRDY | RCC_CR_HSERDY)) != (RCC_CR_PLLRDY | RCC_CR_HSERDY));
while ((RCC->CR & (RCC_CR_PLLRDY | RCC_CR_HSERDY)) !=
(RCC_CR_PLLRDY | RCC_CR_HSERDY))
;
// APB2=2, APB1=4, AHB=1, system clock = main PLL
const uint32_t cfgr = RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_PLL;
const uint32_t cfgr = RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4 |
RCC_CFGR_HPRE_DIV1 | RCC_CFGR_SW_PLL;
RCC->CFGR = cfgr;
// wait until PLL is system clock and also verify that the pre-scalers were set
while(RCC->CFGR != (RCC_CFGR_SWS_PLL | cfgr));
// turn off the HSI as it is now unused (it will be turned on again automatically if a clock security failure occurs)
// wait until PLL is system clock and also verify that the pre-scalers were
// set
while (RCC->CFGR != (RCC_CFGR_SWS_PLL | cfgr))
;
// turn off the HSI as it is now unused (it will be turned on again
// automatically if a clock security failure occurs)
RCC->CR &= ~RCC_CR_HSION;
// wait until ths HSI is off
while((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION);
while ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
;
// init the TRNG peripheral
rng_init();
// set CP10 and CP11 to enable full access to the fpu coprocessor; ARMv7-M Architecture Reference Manual section B3.2.20
// set CP10 and CP11 to enable full access to the fpu coprocessor; ARMv7-M
// Architecture Reference Manual section B3.2.20
SCB->CPACR |= ((3U << 22) | (3U << 20));
}
extern volatile uint32_t uwTick;
void SysTick_Handler(void)
{
void SysTick_Handler(void) {
// this is a millisecond tick counter that wraps after approximately
// 49.71 days = (0xffffffff / (24 * 60 * 60 * 1000))
uwTick++;
@ -82,8 +97,7 @@ void SysTick_Handler(void)
// from util.s
extern void shutdown(void);
void PVD_IRQHandler(void)
{
void PVD_IRQHandler(void) {
TIM1->CCR1 = 0; // turn off display backlight
shutdown();
}

@ -1,3 +1,5 @@
// clang-format off
/**
******************************************************************************
* @file stm32f4xx_hal_conf.h

@ -1,3 +1,5 @@
// clang-format off
/*
* This file is part of the TREZOR project, https://trezor.io/
*

@ -28,17 +28,20 @@
#error Unknown TREZOR Model
#endif
uint32_t touch_click(void)
{
uint32_t touch_click(void) {
uint32_t r = 0;
// flush touch events if any
while (touch_read()) { }
while (touch_read()) {
}
// wait for TOUCH_START
while ((touch_read() & TOUCH_START) == 0) { }
while ((touch_read() & TOUCH_START) == 0) {
}
// wait for TOUCH_END
while (((r = touch_read()) & TOUCH_END) == 0) { }
while (((r = touch_read()) & TOUCH_END) == 0) {
}
// flush touch events if any
while (touch_read()) { }
while (touch_read()) {
}
// return last touch coordinate
return r;
}

@ -33,8 +33,14 @@ void touch_sensitivity(uint8_t value);
uint32_t touch_read(void);
uint32_t touch_click(void);
uint32_t touch_is_detected(void);
static inline uint16_t touch_unpack_x(uint32_t evt) { return (evt >> 12) & 0xFFF; }
static inline uint16_t touch_unpack_y(uint32_t evt) { return (evt >> 0) & 0xFFF; }
static inline uint32_t touch_pack_xy(uint16_t x, uint16_t y) { return ((x & 0xFFF) << 12) | (y & 0xFFF); }
static inline uint16_t touch_unpack_x(uint32_t evt) {
return (evt >> 12) & 0xFFF;
}
static inline uint16_t touch_unpack_y(uint32_t evt) {
return (evt >> 0) & 0xFFF;
}
static inline uint32_t touch_pack_xy(uint16_t x, uint16_t y) {
return ((x & 0xFFF) << 12) | (y & 0xFFF);
}
#endif

@ -19,14 +19,13 @@ void touch_init(void) {
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void touch_power_on(void) { }
void touch_power_on(void) {}
void touch_power_off(void) { }
void touch_power_off(void) {}
void touch_sensitivity(uint8_t value) { (void)value; }
uint32_t touch_read(void)
{
uint32_t touch_read(void) {
static char last_left = 0, last_right = 0;
char left = (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, BTN_PIN_LEFT));
char right = (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, BTN_PIN_RIGHT));
@ -49,7 +48,7 @@ uint32_t touch_read(void)
return 0;
}
uint32_t touch_is_detected(void)
{
return (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, BTN_PIN_LEFT)) || (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, BTN_PIN_RIGHT));
uint32_t touch_is_detected(void) {
return (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, BTN_PIN_LEFT)) ||
(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, BTN_PIN_RIGHT));
}

@ -3,7 +3,8 @@
#include "common.h"
#include "secbool.h"
#define TOUCH_ADDRESS (0x38U << 1) // the HAL requires the 7-bit address to be shifted by one bit
#define TOUCH_ADDRESS \
(0x38U << 1) // the HAL requires the 7-bit address to be shifted by one bit
#define TOUCH_PACKET_SIZE 7U
#define EVENT_PRESS_DOWN 0x00U
#define EVENT_CONTACT 0x80U
@ -19,11 +20,18 @@ static I2C_HandleTypeDef i2c_handle;
static void touch_default_pin_state(void) {
// set power off and other pins as per section 3.5 of FT6236 datasheet
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); // CTP_ON/PB10 (active low) i.e.- CTPM power off when set/high/log 1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10,
GPIO_PIN_SET); // CTP_ON/PB10 (active low) i.e.- CTPM power
// off when set/high/log 1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // CTP_I2C_SCL/PB6
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET); // CTP_I2C_SDA/PB7
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET); // CTP_INT/PC4 normally an input, but drive low as an output while powered off
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET); // CTP_REST/PC5 (active low) i.e.- CTPM held in reset until released
HAL_GPIO_WritePin(
GPIOC, GPIO_PIN_4,
GPIO_PIN_RESET); // CTP_INT/PC4 normally an input, but drive low as an
// output while powered off
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5,
GPIO_PIN_RESET); // CTP_REST/PC5 (active low) i.e.- CTPM
// held in reset until released
// set above pins to OUTPUT / NOPULL
GPIO_InitTypeDef GPIO_InitStructure;
@ -38,7 +46,8 @@ static void touch_default_pin_state(void) {
// in-case power was on, or CTPM was active make sure to wait long enough
// for these changes to take effect. a reset needs to be low for
// a minimum of 5ms. also wait for power circuitry to stabilize (if it changed).
// a minimum of 5ms. also wait for power circuitry to stabilize (if it
// changed).
HAL_Delay(100); // 100ms (being conservative)
}
@ -51,7 +60,9 @@ static void touch_active_pin_state(void) {
// configure CTP I2C SCL and SDA GPIO lines (PB6 & PB7)
GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; // I2C is a KHz bus and low speed is still good into the low MHz
GPIO_InitStructure.Speed =
GPIO_SPEED_FREQ_LOW; // I2C is a KHz bus and low speed is still good into
// the low MHz
GPIO_InitStructure.Alternate = GPIO_AF4_I2C1;
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
@ -64,12 +75,11 @@ static void touch_active_pin_state(void) {
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET); // release CTPM reset
HAL_Delay(310); // "Time of starting to report point after resetting" min is 300ms, giving an extra 10ms
HAL_Delay(310); // "Time of starting to report point after resetting" min is
// 300ms, giving an extra 10ms
}
void touch_init(void) {
touch_default_pin_state();
}
void touch_init(void) { touch_default_pin_state(); }
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) {
// enable I2C clock
@ -106,9 +116,14 @@ void touch_power_on(void) {
return;
}
// set register 0xA4 G_MODE to interrupt polling mode (0x00). basically, CTPM keeps this input line (to PC4) low while a finger is on the screen.
// set register 0xA4 G_MODE to interrupt polling mode (0x00). basically, CTPM
// keeps this input line (to PC4) low while a finger is on the screen.
uint8_t touch_panel_config[] = {0xA4, 0x00};
ensure(sectrue * (HAL_OK == HAL_I2C_Master_Transmit(&i2c_handle, TOUCH_ADDRESS, touch_panel_config, sizeof(touch_panel_config), 10)), NULL);
ensure(
sectrue * (HAL_OK == HAL_I2C_Master_Transmit(
&i2c_handle, TOUCH_ADDRESS, touch_panel_config,
sizeof(touch_panel_config), 10)),
NULL);
touch_sensitivity(0x06);
}
@ -126,11 +141,14 @@ void touch_power_off(void) {
void touch_sensitivity(uint8_t value) {
// set panel threshold (TH_GROUP) - default value is 0x12
uint8_t touch_panel_threshold[] = {0x80, value};
ensure(sectrue * (HAL_OK == HAL_I2C_Master_Transmit(&i2c_handle, TOUCH_ADDRESS, touch_panel_threshold, sizeof(touch_panel_threshold), 10)), NULL);
ensure(sectrue *
(HAL_OK == HAL_I2C_Master_Transmit(
&i2c_handle, TOUCH_ADDRESS, touch_panel_threshold,
sizeof(touch_panel_threshold), 10)),
NULL);
}
uint32_t touch_is_detected(void)
{
uint32_t touch_is_detected(void) {
// check the interrupt line coming in from the CTPM.
// the line goes low when a touch event is actively detected.
// reference section 1.2 of "Application Note for FT6x06 CTPM".
@ -138,9 +156,9 @@ uint32_t touch_is_detected(void)
return GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);
}
uint32_t touch_read(void)
{
static uint8_t touch_data[TOUCH_PACKET_SIZE], previous_touch_data[TOUCH_PACKET_SIZE];
uint32_t touch_read(void) {
static uint8_t touch_data[TOUCH_PACKET_SIZE],
previous_touch_data[TOUCH_PACKET_SIZE];
static uint32_t xy;
static int touching;
@ -157,11 +175,13 @@ uint32_t touch_read(void)
}
uint8_t outgoing[] = {0x00}; // start reading from address 0x00
if (HAL_OK != HAL_I2C_Master_Transmit(&i2c_handle, TOUCH_ADDRESS, outgoing, sizeof(outgoing), 1)) {
if (HAL_OK != HAL_I2C_Master_Transmit(&i2c_handle, TOUCH_ADDRESS, outgoing,
sizeof(outgoing), 1)) {
return 0;
}
if (HAL_OK != HAL_I2C_Master_Receive(&i2c_handle, TOUCH_ADDRESS, touch_data, TOUCH_PACKET_SIZE, 1)) {
if (HAL_OK != HAL_I2C_Master_Receive(&i2c_handle, TOUCH_ADDRESS, touch_data,
TOUCH_PACKET_SIZE, 1)) {
return 0; // read failure
}
@ -171,10 +191,13 @@ uint32_t touch_read(void)
memcpy(previous_touch_data, touch_data, TOUCH_PACKET_SIZE);
}
const uint32_t number_of_touch_points = touch_data[2] & 0x0F; // valid values are 0, 1, 2 (invalid 0xF before first touch) (tested with FT6206)
const uint32_t number_of_touch_points =
touch_data[2] & 0x0F; // valid values are 0, 1, 2 (invalid 0xF before
// first touch) (tested with FT6206)
const uint32_t event_flag = touch_data[3] & 0xC0;
if (touch_data[1] == GESTURE_NO_GESTURE) {
xy = touch_pack_xy((X_POS_MSB << 8) | X_POS_LSB, (Y_POS_MSB << 8) | Y_POS_LSB);
xy = touch_pack_xy((X_POS_MSB << 8) | X_POS_LSB,
(Y_POS_MSB << 8) | Y_POS_LSB);
if ((number_of_touch_points == 1) && (event_flag == EVENT_PRESS_DOWN)) {
touching = 1;
return TOUCH_START | xy;
@ -187,8 +210,8 @@ uint32_t touch_read(void)
}
if (last_packet) {
// interrupt line is inactive, we didn't read valid touch data, and as far as
// we know, we never sent a TOUCH_END event.
// interrupt line is inactive, we didn't read valid touch data, and as far
// as we know, we never sent a TOUCH_END event.
touching = 0;
return TOUCH_END | xy;
}

@ -19,8 +19,8 @@
#include STM32_HAL_H
#include "common.h"
#include "usb.h"
#include "common.h"
#include "usbd_core.h"
#define USB_MAX_CONFIG_DESC_SIZE 256
@ -35,8 +35,12 @@
#error Unable to determine proper USB_PHY_ID to use
#endif
#define USB_WINUSB_VENDOR_CODE '!' // arbitrary, but must be equivalent to the last character in extra string
#define USB_WINUSB_EXTRA_STRING 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, '1', 0x00, '0', 0x00, '0', 0x00, USB_WINUSB_VENDOR_CODE , 0x00 // MSFT100!
#define USB_WINUSB_VENDOR_CODE \
'!' // arbitrary, but must be equivalent to the last character in extra
// string
#define USB_WINUSB_EXTRA_STRING \
'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, '1', 0x00, '0', 0x00, '0', 0x00, \
USB_WINUSB_VENDOR_CODE, 0x00 // MSFT100!
#define USB_WINUSB_EXTRA_STRING_INDEX 0xEE
#define USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR 0x04
#define USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR 0x05
@ -46,8 +50,10 @@
static usb_device_descriptor_t usb_dev_desc;
// Config descriptor
static uint8_t usb_config_buf[USB_MAX_CONFIG_DESC_SIZE] __attribute__((aligned(4)));
static usb_config_descriptor_t *usb_config_desc = (usb_config_descriptor_t *)(usb_config_buf);
static uint8_t usb_config_buf[USB_MAX_CONFIG_DESC_SIZE]
__attribute__((aligned(4)));
static usb_config_descriptor_t *usb_config_desc =
(usb_config_descriptor_t *)(usb_config_buf);
static usb_interface_descriptor_t *usb_next_iface_desc;
// String descriptor
@ -70,7 +76,6 @@ static secbool __wur check_desc_str(const char *s) {
}
void usb_init(const usb_dev_info_t *dev_info) {
// enable/disable USB 2.1 features
usb21_enabled = dev_info->usb21_enabled;
usb21_landing = dev_info->usb21_landing;
@ -78,7 +83,8 @@ void usb_init(const usb_dev_info_t *dev_info) {
// Device descriptor
usb_dev_desc.bLength = sizeof(usb_device_descriptor_t);
usb_dev_desc.bDescriptorType = USB_DESC_TYPE_DEVICE;
usb_dev_desc.bcdUSB = (sectrue == usb21_enabled) ? 0x0210 : 0x0200; // USB 2.1 or USB 2.0
usb_dev_desc.bcdUSB =
(sectrue == usb21_enabled) ? 0x0210 : 0x0200; // USB 2.1 or USB 2.0
usb_dev_desc.bDeviceClass = dev_info->device_class;
usb_dev_desc.bDeviceSubClass = dev_info->device_subclass;
usb_dev_desc.bDeviceProtocol = dev_info->device_protocol;
@ -86,9 +92,11 @@ void usb_init(const usb_dev_info_t *dev_info) {
usb_dev_desc.idVendor = dev_info->vendor_id;
usb_dev_desc.idProduct = dev_info->product_id;
usb_dev_desc.bcdDevice = dev_info->release_num;
usb_dev_desc.iManufacturer = USBD_IDX_MFC_STR; // Index of manufacturer string
usb_dev_desc.iManufacturer =
USBD_IDX_MFC_STR; // Index of manufacturer string
usb_dev_desc.iProduct = USBD_IDX_PRODUCT_STR; // Index of product string
usb_dev_desc.iSerialNumber = USBD_IDX_SERIAL_STR; // Index of serial number string
usb_dev_desc.iSerialNumber =
USBD_IDX_SERIAL_STR; // Index of serial number string
usb_dev_desc.bNumConfigurations = 1;
// String table
@ -105,18 +113,31 @@ void usb_init(const usb_dev_info_t *dev_info) {
// Configuration descriptor
usb_config_desc->bLength = sizeof(usb_config_descriptor_t);
usb_config_desc->bDescriptorType = USB_DESC_TYPE_CONFIGURATION;
usb_config_desc->wTotalLength = sizeof(usb_config_descriptor_t); // will be updated later via usb_desc_add_iface()
usb_config_desc->bNumInterfaces = 0; // will be updated later via usb_desc_add_iface()
usb_config_desc->wTotalLength =
sizeof(usb_config_descriptor_t); // will be updated later via
// usb_desc_add_iface()
usb_config_desc->bNumInterfaces =
0; // will be updated later via usb_desc_add_iface()
usb_config_desc->bConfigurationValue = 0x01;
usb_config_desc->iConfiguration = 0;
usb_config_desc->bmAttributes = 0x80; // 0x80 = bus powered; 0xC0 = self powered
usb_config_desc->bmAttributes =
0x80; // 0x80 = bus powered; 0xC0 = self powered
usb_config_desc->bMaxPower = 0x32; // Maximum Power Consumption in 2mA units
// Pointer to interface descriptor data
usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength);
ensure(sectrue * (USBD_OK == USBD_Init(&usb_dev_handle, (USBD_DescriptorsTypeDef*)&usb_descriptors, USB_PHY_ID)), NULL);
ensure(sectrue * (USBD_OK == USBD_RegisterClass(&usb_dev_handle, (USBD_ClassTypeDef*)&usb_class)), NULL);
usb_next_iface_desc =
(usb_interface_descriptor_t *)(usb_config_buf +
usb_config_desc->wTotalLength);
ensure(sectrue *
(USBD_OK == USBD_Init(&usb_dev_handle,
(USBD_DescriptorsTypeDef *)&usb_descriptors,
USB_PHY_ID)),
NULL);
ensure(sectrue *
(USBD_OK == USBD_RegisterClass(&usb_dev_handle,
(USBD_ClassTypeDef *)&usb_class)),
NULL);
}
void usb_deinit(void) {
@ -126,13 +147,9 @@ void usb_deinit(void) {
}
}
void usb_start(void) {
USBD_Start(&usb_dev_handle);
}
void usb_start(void) { USBD_Start(&usb_dev_handle); }
void usb_stop(void) {
USBD_Stop(&usb_dev_handle);
}
void usb_stop(void) { USBD_Stop(&usb_dev_handle); }
/*
* Utility functions for USB interfaces
@ -157,7 +174,9 @@ static void *usb_desc_alloc_iface(size_t desc_len) {
static void usb_desc_add_iface(size_t desc_len) {
usb_config_desc->bNumInterfaces++;
usb_config_desc->wTotalLength += desc_len;
usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength);
usb_next_iface_desc =
(usb_interface_descriptor_t *)(usb_config_buf +
usb_config_desc->wTotalLength);
}
static uint8_t usb_ep_set_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) {
@ -186,12 +205,14 @@ static uint8_t usb_ep_clear_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) {
* USB configuration (device & string descriptors)
*/
static uint8_t *usb_get_dev_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_dev_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
*length = sizeof(usb_dev_desc);
return (uint8_t *)(&usb_dev_desc);
}
static uint8_t *usb_get_langid_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_langid_str_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
static const usb_langid_descriptor_t usb_langid_str_desc = {
.bLength = USB_LEN_LANGID_STR_DESC,
.bDescriptorType = USB_DESC_TYPE_STRING,
@ -201,32 +222,38 @@ static uint8_t *usb_get_langid_str_descriptor(USBD_SpeedTypeDef speed, uint16_t
return UNCONST(&usb_langid_str_desc);
}
static uint8_t *usb_get_manufacturer_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_manufacturer_str_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
USBD_GetString((uint8_t *)usb_str_table.manufacturer, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_product_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_product_str_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
USBD_GetString((uint8_t *)usb_str_table.product, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_serial_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_serial_str_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
USBD_GetString((uint8_t *)usb_str_table.serial_number, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_configuration_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_configuration_str_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
USBD_GetString((uint8_t *)"", usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_interface_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_interface_str_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
USBD_GetString((uint8_t *)usb_str_table.interface, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_bos_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
static uint8_t *usb_get_bos_descriptor(USBD_SpeedTypeDef speed,
uint16_t *length) {
if (sectrue == usb21_enabled) {
static uint8_t bos[] = {
// usb_bos_descriptor {
@ -240,7 +267,8 @@ static uint8_t *usb_get_bos_descriptor(USBD_SpeedTypeDef speed, uint16_t *length
USB_DESC_TYPE_DEVICE_CAPABILITY, // uint8_t bDescriptorType
USB_DEVICE_CAPABILITY_PLATFORM, // uint8_t bDevCapabilityType
0x00, // uint8_t bReserved
0x38, 0xb6, 0x08, 0x34, 0xa9, 0x09, 0xa0, 0x47, 0x8b, 0xfd, 0xa0, 0x76, 0x88, 0x15, 0xb6, 0x65, // uint128_t platformCompatibilityUUID
0x38, 0xb6, 0x08, 0x34, 0xa9, 0x09, 0xa0, 0x47, 0x8b, 0xfd, 0xa0, 0x76,
0x88, 0x15, 0xb6, 0x65, // uint128_t platformCompatibilityUUID
0x00, 0x01, // uint16_t bcdVersion
USB_WEBUSB_VENDOR_CODE, // uint8_t bVendorCode
USB_WEBUSB_LANDING_PAGE, // uint8_t iLandingPage
@ -313,7 +341,8 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
#define USB_WEBUSB_URL_SCHEME_HTTP 0
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev,
USBD_SetupReqTypedef *req) {
delay_random();
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
@ -324,23 +353,39 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
if ((req->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_VENDOR) {
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) {
if (sectrue == usb21_enabled && req->bRequest == USB_WEBUSB_VENDOR_CODE) {
if (req->wIndex == USB_WEBUSB_REQ_GET_URL && req->wValue == USB_WEBUSB_LANDING_PAGE) {
if (req->wIndex == USB_WEBUSB_REQ_GET_URL &&
req->wValue == USB_WEBUSB_LANDING_PAGE) {
static const char webusb_url[] = {
3 + 15, // uint8_t bLength
USB_WEBUSB_DESCRIPTOR_TYPE_URL, // uint8_t bDescriptorType
USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
't',
'r',
'e',
'z',
'o',
'r',
'.',
'i',
'o',
'/',
's',
't',
'a',
'r',
't', // char URL[]
};
USBD_CtlSendData(dev, UNCONST(webusb_url), MIN_8bits(req->wLength, sizeof(webusb_url)));
USBD_CtlSendData(dev, UNCONST(webusb_url),
MIN_8bits(req->wLength, sizeof(webusb_url)));
return USBD_OK;
} else {
USBD_CtlError(dev, req);
return USBD_FAIL;
}
}
else
if (sectrue == usb21_enabled && req->bRequest == USB_WINUSB_VENDOR_CODE) {
if (req->wIndex == USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR) {
} else if (sectrue == usb21_enabled &&
req->bRequest == USB_WINUSB_VENDOR_CODE) {
if (req->wIndex ==
USB_WINUSB_REQ_GET_COMPATIBLE_ID_FEATURE_DESCRIPTOR) {
static const uint8_t winusb_wcid[] = {
// header
0x28, 0x00, 0x00, 0x00, // dwLength
@ -349,13 +394,16 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
0x01, // bNumSections
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
// functions
0x00, // bInterfaceNumber - HACK: we present only interface 0 as WinUSB
0x00, // bInterfaceNumber - HACK: we present only interface 0 as
// WinUSB
0x01, // reserved
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleId
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, // subCompatibleId
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
};
USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN_8bits(req->wLength, sizeof(winusb_wcid)));
USBD_CtlSendData(dev, UNCONST(winusb_wcid),
MIN_8bits(req->wLength, sizeof(winusb_wcid)));
return USBD_OK;
} else {
USBD_CtlError(dev, req);
@ -363,9 +411,11 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
}
}
}
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE) {
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_INTERFACE) {
if (sectrue == usb21_enabled && req->bRequest == USB_WINUSB_VENDOR_CODE) {
if (req->wIndex == USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR &&
if (req->wIndex ==
USB_WINUSB_REQ_GET_EXTENDED_PROPERTIES_OS_FEATURE_DESCRIPTOR &&
(req->wValue & 0xFF) == 0) { // reply only if interface is 0
static const uint8_t winusb_guid[] = {
// header
@ -377,11 +427,21 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
0x88, 0x00, 0x00, 0x00, // dwLength
0x07, 0x00, 0x00, 0x00, // dwPropertyDataType
0x2A, 0x00, // wNameLength
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00, // .name
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00,
'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00,
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00,
'D', 0x00, 's', 0x00, 0x00, 0x00, // .name
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00,
'4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00,
'8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00,
'8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00,
'-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00,
'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00,
'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
};
USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN_8bits(req->wLength, sizeof(winusb_guid)));
USBD_CtlSendData(dev, UNCONST(winusb_guid),
MIN_8bits(req->wLength, sizeof(winusb_guid)));
return USBD_OK;
} else {
USBD_CtlError(dev, req);
@ -389,8 +449,8 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
}
}
}
} else
if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE) {
} else if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) ==
USB_REQ_RECIPIENT_INTERFACE) {
if (req->wIndex >= USBD_MAX_NUM_INTERFACES) {
USBD_CtlError(dev, req);
return USBD_FAIL;
@ -401,7 +461,8 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
case USB_IFACE_TYPE_VCP:
return usb_vcp_class_setup(dev, &usb_ifaces[req->wIndex].vcp, req);
case USB_IFACE_TYPE_WEBUSB:
return usb_webusb_class_setup(dev, &usb_ifaces[req->wIndex].webusb, req);
return usb_webusb_class_setup(dev, &usb_ifaces[req->wIndex].webusb,
req);
default:
USBD_CtlError(dev, req);
return USBD_FAIL;
@ -469,7 +530,8 @@ static uint8_t *usb_class_get_cfg_desc(uint16_t *length) {
return usb_config_buf;
}
static uint8_t *usb_class_get_usrstr_desc(USBD_HandleTypeDef *dev, uint8_t index, uint16_t *length) {
static uint8_t *usb_class_get_usrstr_desc(USBD_HandleTypeDef *dev,
uint8_t index, uint16_t *length) {
if (sectrue == usb21_enabled && index == USB_WINUSB_EXTRA_STRING_INDEX) {
static const uint8_t winusb_string_descriptor[] = {
0x12, // bLength

@ -77,5 +77,7 @@ int __wur usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t len);
int __wur usb_hid_write(uint8_t iface_num, const uint8_t *buf, uint32_t len);
int __wur usb_hid_read_select(uint32_t timeout);
int __wur usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int timeout);
int __wur usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout);
int __wur usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len,
int timeout);
int __wur usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf,
uint32_t len, int timeout);

@ -30,7 +30,6 @@
/* usb_hid_add adds and configures new USB HID interface according to
* configuration options passed in `info`. */
secbool usb_hid_add(const usb_hid_info_t *info) {
usb_iface_t *iface = usb_get_iface(info->iface_num);
if (iface == NULL) {
@ -40,7 +39,8 @@ secbool usb_hid_add(const usb_hid_info_t *info) {
return secfalse; // Interface is already enabled
}
usb_hid_descriptor_block_t *d = usb_desc_alloc_iface(sizeof(usb_hid_descriptor_block_t));
usb_hid_descriptor_block_t *d =
usb_desc_alloc_iface(sizeof(usb_hid_descriptor_block_t));
if (d == NULL) {
return secfalse; // Not enough space in the configuration descriptor
@ -206,7 +206,8 @@ int usb_hid_read_select(uint32_t timeout) {
return -1; // Timeout
}
int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int timeout) {
int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len,
int timeout) {
const uint32_t start = HAL_GetTick();
while (sectrue != usb_hid_can_read(iface_num)) {
if (timeout >= 0 && HAL_GetTick() - start >= timeout) {
@ -217,7 +218,8 @@ int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int tim
return usb_hid_read(iface_num, buf, len);
}
int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout) {
int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len,
int timeout) {
const uint32_t start = HAL_GetTick();
while (sectrue != usb_hid_can_write(iface_num)) {
if (timeout >= 0 && HAL_GetTick() - start >= timeout) {
@ -228,7 +230,8 @@ int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len,
return usb_hid_write(iface_num, buf, len);
}
static void usb_hid_class_init(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t cfg_idx) {
static void usb_hid_class_init(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
uint8_t cfg_idx) {
// Open endpoints
USBD_LL_OpenEP(dev, state->ep_in, USBD_EP_TYPE_INTR, state->max_packet_len);
USBD_LL_OpenEP(dev, state->ep_out, USBD_EP_TYPE_INTR, state->max_packet_len);
@ -241,10 +244,12 @@ static void usb_hid_class_init(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
state->ep_in_is_idle = 1;
// Prepare the OUT EP to receive next packet
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_buffer, state->max_packet_len);
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_buffer,
state->max_packet_len);
}
static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t cfg_idx) {
static void usb_hid_class_deinit(USBD_HandleTypeDef *dev,
usb_hid_state_t *state, uint8_t cfg_idx) {
// Flush endpoints
USBD_LL_FlushEP(dev, state->ep_in);
USBD_LL_FlushEP(dev, state->ep_out);
@ -253,13 +258,12 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state
USBD_LL_CloseEP(dev, state->ep_out);
}
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
USBD_SetupReqTypedef *req) {
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
// Class request
case USB_REQ_TYPE_CLASS:
switch (req->bRequest) {
case USB_HID_REQ_SET_PROTOCOL:
state->protocol = req->wValue;
USBD_CtlSendStatus(dev);
@ -287,25 +291,27 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
// Interface & Endpoint request
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
state->alt_setting = req->wValue;
USBD_CtlSendStatus(dev);
return USBD_OK;
case USB_REQ_GET_INTERFACE:
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
USBD_CtlSendData(dev, &state->alt_setting,
sizeof(state->alt_setting));
return USBD_OK;
case USB_REQ_GET_DESCRIPTOR:
switch (req->wValue >> 8) {
case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN_8bits(req->wLength, sizeof(state->desc_block->hid)));
USBD_CtlSendData(
dev, UNCONST(&state->desc_block->hid),
MIN_8bits(req->wLength, sizeof(state->desc_block->hid)));
return USBD_OK;
case USB_DESC_TYPE_REPORT:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN_8bits(req->wLength, state->report_desc_len));
USBD_CtlSendData(dev, UNCONST(state->report_desc),
MIN_8bits(req->wLength, state->report_desc_len));
return USBD_OK;
default:
@ -324,19 +330,23 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
return USBD_OK;
}
static void usb_hid_class_data_in(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t ep_num) {
static void usb_hid_class_data_in(USBD_HandleTypeDef *dev,
usb_hid_state_t *state, uint8_t ep_num) {
if ((ep_num | USB_EP_DIR_IN) == state->ep_in) {
state->ep_in_is_idle = 1;
}
}
static void usb_hid_class_data_out(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t ep_num) {
static void usb_hid_class_data_out(USBD_HandleTypeDef *dev,
usb_hid_state_t *state, uint8_t ep_num) {
if (ep_num == state->ep_out) {
state->last_read_len = USBD_LL_GetRxDataSize(dev, ep_num);
// Prepare the OUT EP to receive next packet
// User should provide state->rx_buffer that is big enough for state->max_packet_len bytes
USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer, state->max_packet_len);
// User should provide state->rx_buffer that is big enough for
// state->max_packet_len bytes
USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer,
state->max_packet_len);
if (state->last_read_len > 0) {
// Block the OUT EP until we process received data

@ -52,9 +52,11 @@ typedef struct __attribute__((packed)) {
typedef struct __attribute__((packed)) {
usb_interface_assoc_descriptor_t assoc;
usb_interface_descriptor_t iface_cdc;
usb_vcp_header_descriptor_t fheader; // Class-Specific Descriptor Header Format
usb_vcp_header_descriptor_t
fheader; // Class-Specific Descriptor Header Format
usb_vcp_cm_descriptor_t fcm; // Call Management Functional Descriptor
usb_vcp_acm_descriptor_t facm; // Abstract Control Management Functional Descriptor
usb_vcp_acm_descriptor_t
facm; // Abstract Control Management Functional Descriptor
usb_vcp_union_descriptor_t funion; // Union Interface Functional Descriptor
usb_endpoint_descriptor_t ep_cmd;
usb_interface_descriptor_t iface_data;
@ -87,21 +89,28 @@ typedef enum {
* passed pointers need to live at least until the interface is disabled
* (usb_stop is called). */
typedef struct {
uint8_t *tx_packet; // Buffer for one packet, with length of at least max_packet_len bytes
uint8_t *tx_buffer; // Buffer for IN EP ring buffer, with length of at least tx_buffer_len bytes
uint8_t *rx_packet; // Buffer for one packet, with length of at least max_packet_len bytes
uint8_t *rx_buffer; // Buffer for OUT EP ring buffer, with length of at least rx_buffer_len bytes
uint8_t *tx_packet; // Buffer for one packet, with length of at least
// max_packet_len bytes
uint8_t *tx_buffer; // Buffer for IN EP ring buffer, with length of at least
// tx_buffer_len bytes
uint8_t *rx_packet; // Buffer for one packet, with length of at least
// max_packet_len bytes
uint8_t *rx_buffer; // Buffer for OUT EP ring buffer, with length of at least
// rx_buffer_len bytes
size_t tx_buffer_len; // Length of tx_buffer, needs to be a power of 2
size_t rx_buffer_len; // Length of rx_buffer, needs to be a power of 2
void (*rx_intr_fn)(void); // Callback called from usb_vcp_class_data_out IRQ handler if rx_intr_byte matches
void (*rx_intr_fn)(void); // Callback called from usb_vcp_class_data_out IRQ
// handler if rx_intr_byte matches
uint8_t rx_intr_byte; // Value matched against every received byte
uint8_t iface_num; // Address of this VCP interface
uint8_t data_iface_num; // Address of data interface of the VCP interface association
uint8_t data_iface_num; // Address of data interface of the VCP interface
// association
uint8_t ep_cmd; // Address of IN CMD endpoint (with the highest bit set)
uint8_t ep_in; // Address of IN endpoint (with the highest bit set)
uint8_t ep_out; // Address of OUT endpoint
uint8_t polling_interval; // In units of 1ms
uint8_t max_packet_len; // Length of the biggest packet, and of tx_packet and rx_packet
uint8_t max_packet_len; // Length of the biggest packet, and of tx_packet and
// rx_packet
} usb_vcp_info_t;
/* usb_rbuf_t is used internally for the RX/TX buffering. */
@ -141,5 +150,7 @@ secbool __wur usb_vcp_can_write(uint8_t iface_num);
int __wur usb_vcp_read(uint8_t iface_num, uint8_t *buf, uint32_t len);
int __wur usb_vcp_write(uint8_t iface_num, const uint8_t *buf, uint32_t len);
int __wur usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int timeout);
int __wur usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout);
int __wur usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len,
int timeout);
int __wur usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf,
uint32_t len, int timeout);

@ -26,7 +26,8 @@
// Class Subclass Code (bFunctionSubClass, bInterfaceSubClass)
#define USB_CDC_SUBCLASS_ACM 0x02
// Communications Interface Class Control Protocol Codes (bFunctionProtocol, bInterfaceProtocol)
// Communications Interface Class Control Protocol Codes (bFunctionProtocol,
// bInterfaceProtocol)
#define USB_CDC_PROTOCOL_AT 0x01
// Descriptor Types (bDescriptorType)
@ -52,7 +53,6 @@
/* usb_vcp_add adds and configures new USB VCP interface according to
* configuration options passed in `info`. */
secbool usb_vcp_add(const usb_vcp_info_t *info) {
usb_iface_t *iface = usb_get_iface(info->iface_num);
if (iface == NULL) {
@ -62,7 +62,8 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
return secfalse; // Interface is already enabled
}
usb_vcp_descriptor_block_t *d = usb_desc_alloc_iface(sizeof(usb_vcp_descriptor_block_t));
usb_vcp_descriptor_block_t *d =
usb_desc_alloc_iface(sizeof(usb_vcp_descriptor_block_t));
if (d == NULL) {
return secfalse; // Not enough space in the configuration descriptor
@ -77,10 +78,12 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
if ((info->ep_out & USB_EP_DIR_MASK) != USB_EP_DIR_OUT) {
return secfalse; // OUT EP is invalid
}
if ((info->rx_buffer_len == 0) || (info->rx_buffer_len & (info->rx_buffer_len - 1)) != 0) {
if ((info->rx_buffer_len == 0) ||
(info->rx_buffer_len & (info->rx_buffer_len - 1)) != 0) {
return secfalse; // Capacity needs to be a power of 2
}
if ((info->tx_buffer_len == 0) || (info->tx_buffer_len & (info->tx_buffer_len - 1)) != 0) {
if ((info->tx_buffer_len == 0) ||
(info->tx_buffer_len & (info->tx_buffer_len - 1)) != 0) {
return secfalse; // Capacity needs to be a power of 2
}
if (info->rx_buffer == NULL) {
@ -121,14 +124,16 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
d->fheader.bFunctionLength = sizeof(usb_vcp_header_descriptor_t);
d->fheader.bDescriptorType = USB_DESC_TYPE_CS_INTERACE;
d->fheader.bDescriptorSubtype = USB_DESC_TYPE_HEADER;
d->fheader.bcdCDC = 0x1001; // USB Class Definitions for Communication Devices Specification release number.
d->fheader.bcdCDC = 0x1001; // USB Class Definitions for Communication
// Devices Specification release number.
// Call Management Functional Descriptor
d->fcm.bFunctionLength = sizeof(usb_vcp_cm_descriptor_t);
d->fcm.bDescriptorType = USB_DESC_TYPE_CS_INTERACE;
d->fcm.bDescriptorSubtype = USB_DESC_TYPE_CM;
// Device sends/receives call management information only over the Communication Class interface.
// Device does not handle call management itself.
// Device sends/receives call management information only over the
// Communication Class interface. Device does not handle call management
// itself.
d->fcm.bmCapabilities = 0x00;
d->fcm.bDataInterface = info->data_iface_num;
@ -136,8 +141,8 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
d->facm.bFunctionLength = sizeof(usb_vcp_acm_descriptor_t);
d->facm.bDescriptorType = USB_DESC_TYPE_CS_INTERACE;
d->facm.bDescriptorSubtype = USB_DESC_TYPE_ACM;
// Device supports the request combination of Set_Line_Coding, Set_Control_Line_State,
// Get_Line_Coding, and the notification Serial_State.
// Device supports the request combination of Set_Line_Coding,
// Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.
d->facm.bmCapabilities = 0x02;
// Union Functional Descriptor
@ -184,7 +189,8 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
// Config descriptor
usb_desc_add_iface(sizeof(usb_vcp_descriptor_block_t));
usb_config_desc->bNumInterfaces++; // usb_vcp_descriptor_block_t contains 2 interfaces
usb_config_desc
->bNumInterfaces++; // usb_vcp_descriptor_block_t contains 2 interfaces
// Interface state
@ -217,17 +223,11 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
return sectrue;
}
static inline size_t ring_length(usb_rbuf_t *b) {
return (b->write - b->read);
}
static inline size_t ring_length(usb_rbuf_t *b) { return (b->write - b->read); }
static inline int ring_empty(usb_rbuf_t *b) {
return ring_length(b) == 0;
}
static inline int ring_empty(usb_rbuf_t *b) { return ring_length(b) == 0; }
static inline int ring_full(usb_rbuf_t *b) {
return ring_length(b) == b->cap;
}
static inline int ring_full(usb_rbuf_t *b) { return ring_length(b) == b->cap; }
secbool usb_vcp_can_read(uint8_t iface_num) {
usb_iface_t *iface = usb_get_iface(iface_num);
@ -300,7 +300,8 @@ int usb_vcp_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) {
return len;
}
int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int timeout) {
int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len,
int timeout) {
uint32_t start = HAL_GetTick();
while (sectrue != usb_vcp_can_read(iface_num)) {
if (timeout >= 0 && HAL_GetTick() - start >= timeout) {
@ -311,7 +312,8 @@ int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int tim
return usb_vcp_read(iface_num, buf, len);
}
int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout) {
int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len,
int timeout) {
uint32_t start = HAL_GetTick();
while (sectrue != usb_vcp_can_write(iface_num)) {
if (timeout >= 0 && HAL_GetTick() - start >= timeout) {
@ -322,11 +324,13 @@ int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len,
return usb_vcp_write(iface_num, buf, len);
}
static void usb_vcp_class_init(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t cfg_idx) {
static void usb_vcp_class_init(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
uint8_t cfg_idx) {
// Open endpoints
USBD_LL_OpenEP(dev, state->ep_in, USBD_EP_TYPE_BULK, state->max_packet_len);
USBD_LL_OpenEP(dev, state->ep_out, USBD_EP_TYPE_BULK, state->max_packet_len);
USBD_LL_OpenEP(dev, state->ep_cmd, USBD_EP_TYPE_INTR, USB_CDC_MAX_CMD_PACKET_LEN);
USBD_LL_OpenEP(dev, state->ep_cmd, USBD_EP_TYPE_INTR,
USB_CDC_MAX_CMD_PACKET_LEN);
// Reset the state
state->rx_ring.read = 0;
@ -336,10 +340,12 @@ static void usb_vcp_class_init(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
state->ep_in_is_idle = 1;
// Prepare the OUT EP to receive next packet
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_packet, state->max_packet_len);
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_packet,
state->max_packet_len);
}
static void usb_vcp_class_deinit(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t cfg_idx) {
static void usb_vcp_class_deinit(USBD_HandleTypeDef *dev,
usb_vcp_state_t *state, uint8_t cfg_idx) {
// Flush endpoints
USBD_LL_FlushEP(dev, state->ep_in);
USBD_LL_FlushEP(dev, state->ep_out);
@ -350,7 +356,8 @@ static void usb_vcp_class_deinit(USBD_HandleTypeDef *dev, usb_vcp_state_t *state
USBD_LL_CloseEP(dev, state->ep_cmd);
}
static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, USBD_SetupReqTypedef *req) {
static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
USBD_SetupReqTypedef *req) {
static const usb_cdc_line_coding_t line_coding = {
.dwDTERate = 115200,
.bCharFormat = USB_CDC_1_STOP_BITS,
@ -364,26 +371,31 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) {
if (req->bRequest == USB_CDC_GET_LINE_CODING) {
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN_8bits(req->wLength, sizeof(line_coding)));
USBD_CtlSendData(dev, UNCONST(&line_coding),
MIN_8bits(req->wLength, sizeof(line_coding)));
} else {
USBD_CtlSendData(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
USBD_CtlSendData(dev, state->cmd_buffer,
MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
}
} else { // USB_REQ_DIR_H2D
if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
USBD_CtlPrepareRx(dev, state->cmd_buffer,
MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
}
}
return USBD_OK;
}
static void usb_vcp_class_data_in(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t ep_num) {
static void usb_vcp_class_data_in(USBD_HandleTypeDef *dev,
usb_vcp_state_t *state, uint8_t ep_num) {
if ((ep_num | USB_EP_DIR_IN) == state->ep_in) {
state->ep_in_is_idle = 1;
}
}
static void usb_vcp_class_data_out(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t ep_num) {
static void usb_vcp_class_data_out(USBD_HandleTypeDef *dev,
usb_vcp_state_t *state, uint8_t ep_num) {
if (ep_num == state->ep_out) {
uint32_t len = USBD_LL_GetRxDataSize(dev, ep_num);
@ -404,7 +416,8 @@ static void usb_vcp_class_data_out(USBD_HandleTypeDef *dev, usb_vcp_state_t *sta
}
// Prepare the OUT EP to receive next packet
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_packet, state->max_packet_len);
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_packet,
state->max_packet_len);
}
}

@ -26,8 +26,8 @@ typedef struct __attribute__((packed)) {
usb_endpoint_descriptor_t ep_out;
} usb_webusb_descriptor_block_t;
/* usb_webusb_info_t contains all information for setting up a WebUSB interface. All
* passed pointers need to live at least until the interface is disabled
/* usb_webusb_info_t contains all information for setting up a WebUSB interface.
* All passed pointers need to live at least until the interface is disabled
* (usb_stop is called). */
typedef struct {
uint8_t *rx_buffer; // With length of max_packet_len bytes
@ -40,10 +40,10 @@ typedef struct {
uint8_t max_packet_len; // Length of the biggest report and of rx_buffer
} usb_webusb_info_t;
/* usb_webusb_state_t encapsulates all state used by enabled WebUSB interface. It
* needs to be completely initialized in usb_webusb_add and reset in
* usb_webusb_class_init. See usb_webusb_info_t for details of the configuration
* fields. */
/* usb_webusb_state_t encapsulates all state used by enabled WebUSB interface.
* It needs to be completely initialized in usb_webusb_add and reset in
* usb_webusb_class_init. See usb_webusb_info_t for details of the
* configuration fields. */
typedef struct {
const usb_webusb_descriptor_block_t *desc_block;
uint8_t *rx_buffer;
@ -63,5 +63,7 @@ int __wur usb_webusb_read(uint8_t iface_num, uint8_t *buf, uint32_t len);
int __wur usb_webusb_write(uint8_t iface_num, const uint8_t *buf, uint32_t len);
int __wur usb_webusb_read_select(uint32_t timeout);
int __wur usb_webusb_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int timeout);
int __wur usb_webusb_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout);
int __wur usb_webusb_read_blocking(uint8_t iface_num, uint8_t *buf,
uint32_t len, int timeout);
int __wur usb_webusb_write_blocking(uint8_t iface_num, const uint8_t *buf,
uint32_t len, int timeout);

@ -22,7 +22,6 @@
/* usb_webusb_add adds and configures new USB WebUSB interface according to
* configuration options passed in `info`. */
secbool usb_webusb_add(const usb_webusb_info_t *info) {
usb_iface_t *iface = usb_get_iface(info->iface_num);
if (iface == NULL) {
@ -32,7 +31,8 @@ secbool usb_webusb_add(const usb_webusb_info_t *info) {
return secfalse; // Interface is already enabled
}
usb_webusb_descriptor_block_t *d = usb_desc_alloc_iface(sizeof(usb_webusb_descriptor_block_t));
usb_webusb_descriptor_block_t *d =
usb_desc_alloc_iface(sizeof(usb_webusb_descriptor_block_t));
if (d == NULL) {
return secfalse; // Not enough space in the configuration descriptor
@ -182,7 +182,8 @@ int usb_webusb_read_select(uint32_t timeout) {
return -1; // Timeout
}
int usb_webusb_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int timeout) {
int usb_webusb_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len,
int timeout) {
const uint32_t start = HAL_GetTick();
while (sectrue != usb_webusb_can_read(iface_num)) {
if (timeout >= 0 && HAL_GetTick() - start >= timeout) {
@ -193,7 +194,8 @@ int usb_webusb_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, int
return usb_webusb_read(iface_num, buf, len);
}
int usb_webusb_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, int timeout) {
int usb_webusb_write_blocking(uint8_t iface_num, const uint8_t *buf,
uint32_t len, int timeout) {
const uint32_t start = HAL_GetTick();
while (sectrue != usb_webusb_can_write(iface_num)) {
if (timeout >= 0 && HAL_GetTick() - start >= timeout) {
@ -204,7 +206,8 @@ int usb_webusb_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t le
return usb_webusb_write(iface_num, buf, len);
}
static void usb_webusb_class_init(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, uint8_t cfg_idx) {
static void usb_webusb_class_init(USBD_HandleTypeDef *dev,
usb_webusb_state_t *state, uint8_t cfg_idx) {
// Open endpoints
USBD_LL_OpenEP(dev, state->ep_in, USBD_EP_TYPE_INTR, state->max_packet_len);
USBD_LL_OpenEP(dev, state->ep_out, USBD_EP_TYPE_INTR, state->max_packet_len);
@ -215,10 +218,13 @@ static void usb_webusb_class_init(USBD_HandleTypeDef *dev, usb_webusb_state_t *s
state->ep_in_is_idle = 1;
// Prepare the OUT EP to receive next packet
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_buffer, state->max_packet_len);
USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_buffer,
state->max_packet_len);
}
static void usb_webusb_class_deinit(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, uint8_t cfg_idx) {
static void usb_webusb_class_deinit(USBD_HandleTypeDef *dev,
usb_webusb_state_t *state,
uint8_t cfg_idx) {
// Flush endpoints
USBD_LL_FlushEP(dev, state->ep_in);
USBD_LL_FlushEP(dev, state->ep_out);
@ -227,14 +233,14 @@ static void usb_webusb_class_deinit(USBD_HandleTypeDef *dev, usb_webusb_state_t
USBD_LL_CloseEP(dev, state->ep_out);
}
static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, USBD_SetupReqTypedef *req) {
static int usb_webusb_class_setup(USBD_HandleTypeDef *dev,
usb_webusb_state_t *state,
USBD_SetupReqTypedef *req) {
if ((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) {
return USBD_OK;
}
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
state->alt_setting = req->wValue;
USBD_CtlSendStatus(dev);
@ -250,19 +256,25 @@ static int usb_webusb_class_setup(USBD_HandleTypeDef *dev, usb_webusb_state_t *s
}
}
static void usb_webusb_class_data_in(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, uint8_t ep_num) {
static void usb_webusb_class_data_in(USBD_HandleTypeDef *dev,
usb_webusb_state_t *state,
uint8_t ep_num) {
if ((ep_num | USB_EP_DIR_IN) == state->ep_in) {
state->ep_in_is_idle = 1;
}
}
static void usb_webusb_class_data_out(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, uint8_t ep_num) {
static void usb_webusb_class_data_out(USBD_HandleTypeDef *dev,
usb_webusb_state_t *state,
uint8_t ep_num) {
if (ep_num == state->ep_out) {
state->last_read_len = USBD_LL_GetRxDataSize(dev, ep_num);
// Prepare the OUT EP to receive next packet
// User should provide state->rx_buffer that is big enough for state->max_packet_len bytes
USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer, state->max_packet_len);
// User should provide state->rx_buffer that is big enough for
// state->max_packet_len bytes
USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer,
state->max_packet_len);
if (state->last_read_len > 0) {
// Block the OUT EP until we process received data

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

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save