Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/build_and_functional_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Build and run functional tests using ragger through reusable workflow

# This workflow will build the app and then run functional tests using the Ragger framework upon Speculos emulation.
# It calls a reusable workflow developed by Ledger's internal developer team to build the application and upload the
# resulting binaries.
# It then calls another reusable workflow to run the Ragger tests on the compiled application binary.
#
# The build part of this workflow is mandatory, this ensures that the app will be deployable in the Ledger App Store.
# While the test part of this workflow is optional, having functional testing on your application is mandatory and this workflow and
# tooling environment is meant to be easy to use and adapt after forking your application

on:
workflow_dispatch:
inputs:
golden_run:
type: choice
required: true
default: 'Raise an error (default)'
description: CI behavior if the test snapshots are different than expected.
options:
- 'Raise an error (default)'
- 'Open a PR'
push:
branches:
- master
- main
- develop
pull_request:

jobs:
build_application:
name: Build application using the reusable workflow
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1
with:
upload_app_binaries_artifact: "app_waves_binaries"
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,11 @@ dkms.conf
# Project-level stuff
debug/
.DS_Store
*.pyc
*.pyc

# Glyphs gen files
src/glyphs.c
src/glyphs.h

# Build dir
bin
35 changes: 15 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,18 @@ include $(BOLOS_SDK)/Makefile.defines
# Main app configuration

APPVERSION_M=1
APPVERSION_N=1
APPVERSION_P=0
APPVERSION_N=2
APPVERSION_P=1

APPNAME = "Waves"
APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)

ifeq ($(TARGET_NAME),TARGET_BLUE)
ICONNAME=blue_app_waves.gif
else ifeq ($(TARGET_NAME),TARGET_NANOS)
ICONNAME=nanos_app_waves.gif
else
ifeq ($(TARGET_NAME),TARGET_NANOX)
ICONNAME=nanox_app_waves.gif
else
ICONNAME = nanos_app_waves.gif
endif
ICONNAME = nanox_app_waves.gif
endif

APP_LOAD_PARAMS = --appFlags 0x240 --path "44'/5741564'" --curve secp256k1 --curve ed25519 $(COMMON_LOAD_PARAMS)
Expand All @@ -48,16 +46,11 @@ APP_SOURCE_PATH += src
SDK_SOURCE_PATH += lib_stusb #qrcode
#use the SDK U2F+HIDGEN USB profile
SDK_SOURCE_PATH += lib_u2f lib_stusb_impl
SDK_SOURCE_PATH += lib_ux
DEFINES += HAVE_UX_FLOW

ifeq ($(TARGET_NAME),TARGET_NANOX)
SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
SDK_SOURCE_PATH += lib_ux
DEFINES += HAVE_UX_FLOW
endif

ifeq ($(TARGET_NAME),TARGET_NANOS)
SDK_SOURCE_PATH += lib_ux
DEFINES += HAVE_UX_FLOW
endif

DEFINES += APPVERSION=\"$(APPVERSION)\"
Expand All @@ -83,28 +76,30 @@ DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL=""


ifeq ($(TARGET_NAME),TARGET_NANOX)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000
DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE
endif

ifeq ($(TARGET_NAME),TARGET_NANOS)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_GLO096
DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64
DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
endif

# Enabling debug PRINTF
DEBUG = 0
ifneq ($(DEBUG),0)

ifeq ($(TARGET_NAME),TARGET_NANOX)
DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf
else
ifeq ($(TARGET_NAME),TARGET_NANOS)
DEFINES += HAVE_PRINTF PRINTF=screen_printf
else
DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf
endif
else
DEFINES += PRINTF\(...\)=
Expand Down
4 changes: 4 additions & 0 deletions ledger_app.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[app]
build_directory = "./"
sdk = "C"
devices = ["nanox", "nanos+"]
111 changes: 47 additions & 64 deletions src/crypto/stream_eddsa_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,69 +20,52 @@

#include "stream_eddsa_sign.h"

