App:
  Serial value depends on active slot: last nible encode active slot
  Fix severals PIN management bugs
  Make PW1 distinction (81/82 tag) for commands PSO:CDS/DEC
  Invalid PW1 'verified' status on PSO:CDS command according to PWstatus
  Remove access control on INS_CHANGE_REFERENCE_DATA
  Remove unused variables
  New icon

 Build
   Add glyphs GIF sources
   Use sdk 1.3.1-4
This commit is contained in:
Cédric Mesnil 2017-03-28 19:24:02 +02:00
parent 278d85a821
commit b0d13ad6d5
15 changed files with 157 additions and 255 deletions

156
Makefile
View File

@ -13,14 +13,18 @@
# limitations under the License. # limitations under the License.
# #
#extract TARGET_ID from the SDK to allow for makefile choices ifeq ($(BOLOS_SDK),)
APPNAME = "OpenPGP" $(error Environment variable BOLOS_SDK is not set)
APPVERSION = "1.0RC1" endif
TARGET_ID = 0x31100002 include $(BOLOS_SDK)/Makefile.defines
$(info TARGET_ID=$(TARGET_ID))
APP_LOAD_PARAMS=--appFlags 0 --path "2152157255" --curve secp256k1 APPNAME = "OpenPGP"
LOADFLAGS = --params --appVersion $(APPVERSION) APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_LOAD_PARAMS)
APPVERSION_M=1
APPVERSION_N=0
APPVERSION_P=RC2
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
ICONNAME=icon_pgp.gif ICONNAME=icon_pgp.gif
@ -28,33 +32,11 @@ ICONNAME=icon_pgp.gif
################ ################
# Default rule # # Default rule #
################ ################
all: default all: default
# consider every intermediate target as final to avoid deleting intermediate files
.SECONDARY:
# disable builtin rules that overload the build process (and the debug log !!)
.SUFFIXES:
MAKEFLAGS += -r
SHELL = /bin/bash
#.ONESHELL:
############ ############
# Platform # # Platform #
############ ############
PROG := token
CONFIG_PRODUCTIONS := bin/$(PROG)
SOURCE_PATH := src $(BOLOS_SDK)/src $(dir $(shell find $(BOLOS_SDK)/lib_stusb* | grep "\.c$$"))
SOURCE_FILES := $(foreach path, $(SOURCE_PATH),$(shell find $(path) | grep "\.c$$") )
INCLUDES_PATH := $(dir $(shell find $(BOLOS_SDK)/lib_stusb* | grep "\.h$$")) include src $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm
### platform definitions
DEFINES := ST31 gcc __IO=volatile
DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128 DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128
DEFINES += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF DEFINES += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF
@ -64,113 +46,39 @@ DEFINES += HAVE_USB_CLASS_CCID
DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME)
############## ##############
# Compiler # # Compiler #
############## ##############
GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/ #GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/
CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin #CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/
CC := $(CLANGPATH)/clang CC := $(CLANGPATH)clang
CFLAGS := #CFLAGS += -O0 -gdwarf-2 -gstrict-dwarf
CFLAGS += -gdwarf-2 -gstrict-dwarf
#CFLAGS += -O0
#CFLAGS += -O0 -g3
CFLAGS += -O3 -Os CFLAGS += -O3 -Os
CFLAGS += -mcpu=cortex-m0 -mthumb
CFLAGS += -fno-common -mtune=cortex-m0 -mlittle-endian
CFLAGS += -std=gnu99 -Werror=int-to-pointer-cast -Wall -Wextra -Wno-unused-variable #-save-temps
CFLAGS += -fdata-sections -ffunction-sections -funsigned-char -fshort-enums
CFLAGS += -mno-unaligned-access
CFLAGS += -Wno-unused-parameter -Wno-duplicate-decl-specifier
CFLAGS += -fropi --target=armv6m-none-eabi AS := $(GCCPATH)arm-none-eabi-gcc
#CFLAGS += -finline-limit-0 -funsigned-bitfields
AS := $(GCCPATH)/arm-none-eabi-gcc LD := $(GCCPATH)arm-none-eabi-gcc
AFLAGS += -ggdb2 -O3 -Os -mcpu=cortex-m0 -fno-common -mtune=cortex-m0 #LDFLAGS += -O0 -gdwarf-2 -gstrict-dwarf
LDFLAGS += -O3 -Os
# NOT SUPPORTED BY STM3L152 CFLAGS += -fpack-struct
#-pg --coverage
LD := $(GCCPATH)/arm-none-eabi-gcc
LDFLAGS :=
LDFLAGS += -gdwarf-2 -gstrict-dwarf
LDFLAGS += -O0 -g3
#LDFLAGS += -O3 -Os
#LDFLAGS += -O0
LDFLAGS += -Wall
LDFLAGS += -mcpu=cortex-m0 -mthumb
LDFLAGS += -fno-common -ffunction-sections -fdata-sections -fwhole-program -nostartfiles
LDFLAGS += -mno-unaligned-access
#LDFLAGS += -nodefaultlibs
#LDFLAGS += -nostdlib -nostdinc
LDFLAGS += -T$(BOLOS_SDK)/script.ld -Wl,--gc-sections -Wl,-Map,debug/$(PROG).map,--cref
LDLIBS += -Wl,--library-path -Wl,$(GCCPATH)/../lib/armv6-m/
#LDLIBS += -Wl,--start-group
LDLIBS += -lm -lgcc -lc LDLIBS += -lm -lgcc -lc
#LDLIBS += -Wl,--end-group
# -mno-unaligned-access # import rules to compile glyphs(/pone)
#-pg --coverage include $(BOLOS_SDK)/Makefile.glyphs
### computed variables ### computed variables
VPATH := $(dir $(SOURCE_FILES)) APP_SOURCE_PATH += src
OBJECT_FILES := $(sort $(addprefix obj/, $(addsuffix .o, $(basename $(notdir $(SOURCE_FILES)))))) SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
DEPEND_FILES := $(sort $(addprefix dep/, $(addsuffix .d, $(basename $(notdir $(SOURCE_FILES))))))
ifeq ($(filter clean,$(MAKECMDGOALS)),)
-include $(DEPEND_FILES)
endif
clean: load: all
rm -fr obj bin debug dep python -m ledgerblue.loadApp $(APP_LOAD_PARAMS)
prepare:
@mkdir -p bin obj debug dep
.SECONDEXPANSION:
# default is not to display make commands
log = $(if $(strip $(VERBOSE)),$1,@$1)
default: prepare bin/$(PROG)
load: default
python -m ledgerblue.loadApp --targetId $(TARGET_ID) --fileName bin/$(PROG).hex --appName $(APPNAME) --icon `python $(BOLOS_SDK)/icon.py $(ICONNAME) hexbitmaponly` $(LOADFLAGS) $(APP_LOAD_PARAMS)
delete: delete:
python -m ledgerblue.deleteApp --targetId $(TARGET_ID) --appName $(APPNAME) python -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS)
bin/$(PROG): $(OBJECT_FILES) $(BOLOS_SDK)/script.ld # import generic rules from the sdk
@echo "[LINK] $@" include $(BOLOS_SDK)/Makefile.rules
$(call log,$(call link_cmdline,$(OBJECT_FILES) $(LDLIBS),$@))
$(call log,$(GCCPATH)/arm-none-eabi-objcopy -O ihex -S bin/$(PROG) bin/$(PROG).hex)
$(call log,mv bin/$(PROG) bin/$(PROG).elf)
$(call log,cp bin/$(PROG).elf obj)
$(call log,$(GCCPATH)/arm-none-eabi-objdump -S -d bin/$(PROG).elf > debug/$(PROG).asm)
dep/%.d: %.c Makefile #add dependency on custom makefile filename
@echo "[DEP] $@" dep/%.d: %.c Makefile.genericwallet
@mkdir -p dep
$(call log,$(call dep_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@))
obj/%.o: %.c dep/%.d
@echo "[CC] $@"
$(call log,$(call cc_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@))
obj/%.o: %.s
@echo "[CC] $@"
$(call log,$(call as_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@))
### BEGIN GCC COMPILER RULES
# link_cmdline(objects,dest) Macro that is used to format arguments for the linker
link_cmdline = $(LD) $(LDFLAGS) -o $(2) $(1)
# dep_cmdline(include,defines,src($<),dest($@)) Macro that is used to format arguments for the dependency creator
dep_cmdline = $(CC) -M $(CFLAGS) $(addprefix -D,$(2)) $(addprefix -I,$(1)) $(3) | sed 's/\($*\)\.o[ :]*/obj\/\1.o: /g' | sed -e 's/[:\t ][^ ]\+\.c//g' > dep/$(basename $(notdir $(4))).d 2>/dev/null
# cc_cmdline(include,defines,src,dest) Macro that is used to format arguments for the compiler
cc_cmdline = $(CC) -c $(CFLAGS) $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3)
as_cmdline = $(AS) -c $(AFLAGS) $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3)
### END GCC COMPILER RULES

