intermediate commit

This commit is contained in:
Cédric 2018-03-05 21:51:57 +01:00
parent 77548b1ddd
commit e6026d5809
13 changed files with 219 additions and 44 deletions

View File

@ -1,17 +1,19 @@
# Copyright 2017 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS
#
#*******************************************************************************
# Ledger App
# (c) 2017 Ledger
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#*******************************************************************************
ifeq ($(BOLOS_SDK),)
$(error Environment variable BOLOS_SDK is not set)
@ -19,57 +21,74 @@ endif
include $(BOLOS_SDK)/Makefile.defines
APPNAME = "OpenPGP"
APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_LOAD_PARAMS)
APP_LOAD_PARAMS=--appFlags 0x50 --path "" --curve secp256k1 $(COMMON_LOAD_PARAMS)
APPVERSION_M=1
APPVERSION_N=1
APPVERSION_N=2
APPVERSION_P=0
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
SPECVERSION="3.3.1"
ICONNAME=images/icon_pgp.gif
ifeq ($(TARGET_NAME),TARGET_BLUE)
ICONNAME=blue_app_cxt.gif
else
ICONNAME=nanos_app_cxt.gif
endif
DEFINES += $(CXT_CONFIG) CXT_VERSION=$(APPVERSION) CXT_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION)
DEFINES += DEBUGLEDGER
################
# Default rule #
################
all: default
############
# Platform #
############
DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128
DEFINES += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=7 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
DEFINES += HAVE_USB_CLASS_CCID
DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_BAGL HAVE_SPRINTF
#DEFINES += HAVE_PRINTF PRINTF=screen_printf
DEFINES += PRINTF\(...\)=
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=6 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P) TCS_LOADER_PATCH_VERSION=0
DEFINES += UNUSED\(x\)=\(void\)x
DEFINES += APPVERSION=\"$(APPVERSION)\"
DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION)
##############
# Compiler #
# Compiler #
##############
#GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/
#CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/
CC := $(CLANGPATH)clang
#CFLAGS += -O0 -gdwarf-2 -gstrict-dwarf
#CFLAGS += -O0
CFLAGS += -O3 -Os
AS := $(GCCPATH)arm-none-eabi-gcc
LD := $(GCCPATH)arm-none-eabi-gcc
#LDFLAGS += -O0 -gdwarf-2 -gstrict-dwarf
LDFLAGS += -O3 -Os
LDLIBS += -lm -lgcc -lc
# import rules to compile glyphs(/pone)
include $(BOLOS_SDK)/Makefile.glyphs
### computed variables
### variables processed by the common makefile.rules of the SDK to grab source files and include dirs
APP_SOURCE_PATH += src
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
SDK_SOURCE_PATH += lib_stusb qrcode
#use the SDK U2F+HIDGEN USB profile
SDK_SOURCE_PATH += lib_u2f lib_stusb_impl
DEFINES += U2F_PROXY_MAGIC=\"BTC\"
DEFINES += HAVE_IO_U2F HAVE_U2F USB_SEGMENT_SIZE=64
DEFINES += BLE_SEGMENT_SIZE=20
DEFINES += HAVE_USB_CLASS_CCID
load: all
python -m ledgerblue.loadApp $(APP_LOAD_PARAMS)
@ -81,5 +100,5 @@ delete:
include $(BOLOS_SDK)/Makefile.rules
#add dependency on custom makefile filename
dep/%.d: %.c Makefile.genericwallet
dep/%.d: %.c Makefile

View File

@ -370,6 +370,7 @@ the reader and the delegated PIN support.
Edit the file ~/.gnupg/scdaemon.conf and add the following lines:
| ``reader-port "Ledger Token [Nano S] (0001) 01 00"``
| ``allow-admin``
| ``enable-pinpad-varlen``

View File

@ -28,7 +28,7 @@ int gpg_apdu_get_data(unsigned int ref) ;
int gpg_apdu_get_next_data(unsigned int ref) ;
int gpg_apdu_put_data(unsigned int ref) ;
int gpg_apdu_pso(unsigned int ref);
int gpg_apdu_pso(void);
int gpg_apdu_internal_authenticate(void);
int gpg_apdu_gen(void );
int gpg_apdu_get_challenge(void) ;

View File