static uint8_t const C_cx_Ed25519_a[] = {
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec};
static uint8_t const C_cx_Ed25519_a[] = {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec};
static uint8_t const C_cx_Ed25519_d[] = {
// d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3
0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73, 0x8c, 0xc7, 0x40,
0x79, 0x77, 0x79, 0xe8, 0x98, 0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41,
0xd8, 0xab, 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3};
0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73, 0x8c, 0xc7, 0x40, 0x79, 0x77, 0x79, 0xe8, 0x98,
0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41, 0xd8, 0xab, 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3};
static uint8_t const C_cx_Ed25519_q[] = {
// q: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed};
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed};
static uint8_t const C_cx_Ed25519_Hq[] = {
// Hq: 0x00000000000000000000000000000000000000000000000000000000000005a4
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xa4};
static uint8_t const C_cx_Ed25519_Bx[] = {
0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0xc0, 0xa4, 0xe2,
0x31, 0xfd, 0xd6, 0xdc, 0x5c, 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25,
0xa7, 0xb2, 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a};
static uint8_t const C_cx_Ed25519_By[] = {
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58};
static uint8_t const C_cx_Ed25519_l[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xa4};
static uint8_t const C_cx_Ed25519_Bx[] = {0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0xc0, 0xa4, 0xe2,
0x31, 0xfd, 0xd6, 0xdc, 0x5c, 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25,
0xa7, 0xb2, 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a};
static uint8_t const C_cx_Ed25519_By[] = {0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58};
static uint8_t const C_cx_Ed25519_l[] = {
// l: 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7,
0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED};
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED};
static uint8_t const C_cx_Ed25519_Hl[] = {
// Hl: 0x0399411b7c309a3dceec73d217f5be65d00e1ba768859347a40611e3449c0f01
0x03, 0x99, 0x41, 0x1b, 0x7c, 0x30, 0x9a, 0x3d, 0xce, 0xec, 0x73,
0xd2, 0x17, 0xf5, 0xbe, 0x65, 0xd0, 0x0e, 0x1b, 0xa7, 0x68, 0x85,
0x93, 0x47, 0xa4, 0x06, 0x11, 0xe3, 0x44, 0x9c, 0x0f, 0x01};
static uint8_t const C_cx_Ed25519_I[] = {
// I: 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0
0x2b, 0x83, 0x24, 0x80, 0x4f, 0xc1, 0xdf, 0x0b, 0x2b, 0x4d, 0x00,
0x99, 0x3d, 0xfb, 0xd7, 0xa7, 0x2f, 0x43, 0x18, 0x06, 0xad, 0x2f,
0xe4, 0x78, 0xc4, 0xee, 0x1b, 0x27, 0x4a, 0x0e, 0xa0, 0xb0};
static uint8_t const C_cx_Ed25519_Qplus3div8[] = {
// q3: 0x0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe};
0x03, 0x99, 0x41, 0x1b, 0x7c, 0x30, 0x9a, 0x3d, 0xce, 0xec, 0x73, 0xd2, 0x17, 0xf5, 0xbe, 0x65,
0xd0, 0x0e, 0x1b, 0xa7, 0x68, 0x85, 0x93, 0x47, 0xa4, 0x06, 0x11, 0xe3, 0x44, 0x9c, 0x0f, 0x01};