BIN
glyphs/badge_back.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 B

BIN
glyphs/icon_dashboard.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 B

After

Width:  |  Height:  |  Size: 88 B

View File

@ -14,20 +14,6 @@ unsigned char const C_badge_back_bitmap[] = {
const bagl_icon_details_t C_badge_back = { GLYPH_badge_back_WIDTH, GLYPH_badge_back_HEIGHT, 1, C_badge_back_colors, C_badge_back_bitmap }; const bagl_icon_details_t C_badge_back = { GLYPH_badge_back_WIDTH, GLYPH_badge_back_HEIGHT, 1, C_badge_back_colors, C_badge_back_bitmap };
#endif // OS_IO_SEPROXYHAL #endif // OS_IO_SEPROXYHAL
#include "glyphs.h" #include "glyphs.h"
unsigned int const C_fish_left_colors[]
= {
0x00000000,
0x00ffffff,
};
unsigned char const C_fish_left_bitmap[] = {
0x00, 0x00, 0x18, 0x84, 0x9f, 0xb1, 0x7f, 0xfe, 0x1f, 0x7f, 0x06, 0x07, 0x01, 0x00, };
#ifdef OS_IO_SEPROXYHAL
#include "os_io_seproxyhal.h"
const bagl_icon_details_t C_fish_left = { GLYPH_fish_left_WIDTH, GLYPH_fish_left_HEIGHT, 1, C_fish_left_colors, C_fish_left_bitmap };
#endif // OS_IO_SEPROXYHAL
#include "glyphs.h"
unsigned int const C_icon_dashboard_colors[] unsigned int const C_icon_dashboard_colors[]
= { = {
0x00000000, 0x00000000,

View File

@ -13,21 +13,6 @@ extern
const bagl_icon_details_t C_badge_back; const bagl_icon_details_t C_badge_back;
#endif // GLYPH_badge_back_BPP #endif // GLYPH_badge_back_BPP
#endif // OS_IO_SEPROXYHAL #endif // OS_IO_SEPROXYHAL
#ifndef GLYPH_fish_left_BPP
#define GLYPH_fish_left_WIDTH 14
#define GLYPH_fish_left_HEIGHT 8
#define GLYPH_fish_left_BPP 1
extern
unsigned int const C_fish_left_colors[]
;
extern
unsigned char const C_fish_left_bitmap[];
#ifdef OS_IO_SEPROXYHAL
#include "os_io_seproxyhal.h"
extern
const bagl_icon_details_t C_fish_left;
#endif // GLYPH_fish_left_BPP
#endif // OS_IO_SEPROXYHAL
#ifndef GLYPH_icon_dashboard_BPP #ifndef GLYPH_icon_dashboard_BPP
#define GLYPH_icon_dashboard_WIDTH 14 #define GLYPH_icon_dashboard_WIDTH 14
#define GLYPH_icon_dashboard_HEIGHT 14 #define GLYPH_icon_dashboard_HEIGHT 14

View File

@ -42,6 +42,7 @@ int gpg_apdu_reset_retry_counter(void) ;
int gpg_oid2curve(unsigned char* oid, unsigned int len); int gpg_oid2curve(unsigned char* oid, unsigned int len);
int gpg_is_pin_verified(int id); int gpg_is_pin_verified(int id);
int gpg_is_pin_blocked(int id); int gpg_is_pin_blocked(int id);
void gpg_set_pin_verified(int id, int verified);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* --- IO ---- */ /* --- IO ---- */

View File

@ -69,6 +69,7 @@ int gpg_apdu_get_data(unsigned int ref) {
/* Full Application identifier */ /* Full Application identifier */
case 0x004F: case 0x004F:
gpg_io_insert(N_gpg_pstate->AID, 16); gpg_io_insert(N_gpg_pstate->AID, 16);
G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset-3] |= G_gpg_vstate.slot+1;
break; break;
/* Historical bytes, */ /* Historical bytes, */
case 0x5F52: case 0x5F52:
@ -261,13 +262,13 @@ int gpg_apdu_put_data(unsigned int ref) {
if (G_gpg_vstate.io_length != 4) { if (G_gpg_vstate.io_length != 4) {
THROW(SW_WRONG_LENGTH); THROW(SW_WRONG_LENGTH);
} }
G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset] &= ~0x07;
nvm_write(&N_gpg_pstate->AID[10], &G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset], 4); nvm_write(&N_gpg_pstate->AID[10], &G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset], 4);
sw = SW_OK; sw = SW_OK;
break; break;
/* ----------------- Extended Header list -----------------*/ /* ----------------- Extended Header list -----------------*/
case 0x3FFF: { case 0x3FFF: {
void *pkey,*vkey;
unsigned int len_e,len_p,len_q; unsigned int len_e,len_p,len_q;
unsigned int endof,ksz,reset_cnt; unsigned int endof,ksz,reset_cnt;
gpg_key_t *keygpg; gpg_key_t *keygpg;

View File

@ -25,6 +25,9 @@ int gpg_is_verified(id) {
} }
void gpg_check_access_ins() { void gpg_check_access_ins() {
unsigned int ref;
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
switch (G_gpg_vstate.io_ins) { switch (G_gpg_vstate.io_ins) {
case INS_SELECT: case INS_SELECT:
return; return;
@ -36,10 +39,7 @@ void gpg_check_access_ins() {
return; return;
case INS_CHANGE_REFERENCE_DATA: case INS_CHANGE_REFERENCE_DATA:
if (gpg_is_verified(ID_PW1) || gpg_is_verified(ID_RC)) { return;
return;
}
break;
case INS_RESET_RETRY_COUNTER: case INS_RESET_RETRY_COUNTER:
if (gpg_is_verified(ID_PW3) || gpg_is_verified(ID_RC)) { if (gpg_is_verified(ID_PW3) || gpg_is_verified(ID_RC)) {
@ -60,7 +60,15 @@ void gpg_check_access_ins() {
break; break;
case INS_PSO: case INS_PSO:
if (gpg_is_verified(ID_PW1) || gpg_is_verified(ID_PW2)) { if ((ref == 0x9e9a) && gpg_is_verified(ID_PW1)) {
//pso:sign
if (N_gpg_pstate->PW_status[0] == 0) {
gpg_set_pin_verified(ID_PW1,0);
}
return;
}
if ((ref == 0x8086 ) && gpg_is_verified(ID_PW2)) {
//pso:dec
return; return;
} }
break; break;
@ -132,7 +140,7 @@ void gpg_check_access_read_DO() {
//PW1 //PW1
case 0x0103: case 0x0103:
if (gpg_is_verified(ID_PW1)) { if (gpg_is_verified(ID_PW2)) {
return; return;
} }
break; break;
@ -158,7 +166,7 @@ void gpg_check_access_write_DO() {
case 0x0101: case 0x0101:
case 0x0103: case 0x0103:
case 0x01F2: case 0x01F2:
if (gpg_is_verified(ID_PW1)) { if (gpg_is_verified(ID_PW2)) {
return; return;
} }
break; break;

View File

@ -169,7 +169,6 @@ int gpg_apdu_gen() {
(keygpg->attributes.value[0] == 19) || (keygpg->attributes.value[0] == 19) ||
(keygpg->attributes.value[0] == 22) ){ (keygpg->attributes.value[0] == 22) ){
unsigned int curve,keepprivate; unsigned int curve,keepprivate;
unsigned char *d;
keepprivate = 0; keepprivate = 0;
curve = gpg_oid2curve(keygpg->attributes.value+1, keygpg->attributes.length-1); curve = gpg_oid2curve(keygpg->attributes.value+1, keygpg->attributes.length-1);
if ((G_gpg_vstate.io_p2 == 0x01) | (G_gpg_vstate.seed_mode)) { if ((G_gpg_vstate.io_p2 == 0x01) | (G_gpg_vstate.seed_mode)) {

View File

@ -239,10 +239,10 @@ int gpg_install(unsigned char app_state) {
G_gpg_vstate.work.io_buffer[7] = app_state; G_gpg_vstate.work.io_buffer[7] = app_state;
gpg_nvm_write(N_gpg_pstate->histo, G_gpg_vstate.work.io_buffer, sizeof(C_default_Histo)); gpg_nvm_write(N_gpg_pstate->histo, G_gpg_vstate.work.io_buffer, sizeof(C_default_Histo));
//AID (TODO: set serial) //AID
os_memmove(G_gpg_vstate.work.io_buffer, C_default_AID, sizeof(C_default_AID)); os_memmove(G_gpg_vstate.work.io_buffer, C_default_AID, sizeof(C_default_AID));
cx_rng(G_gpg_vstate.work.io_buffer+10, 4); cx_rng(G_gpg_vstate.work.io_buffer+10, 4);
G_gpg_vstate.work.io_buffer[13] &= 0x07; G_gpg_vstate.work.io_buffer[13] &= ~0x07;
gpg_nvm_write(N_gpg_pstate->AID, &G_gpg_vstate.work.io_buffer, sizeof(C_default_AID)); gpg_nvm_write(N_gpg_pstate->AID, &G_gpg_vstate.work.io_buffer, sizeof(C_default_AID));
if (app_state == STATE_ACTIVATE) { if (app_state == STATE_ACTIVATE) {

View File

@ -188,6 +188,9 @@ const bagl_element_t* ui_idle_main_preprocessor(const ux_menu_entry_t* entry, ba
/* ------------------------------- Helpers UX ------------------------------- */ /* ------------------------------- Helpers UX ------------------------------- */
void ui_CCID_reset(void) {
//INSERT CODE HERE TO REMOVE/INSERT THE TOKEN
}
void ui_info(const char* msg1, const char* msg2, const void *menu_display, unsigned int entry) { void ui_info(const char* msg1, const char* msg2, const void *menu_display, unsigned int entry) {
ux_menu_entry_t ui_dogsays[2] = { ux_menu_entry_t ui_dogsays[2] = {
@ -436,6 +439,7 @@ void ui_idle_sub_reset_action(unsigned int value) {
magic[0] = 0; magic[1] = 0; magic[2] = 0; magic[3] = 0; magic[0] = 0; magic[1] = 0; magic[2] = 0; magic[3] = 0;
gpg_nvm_write(N_gpg_pstate->magic, magic, 4); gpg_nvm_write(N_gpg_pstate->magic, magic, 4);
gpg_init(); gpg_init();
ui_CCID_reset();
ui_idle_main_display(0); ui_idle_main_display(0);
} }
@ -460,7 +464,7 @@ const ux_menu_entry_t ui_idle_sub_slot[] = {
{NULL, ui_idle_sub_slot_action, 2, NULL, "", NULL, 0, 0}, {NULL, ui_idle_sub_slot_action, 2, NULL, "", NULL, 0, 0},
{NULL, ui_idle_sub_slot_action, 3, NULL, "", NULL, 0, 0}, {NULL, ui_idle_sub_slot_action, 3, NULL, "", NULL, 0, 0},
{NULL, ui_idle_sub_slot_action, 128, NULL, "Set Default", NULL, 0, 0}, {NULL, ui_idle_sub_slot_action, 128, NULL, "Set Default", NULL, 0, 0},
{NULL, ui_idle_main_display, 1, &C_badge_back, "Back", NULL, 61, 40}, {NULL, ui_idle_main_display, 1, &C_badge_back, "Back", NULL, 61, 40},
UX_MENU_END UX_MENU_END
}; };
void ui_idle_sub_slot_display(unsigned int value) { void ui_idle_sub_slot_display(unsigned int value) {
@ -496,9 +500,11 @@ void ui_idle_sub_slot_action(unsigned int value) {
} }
else { else {
s = (unsigned char)(value-1); s = (unsigned char)(value-1);
G_gpg_vstate.slot = s; if (s!= G_gpg_vstate.slot) {
G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot]; G_gpg_vstate.slot = s;
G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot];
ui_CCID_reset();
}
} }
// redisplay first entry of the idle menu // redisplay first entry of the idle menu
ui_idle_sub_slot_display(value); ui_idle_sub_slot_display(value);
@ -547,7 +553,7 @@ const bagl_element_t* ui_idle_main_preprocessor(const ux_menu_entry_t* entry, ba
serial = (N_gpg_pstate->AID[10] << 24) | serial = (N_gpg_pstate->AID[10] << 24) |
(N_gpg_pstate->AID[11] << 16) | (N_gpg_pstate->AID[11] << 16) |
(N_gpg_pstate->AID[12] << 8) | (N_gpg_pstate->AID[12] << 8) |
(N_gpg_pstate->AID[13]); (N_gpg_pstate->AID[13] |(G_gpg_vstate.slot+1));
os_memset(G_gpg_vstate.menu, 0, sizeof(G_gpg_vstate.menu)); os_memset(G_gpg_vstate.menu, 0, sizeof(G_gpg_vstate.menu));
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "< User: %s / SLOT: %d / Serial: %x >", snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "< User: %s / SLOT: %d / Serial: %x >",
name, G_gpg_vstate.slot+1, serial); name, G_gpg_vstate.slot+1, serial);
@ -693,38 +699,44 @@ __attribute__((section(".boot"))) int main(void) {
// ensure exception will work as planned // ensure exception will work as planned
os_boot(); os_boot();
UX_INIT(); for(;;) {
UX_INIT();
BEGIN_TRY { BEGIN_TRY {
TRY { TRY {
//start communication with MCU //start communication with MCU
io_seproxyhal_init(); io_seproxyhal_init();
USB_CCID_power(1); USB_CCID_power(1);
//set up //set up
gpg_init(); gpg_init();
//set up initial screen //set up initial screen
ui_idle_init(); ui_idle_init();
//start the application //start the application
//the first exchange will: //the first exchange will:
// - display the initial screen // - display the initial screen
// - send the ATR // - send the ATR
// - receive the first command // - receive the first command
gpg_main(); gpg_main();
} }
CATCH_OTHER(e) { CATCH(EXCEPTION_IO_RESET) {
} // reset IO and UX
FINALLY { continue;
}
CATCH_ALL {
break;
}
FINALLY {
}
} }
END_TRY;
} }
END_TRY;
app_exit(); app_exit();
} }

View File

@ -35,16 +35,16 @@ static gpg_pin_t *gpg_get_pin(int id) {
static void gpg_set_verified(int id, int verified) { void gpg_set_pin_verified(int id, int verified) {
G_gpg_vstate.verified_pin[id] = verified; G_gpg_vstate.verified_pin[id] = verified;
} }
static int gpg_check_pin(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) { static void gpg_check_pin(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
cx_sha256_t sha256; cx_sha256_t sha256;
unsigned int counter; unsigned int counter;
if (pin->counter == 0) { if (pin->counter == 0) {
return -1; THROW(SW_PIN_BLOCKED);
} }
counter = pin->counter-1; counter = pin->counter-1;
@ -53,12 +53,11 @@ static int gpg_check_pin(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
cx_sha256_init(&sha256); cx_sha256_init(&sha256);
cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, NULL); cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, NULL);
if (os_memcmp(sha256.acc, pin->value, 32)) { if (os_memcmp(sha256.acc, pin->value, 32)) {
return 0; THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
} }
counter = 3; counter = 3;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int)); gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
return 1;
} }
static void gpg_set_pin(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) { static void gpg_set_pin(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
@ -102,8 +101,6 @@ int gpg_is_pin_blocked(int id) {
} }
/* @return: 1 verified /* @return: 1 verified
* 0 not verified * 0 not verified
* -1 blocked * -1 blocked
@ -111,32 +108,40 @@ int gpg_is_pin_blocked(int id) {
int gpg_apdu_verify(int id) { int gpg_apdu_verify(int id) {
gpg_pin_t *pin; gpg_pin_t *pin;
gpg_set_verified(id,0);
pin = gpg_get_pin(id); pin = gpg_get_pin(id);
if (gpg_check_pin(pin, if (pin == NULL) {
G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset, THROW(SW_WRONG_DATA);
G_gpg_vstate.io_lc)) {
gpg_set_verified(id,1);
gpg_io_discard(1);
return SW_OK;
} }
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
return 0; gpg_set_pin_verified(id,0);
if (gpg_is_pin_blocked(id)) {
THROW(SW_PIN_BLOCKED);
return 0;
}
gpg_check_pin(pin,
G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset,
G_gpg_vstate.io_length);
gpg_set_pin_verified(id,1);
gpg_io_discard(1);
return SW_OK;
} }
int gpg_apdu_change_ref_data(int id) { int gpg_apdu_change_ref_data(int id) {
gpg_pin_t *pin; gpg_pin_t *pin;
int len, newlen; int len, newlen;
gpg_set_verified(id,0);
pin = gpg_get_pin(id); pin = gpg_get_pin(id);
if (pin == NULL) { if (pin == NULL) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
} }
gpg_set_pin_verified(id,0);
// --- RC pin --- // --- RC pin ---
if (id == ID_RC) { if (id == ID_RC) {
newlen = G_gpg_vstate.io_lc; newlen = G_gpg_vstate.io_length;
if (newlen == 0) { if (newlen == 0) {
gpg_nvm_write(pin, NULL, sizeof(gpg_pin_t)); gpg_nvm_write(pin, NULL, sizeof(gpg_pin_t));
@ -154,32 +159,32 @@ int gpg_apdu_change_ref_data(int id) {
} }
// --- PW1/PW3 pin --- // --- PW1/PW3 pin ---
if (gpg_is_pin_blocked(id)) {
THROW(SW_PIN_BLOCKED);
return 0;
}
//avoid any-overflow whitout giving info //avoid any-overflow whitout giving info
if (pin->length > G_gpg_vstate.io_lc) { if (pin->length > G_gpg_vstate.io_length) {
len = G_gpg_vstate.io_lc; len = G_gpg_vstate.io_length;
} else { } else {
len = pin->length; len = pin->length;
} }
if (gpg_check_pin(pin, gpg_check_pin(pin,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
len)) { len);
newlen = G_gpg_vstate.io_lc-len; newlen = G_gpg_vstate.io_length-len;
if ( (newlen > GPG_MAX_PW_LENGTH) || if ( (newlen > GPG_MAX_PW_LENGTH) ||
((id == ID_PW1) && (newlen < 6)) || ((id == ID_PW1) && (newlen < 6)) ||
((id == ID_PW3) && (newlen < 8)) ) { ((id == ID_PW3) && (newlen < 8)) ) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
}
gpg_set_pin(pin,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+len,
newlen);
gpg_io_discard(1);
return SW_OK;
} }
THROW(SW_SECURITY_STATUS_NOT_SATISFIED); gpg_set_pin(pin,
return 0.; G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+len,
newlen);
gpg_io_discard(1);
return SW_OK;
} }
int gpg_apdu_reset_retry_counter() { int gpg_apdu_reset_retry_counter() {
@ -194,21 +199,19 @@ int gpg_apdu_reset_retry_counter() {
THROW(SW_SECURITY_STATUS_NOT_SATISFIED); THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
} }
rc_len = 0; rc_len = 0;
pw1_len = G_gpg_vstate.io_lc; pw1_len = G_gpg_vstate.io_length;
} else { } else {
pin_rc = gpg_get_pin(ID_RC); pin_rc = gpg_get_pin(ID_RC);
//avoid any-overflow whitout giving info //avoid any-overflow whitout giving info
if (pin_rc->length > G_gpg_vstate.io_lc) { if (pin_rc->length > G_gpg_vstate.io_length) {
rc_len = G_gpg_vstate.io_lc; rc_len = G_gpg_vstate.io_length;
} else { } else {
rc_len = pin_rc->length; rc_len = pin_rc->length;
} }
pw1_len = G_gpg_vstate.io_lc-rc_len; pw1_len = G_gpg_vstate.io_length-rc_len;
if (!gpg_check_pin(pin_rc, gpg_check_pin(pin_rc,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
rc_len)) { rc_len);
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
}
} }
if ((pw1_len > GPG_MAX_PW_LENGTH) ||(pw1_len < 6)) { if ((pw1_len > GPG_MAX_PW_LENGTH) ||(pw1_len < 6)) {
@ -219,5 +222,4 @@ int gpg_apdu_reset_retry_counter() {
pw1_len); pw1_len);
gpg_io_discard(1); gpg_io_discard(1);
return SW_OK; return SW_OK;
} }

View File

@ -76,7 +76,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
if ((sigkey->attributes.value[0] == 19) || if ((sigkey->attributes.value[0] == 19) ||
(sigkey->attributes.value[0] == 22)) { (sigkey->attributes.value[0] == 22)) {
cx_ecfp_private_key_t *key; cx_ecfp_private_key_t *key;
unsigned int sz,i,j,rs_len; unsigned int sz,i,rs_len;
unsigned char *rs; unsigned char *rs;
key = &sigkey->key.ecfp256; key = &sigkey->key.ecfp256;
@ -128,7 +128,6 @@ static int gpg_sign(gpg_key_t *sigkey) {
int gpg_apdu_pso(unsigned int pso) { int gpg_apdu_pso(unsigned int pso) {
unsigned int t,l,ksz; unsigned int t,l,ksz;
unsigned int hid,oidlen;
switch(pso) { switch(pso) {
// --- PSO:CDS --- // --- PSO:CDS ---
case 0x9e9a: { case 0x9e9a: {

View File

@ -164,17 +164,17 @@ typedef struct gpg_nv_state_s gpg_nv_state_t;
struct gpg_v_state_s { struct gpg_v_state_s {
/* app state */ /* app state */
unsigned char selected; unsigned char selected;
unsigned char slot; /* DO 01F2 */ unsigned char slot; /* DO 01F2 */
gpg_key_slot_t *kslot; gpg_key_slot_t *kslot;
unsigned char seed_mode; unsigned char seed_mode;
/* io state*/ /* io state*/
unsigned char io_cla; unsigned char io_cla;
unsigned char io_ins; unsigned char io_ins;
unsigned char io_p1; unsigned char io_p1;
unsigned char io_p2; unsigned char io_p2;
unsigned char io_lc; unsigned char io_lc;
unsigned char io_le; unsigned char io_le;
unsigned short io_length; unsigned short io_length;
unsigned short io_offset; unsigned short io_offset;
unsigned short io_mark; unsigned short io_mark;
@ -207,7 +207,7 @@ struct gpg_v_state_s {
cx_sha3_t sha3; cx_sha3_t sha3;
cx_sha256_t sha256; cx_sha256_t sha256;
}; };
} md ; } md;
} work; } work;
/* data state */ /* data state */
@ -311,6 +311,7 @@ typedef struct gpg_v_state_s gpg_v_state_t;
#define SW_SECURITY_STATUS_NOT_SATISFIED 0x6982 #define SW_SECURITY_STATUS_NOT_SATISFIED 0x6982
#define SW_FILE_INVALID 0x6983 #define SW_FILE_INVALID 0x6983
#define SW_PIN_BLOCKED 0x6983
#define SW_DATA_INVALID 0x6984 #define SW_DATA_INVALID 0x6984
#define SW_CONDITIONS_NOT_SATISFIED 0x6985 #define SW_CONDITIONS_NOT_SATISFIED 0x6985
#define SW_COMMAND_NOT_ALLOWED 0x6986 #define SW_COMMAND_NOT_ALLOWED 0x6986