@ -282,7 +282,7 @@ int gpg_apdu_put_data(unsigned int ref) {
if (G_gpg_vstate.io_length != 4) {
THROW(SW_WRONG_LENGTH);
}
G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset] &= ~0x07;
G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset+3] &= ~0x07;
nvm_write(&N_gpg_pstate->AID[10], &G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset], 4);
break;

View File

@ -62,7 +62,7 @@ void gpg_check_access_ins() {
case INS_PSO:
if ((ref == 0x9e9a) && gpg_pin_is_verified(PIN_ID_PW1)) {
//pso:sign
//pso:sign
if (N_gpg_pstate->PW_status[0] == 0) {
gpg_pin_set_verified(PIN_ID_PW1, 0);
}
@ -236,7 +236,9 @@ int gpg_dispatch() {
unsigned int tag,t,l;
int sw;
if ((G_gpg_vstate.io_cla != 0x00) && (G_gpg_vstate.io_cla != 0x10) && (G_gpg_vstate.io_cla != 0xEF)) {
if ((G_gpg_vstate.io_cla != 0x00) &&
(G_gpg_vstate.io_cla != 0x10) &&
(G_gpg_vstate.io_cla != 0xEF)) {
THROW(SW_CLA_NOT_SUPPORTED);
return SW_CLA_NOT_SUPPORTED;
}
@ -378,8 +380,9 @@ int gpg_dispatch() {
/* --- PSO --- */
case INS_PSO:
sw = gpg_apdu_pso(tag);
sw = gpg_apdu_pso();
break;
case INS_INTERNAL_AUTHENTICATE:
sw = gpg_apdu_internal_authenticate();
break;

View File

@ -122,7 +122,7 @@ const unsigned char C_ext_length[8] = {
const unsigned char C_default_AID[] = {
0xD2, 0x76, 0x00, 0x01, 0x24, 0x01,
//version
0x03, 0x00,
0x02, 0x00,
//manufacturer
0x2C, 0x97,
//serial
@ -289,7 +289,8 @@ int gpg_install(unsigned char app_state) {
#if 1
G_gpg_vstate.work.io_buffer[0] = PIN_MODE_CONFIRM;
gpg_nvm_write(&N_gpg_pstate->config_pin, G_gpg_vstate.work.io_buffer, 1);
USBD_CCID_activate_pinpad(3);
#warning USBD_CCID_activate_pinpad commented
//USBD_CCID_activate_pinpad(3);
#else
G_gpg_vstate.work.io_buffer[0] = PIN_MODE_HOST;
gpg_nvm_write(&N_gpg_pstate->config_pin, G_gpg_vstate.work.io_buffer, 1);

View File

@ -149,10 +149,7 @@ void gpg_io_insert_tlv(unsigned int T, unsigned int L, unsigned char const *V) {
/* ----------------------------------------------------------------------- */
/* FECTH data from received buffer */
/* ----------------------------------------------------------------------- */
void gpg_io_fetch_buffer(unsigned char* buffer, unsigned int len) {
os_memmove(buffer, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, len);
G_gpg_vstate.io_offset += len;
}
unsigned int gpg_io_fetch_u32() {
unsigned int v32;

View File

@ -165,7 +165,7 @@ __attribute__((section(".boot"))) int main(void) {
//start communication with MCU
io_seproxyhal_init();
USB_CCID_power(1);
USB_power(1);
io_usb_ccid_set_card_inserted(1);

View File

@ -83,7 +83,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
if ((sigkey->attributes.value[0] == 19) ||
(sigkey->attributes.value[0] == 22)) {
cx_ecfp_private_key_t *key;
unsigned int sz,i,rs_len;
unsigned int sz,i,rs_len,info;
unsigned char *rs;
key = &sigkey->key.ecfp256;
@ -97,7 +97,8 @@ static int gpg_sign(gpg_key_t *sigkey) {
CX_RND_TRNG,
CX_NONE,
G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length,
G_gpg_vstate.work.io_buffer);
G_gpg_vstate.work.io_buffer,
&info);
//reencode r,s in MPI format
gpg_io_discard(0);
@ -116,11 +117,12 @@ static int gpg_sign(gpg_key_t *sigkey) {
rs += 2;
}
} else{
sz = cx_eddsa_sign(key, NULL,
sz = cx_eddsa_sign(key,
CX_NONE,
CX_SHA512,
G_gpg_vstate.work.io_buffer, G_gpg_vstate.io_length,
G_gpg_vstate.work.io_buffer+128);
NULL, 0,
G_gpg_vstate.work.io_buffer+128, &info);
gpg_io_discard(0);
gpg_io_insert(G_gpg_vstate.work.io_buffer+128, sz);
}
@ -134,8 +136,30 @@ static int gpg_sign(gpg_key_t *sigkey) {
return SW_REFERENCED_DATA_NOT_FOUND;
}
int gpg_apdu_pso(unsigned int pso) {
int gpg_apdu_pso() {
unsigned int t,l,ksz;
unsigned int pso;
pso = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
//UIF HANDLE
switch(pso) {
// --- PSO:CDS ---
case 0x9e9a:
if ((G_gpg_vstate.kslot->sig.UIF[0]) && ((G_gpg_vstate.UIF_flags)==0)) {
ui_menu_uifconfirm_display(0);
return 0;
}
case 0x8680:
if ((G_gpg_vstate.kslot->dec.UIF[0]) && ((G_gpg_vstate.UIF_flags)==0)) {
ui_menu_uifconfirm_display(0);
return 0;
}
}
switch(pso) {
// --- PSO:CDS ---
case 0x9e9a: {
@ -296,7 +320,6 @@ int gpg_apdu_pso(unsigned int pso) {
THROW(SW_REFERENCED_DATA_NOT_FOUND);
return SW_REFERENCED_DATA_NOT_FOUND;
}
}
//--- PSO:yy NOT SUPPPORTED ---
@ -310,6 +333,11 @@ int gpg_apdu_pso(unsigned int pso) {
int gpg_apdu_internal_authenticate() {
if ((G_gpg_vstate.kslot->aut.UIF[0]) && ((G_gpg_vstate.UIF_flags)==0)) {
ui_menu_uifconfirm_display(0);
return 0;
}
if (G_gpg_vstate.mse_aut->attributes.value[0] == 1) {
if ( G_gpg_vstate.io_length > ((G_gpg_vstate.mse_aut->attributes.value[1]<<8)|G_gpg_vstate.mse_aut->attributes.value[2])*40/100) {
THROW(SW_WRONG_LENGTH);

View File

@ -19,10 +19,19 @@
#include "gpg_types.h"
#include "gpg_api.h"
#include "gpg_vars.h"
const unsigned char C_MF[] = {0x3F, 0x00};
int gpg_apdu_select() {
int sw;
if ( (G_gpg_vstate.io_length == 6) &&
//MF
if ( (G_gpg_vstate.io_length == 2) &&
(os_memcmp(G_gpg_vstate.work.io_buffer, C_MF, G_gpg_vstate.io_length) == 0) ) {
gpg_io_discard(0);
sw = SW_OK;
}
//AID APP
else if ( (G_gpg_vstate.io_length == 6) &&
(os_memcmp(G_gpg_vstate.work.io_buffer, N_gpg_pstate->AID, G_gpg_vstate.io_length) == 0) ) {
G_gpg_vstate.DO_current = 0;
G_gpg_vstate.DO_reccord = 0;
@ -40,7 +49,9 @@ int gpg_apdu_select() {
THROW(SW_STATE_TERMINATED);
}
sw = SW_OK;
} else {
}
//NOT FOUND
else {
THROW(SW_FILE_NOT_FOUND);
return SW_FILE_NOT_FOUND;
}

View File

@ -178,6 +178,8 @@ struct gpg_v_state_s {
gpg_key_t *mse_dec;
unsigned char seed_mode;
unsigned char UIF_flags;
/* io state*/
unsigned char io_cla;
@ -230,7 +232,7 @@ struct gpg_v_state_s {
unsigned char pinmode;
/* ux menus */
char menu[64];
char menu[112];
unsigned char ux_pinentry[12];
unsigned int ux_key;
unsigned int ux_type;

View File

@ -91,6 +91,115 @@ void ui_info(const char* msg1, const char* msg2, const void *menu_display, unsig
UX_MENU_DISPLAY(0, G_gpg_vstate.ui_dogsays, NULL);
};
/* ------------------------------ UIF CONFIRM UX ----------------------------- */
unsigned int ui_uifconfirm_nanos_button(unsigned int button_mask, unsigned int button_mask_counter);
unsigned int ui_uifconfirm_prepro(const bagl_element_t* element);
const bagl_element_t ui_uifconfirm_nanos[] = {
// type userid x y w h str rad fill fg bg font_id icon_id
{ {BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0},
NULL,
0,
0, 0,
NULL, NULL, NULL},
{ {BAGL_ICON, 0x00, 3, 12, 7, 7, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CROSS },
NULL,
0,
0, 0,
NULL, NULL, NULL },
{ {BAGL_ICON, 0x00, 117, 13, 8, 6, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CHECK },
NULL,
0,
0, 0,
NULL, NULL, NULL },
{ {BAGL_LABELINE, 0x01, 0, 12, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px|BAGL_FONT_ALIGNMENT_CENTER, 0 },
G_gpg_vstate.menu,
0,
0, 0,
NULL, NULL, NULL },
{ {BAGL_LABELINE, 0x02, 0, 26, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px|BAGL_FONT_ALIGNMENT_CENTER, 0 },
G_gpg_vstate.menu,
0,
0, 0,
NULL, NULL, NULL },
};
void ui_menu_uifconfirm_display(unsigned int value) {
UX_DISPLAY(ui_uifconfirm_nanos, (void*)ui_uifconfirm_prepro);
}
unsigned int ui_uifconfirm_prepro(const bagl_element_t* element) {
if (element->component.userid == 1) {
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Confirm Operation:");
return 1;
}
if (element->component.userid == 2) {
unsigned int uif_case = (G_gpg_vstate.io_ins<<16)|(G_gpg_vstate.io_p1<<8)|(G_gpg_vstate.io_p2);
switch (uif_case) {
case 0x002A9E9A:
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Signature");
return 1;
case 0x002A8680:
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Encryption");
return 1;
case 0x002A8086:
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Decryption");
return 1;
case 0x0088000:
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Authentication");
return 1;
}
}
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Please Cancel");
return 1;
}
unsigned int ui_uifconfirm_nanos_button(unsigned int button_mask, unsigned int button_mask_counter) {
unsigned int sw;
sw = 0x6985;
switch(button_mask) {
case BUTTON_EVT_RELEASED|BUTTON_LEFT: // CANCEL
gpg_io_discard(1);
gpg_io_insert_u16(sw);
gpg_io_do(IO_RETURN_AFTER_TX);
ui_menu_main_display(0);
sw = 0x6985;
break;
case BUTTON_EVT_RELEASED|BUTTON_RIGHT: // OK
BEGIN_TRY {
TRY {
G_gpg_vstate.UIF_flags = 1;
sw = gpg_apdu_pso();
}
CATCH_OTHER(e) {
gpg_io_discard(1);
if ( (e & 0xFFFF0000) ||
( ((e&0xF000)!=0x6000) && ((e&0xF000)!=0x9000) ) ) {
gpg_io_insert_u32(e);
sw = 0x6f42;
} else {
sw = e;
}
}
FINALLY {
G_gpg_vstate.UIF_flags = 0;
gpg_io_insert_u16(sw);
gpg_io_do(IO_RETURN_AFTER_TX);
ui_menu_main_display(0);
}
break;
} END_TRY;
}
return 0;
}
/* ------------------------------ PIN CONFIRM UX ----------------------------- */
const bagl_element_t ui_pinconfirm_nanos[] = {
@ -663,7 +772,8 @@ void ui_menu_pinmode_action(unsigned int value) {
} else {
s = 3;
}
USBD_CCID_activate_pinpad(s);
#warning USBD_CCID_activate_pinpad commented
//USBD_CCID_activate_pinpad(s);
}
}
else {

View File

@ -40,6 +40,9 @@
/* Includes ------------------------------------------------------------------*/
#include "usbd_ccid_core.h"
#include "usbd_ccid_impl.h"
#define CCID_INTR_IN_EP 0x81
#define CCID_INTR_EPIN_SIZE 16
#ifdef HAVE_USB_CLASS_CCID
@ -57,7 +60,7 @@ static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
'e', 0,
};
#elif TARGET_ID == 0x31100002 // nano s
#elif TARGET_ID == 0x31100003 // nano s
#define USBD_PID 0x0001
static const uint8_t const USBD_PRODUCT_FS_STRING[] = {
6*2+2,