#define C_cx_Ed25519_h 8
cx_curve_twisted_edward_t const C_cx_Ed25519 = {
CX_CURVE_Ed25519,
256,
32,
(uint8_t *)C_cx_Ed25519_q,
(uint8_t *)C_cx_Ed25519_Hq,
(uint8_t *)C_cx_Ed25519_Bx,
(uint8_t *)C_cx_Ed25519_By,
(uint8_t *)C_cx_Ed25519_l,
(uint8_t *)C_cx_Ed25519_Hl,
C_cx_Ed25519_h,
(uint8_t *)C_cx_Ed25519_a,
(uint8_t *)C_cx_Ed25519_d,
(uint8_t *)C_cx_Ed25519_I,
(uint8_t *)C_cx_Ed25519_Qplus3div8,

cx_curve_twisted_edwards_t const C_cx_Ed25519 = {
.curve = CX_CURVE_Ed25519,
.bit_size = 256,
.length = 32,

.a = C_cx_Ed25519_a,
.b = C_cx_Ed25519_d,
.p = C_cx_Ed25519_q,
.Gx = C_cx_Ed25519_Bx,
.Gy = C_cx_Ed25519_By,
.n = C_cx_Ed25519_l,
.h = C_cx_Ed25519_h,
.Hp = C_cx_Ed25519_Hq,
.Hn = C_cx_Ed25519_Hl,
};

/* ----------------------------------------------------------------------- */
Expand Down Expand Up @@ -120,12 +103,12 @@ static void cx_compress(unsigned char *P, int size) {
/* ----------------------------------------------------------------------- */
/* */
/* ----------------------------------------------------------------------- */
static void cx_eddsa_get_public_key_internal(
static void l_cx_eddsa_get_public_key_internal(
const cx_ecfp_private_key_t *pv_key, cx_md_t hashID,
cx_ecfp_public_key_t *pu_key, unsigned char *a, unsigned int a_len,
unsigned char *h, unsigned int h_len, unsigned char *scal /*tmp*/) {
cx_curve_twisted_edward_t *domain =
(cx_curve_twisted_edward_t *)&C_cx_Ed25519;
cx_curve_twisted_edwards_t *domain =
(cx_curve_twisted_edwards_t *)&C_cx_Ed25519;
cx_sha512_t hash_ctx;
unsigned int size;

Expand Down Expand Up @@ -179,14 +162,14 @@ static void cx_eddsa_get_public_key_internal(
void stream_eddsa_sign_step1(streamEddsaContext_t *eddsa_context,
const cx_ecfp_private_key_t *pv_key) {
os_memset((unsigned char *)eddsa_context, 0, sizeof(streamEddsaContext_t));
cx_curve_twisted_edward_t *domain =
(cx_curve_twisted_edward_t *)&C_cx_Ed25519;
cx_curve_twisted_edwards_t *domain =
(cx_curve_twisted_edwards_t *)&C_cx_Ed25519;

unsigned int size = domain->length;

unsigned char scal[64];
// retrieve public key,private scalar a, and private prefix h (stored in r)
cx_eddsa_get_public_key_internal(
l_cx_eddsa_get_public_key_internal(
pv_key, CX_SHA512,
(cx_ecfp_public_key_t *)&eddsa_context->u.internal_pu_key,
eddsa_context->a, sizeof(eddsa_context->a), eddsa_context->r,
Expand Down Expand Up @@ -223,8 +206,8 @@ void stream_eddsa_sign_step2(streamEddsaContext_t *eddsa_context,

void stream_eddsa_sign_step3(streamEddsaContext_t *eddsa_context) {
unsigned char scal[64];
cx_curve_twisted_edward_t *domain =
(cx_curve_twisted_edward_t *)&C_cx_Ed25519;
cx_curve_twisted_edwards_t *domain =
(cx_curve_twisted_edwards_t *)&C_cx_Ed25519;
unsigned int size = domain->length;
unsigned int hsize = 2 * size;

Expand Down Expand Up @@ -266,8 +249,8 @@ void stream_eddsa_sign_step4(streamEddsaContext_t *eddsa_context,
int stream_eddsa_sign_step5(streamEddsaContext_t *eddsa_context,
unsigned char *sig) {
unsigned char scal[64];
cx_curve_twisted_edward_t *domain =
(cx_curve_twisted_edward_t *)&C_cx_Ed25519;
cx_curve_twisted_edwards_t *domain =
(cx_curve_twisted_edwards_t *)&C_cx_Ed25519;
unsigned int size = domain->length;
unsigned int hsize = 2 * size;

Expand All @@ -293,4 +276,4 @@ int stream_eddsa_sign_step5(streamEddsaContext_t *eddsa_context,
os_memset((unsigned char *)eddsa_context, 0, sizeof(streamEddsaContext_t));

return 2 * size;
}
}
12 changes: 6 additions & 6 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal_storage_t const N_storage_real;
// SPI Buffer for io_event
unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B];

#if !defined(TARGET_NANOS) && !defined(TARGET_BLUE) && !defined(TARGET_NANOX)
#if !defined(TARGET_NANOS) && !defined(TARGET_BLUE) && !defined(TARGET_NANOX) && !defined(TARGET_NANOS2)
#error This application only supports the Ledger Nano S, Nano X and the Ledger Blue
#endif

Expand Down Expand Up @@ -217,7 +217,7 @@ void handle_apdu(volatile unsigned int *flags, volatile unsigned int *tx,
BEGIN_TRY {
TRY {

if (os_global_pin_is_validated() == 0) {
if (os_global_pin_is_validated() != BOLOS_UX_OK) {
THROW(SW_DEVICE_IS_LOCKED);
}

Expand Down Expand Up @@ -479,10 +479,10 @@ __attribute__((section(".boot"))) int main(void) {

io_seproxyhal_init();

#ifdef TARGET_NANOX
#ifdef HAVE_BLE
// grab the current plane mode setting
G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0);
#endif // TARGET_NANOX
#endif // HAVE_BLE

init_context();

Expand All @@ -496,13 +496,13 @@ __attribute__((section(".boot"))) int main(void) {
USB_power(0);
USB_power(1);

ui_idle();

#ifdef HAVE_BLE
BLE_power(0, NULL);
BLE_power(1, "Nano X");
#endif // HAVE_BLE

ui_idle();

// set menu bar colour for blue
#if defined(TARGET_BLUE)
UX_SET_STATUS_BAR_COLOR(COLOR_BG_1, COLOR_APP);
Expand Down
1 change: 1 addition & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define __MAIN_H__
#include "os.h"
#include "cx.h"
#include "ux.h"
#include "stream_eddsa_sign.h"
#include <stdbool.h>

Expand Down
1 change: 1 addition & 0 deletions src/ui/blue/ui_menus_blue_prepro.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define __UI_MENUS_BLUE_PREPRO_H__

#include "os_io_seproxyhal.h"
#include "ux.h"

const bagl_element_t *ui_address_blue_prepro(const bagl_element_t *element);
const bagl_element_t *ui_idle_blue_prepro(const bagl_element_t *element);
Expand Down
2 changes: 1 addition & 1 deletion src/ui/ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "ui.h"
#include <stdbool.h>
#include "../glyphs.h"
#include "glyphs.h"
#include "../main.h"
#include "../crypto/waves.h"
#include "transactions/transfer.h"
Expand Down
1 change: 1 addition & 0 deletions src/ui/ui_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define __UI_LOGIC_H__

#include "os_io_seproxyhal.h"
#include "ux.h"

unsigned int io_seproxyhal_touch_address_ok(const bagl_element_t *e);
unsigned int io_seproxyhal_cancel(const bagl_element_t *e);
Expand Down