From b0d13ad6d55b6e6b6ba1674fc17ef327af14ddc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Mesnil?= Date: Tue, 28 Mar 2017 19:24:02 +0200 Subject: [PATCH] 1.0 RC2 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 --- Makefile | 158 ++++++++------------------------------ glyphs/badge_back.gif | Bin 0 -> 74 bytes glyphs/icon_dashboard.gif | Bin 0 -> 1133 bytes icon_pgp.gif | Bin 90 -> 88 bytes src/glyphs.c | 14 ---- src/glyphs.h | 15 ---- src/gpg_api.h | 1 + src/gpg_data.c | 3 +- src/gpg_dispatch.c | 24 ++++-- src/gpg_gen.c | 1 - src/gpg_init.c | 4 +- src/gpg_main.c | 74 ++++++++++-------- src/gpg_pin.c | 98 +++++++++++------------ src/gpg_pso.c | 3 +- src/gpg_types.h | 21 ++--- 15 files changed, 159 insertions(+), 257 deletions(-) create mode 100644 glyphs/badge_back.gif create mode 100644 glyphs/icon_dashboard.gif diff --git a/Makefile b/Makefile index 6e91ff0..c6c8c50 100644 --- a/Makefile +++ b/Makefile @@ -13,14 +13,18 @@ # limitations under the License. # -#extract TARGET_ID from the SDK to allow for makefile choices +ifeq ($(BOLOS_SDK),) +$(error Environment variable BOLOS_SDK is not set) +endif +include $(BOLOS_SDK)/Makefile.defines + APPNAME = "OpenPGP" -APPVERSION = "1.0RC1" -TARGET_ID = 0x31100002 -$(info TARGET_ID=$(TARGET_ID)) +APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_LOAD_PARAMS) -APP_LOAD_PARAMS=--appFlags 0 --path "2152157255" --curve secp256k1 -LOADFLAGS = --params --appVersion $(APPVERSION) +APPVERSION_M=1 +APPVERSION_N=0 +APPVERSION_P=RC2 +APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) ICONNAME=icon_pgp.gif @@ -28,33 +32,11 @@ ICONNAME=icon_pgp.gif ################ # Default rule # ################ - 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 # ############ -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 += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF @@ -64,113 +46,39 @@ DEFINES += HAVE_USB_CLASS_CCID DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) ############## -# Compiler # +# Compiler # ############## -GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/ -CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin -CC := $(CLANGPATH)/clang - -CFLAGS := -CFLAGS += -gdwarf-2 -gstrict-dwarf -#CFLAGS += -O0 -#CFLAGS += -O0 -g3 -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 -#CFLAGS += -finline-limit-0 -funsigned-bitfields - -AS := $(GCCPATH)/arm-none-eabi-gcc -AFLAGS += -ggdb2 -O3 -Os -mcpu=cortex-m0 -fno-common -mtune=cortex-m0 - -# 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 += -Wl,--end-group -# -mno-unaligned-access -#-pg --coverage - -### computed variables -VPATH := $(dir $(SOURCE_FILES)) -OBJECT_FILES := $(sort $(addprefix obj/, $(addsuffix .o, $(basename $(notdir $(SOURCE_FILES)))))) -DEPEND_FILES := $(sort $(addprefix dep/, $(addsuffix .d, $(basename $(notdir $(SOURCE_FILES)))))) +#GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/ +#CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/ +CC := $(CLANGPATH)clang -ifeq ($(filter clean,$(MAKECMDGOALS)),) --include $(DEPEND_FILES) -endif +#CFLAGS += -O0 -gdwarf-2 -gstrict-dwarf +CFLAGS += -O3 -Os -clean: - rm -fr obj bin debug dep +AS := $(GCCPATH)arm-none-eabi-gcc -prepare: - @mkdir -p bin obj debug dep +LD := $(GCCPATH)arm-none-eabi-gcc +#LDFLAGS += -O0 -gdwarf-2 -gstrict-dwarf +LDFLAGS += -O3 -Os +LDLIBS += -lm -lgcc -lc -.SECONDEXPANSION: +# import rules to compile glyphs(/pone) +include $(BOLOS_SDK)/Makefile.glyphs -# default is not to display make commands -log = $(if $(strip $(VERBOSE)),$1,@$1) +### computed variables +APP_SOURCE_PATH += src +SDK_SOURCE_PATH += lib_stusb lib_stusb_impl -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) +load: all + python -m ledgerblue.loadApp $(APP_LOAD_PARAMS) delete: - python -m ledgerblue.deleteApp --targetId $(TARGET_ID) --appName $(APPNAME) - -bin/$(PROG): $(OBJECT_FILES) $(BOLOS_SDK)/script.ld - @echo "[LINK] $@" - $(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 - @echo "[DEP] $@" - @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 + python -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS) -# 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) +# import generic rules from the sdk +include $(BOLOS_SDK)/Makefile.rules -as_cmdline = $(AS) -c $(AFLAGS) $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3) +#add dependency on custom makefile filename +dep/%.d: %.c Makefile.genericwallet -### END GCC COMPILER RULES diff --git a/glyphs/badge_back.gif b/glyphs/badge_back.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2a7e6d4fa290e4875992d4024e988d14b91df26 GIT binary patch literal 74 zcmZ?wbhEHbh+i z#(Mch>H3D2mX`VkM*2oZx|Z5PF?(>IEf;+ybD@E~!PCWvMA{Mftf3V2@j6;&zJ# zPV=C8Q*gV*5~p5$pkwqw(Tfz_Fd<+X0x{u<7s!Dp|I|ESnlAz-ZpQ!r{{H#>>*tT} z-@bnN{ORL|_wU}mdHw3;i|5atK6(7;;e-44?%uh5>*kH?*REcZ;0$^0LyB;-bQW{Jh+p?5xa; z^t9BJ|cQ;oTXD3GodplbjYb#3&b2C#D zVqwaWPR5VIe^Qem-6vZZ1v^b~aWPW+p~p z3GtH!SWYl7=zs`N*}=f1)WgepeBpkH7I)L>0efyf`cv6&*0!WWPeHu$lGW7Enz_D= G4Aua{vX6rR literal 0 HcmV?d00001 diff --git a/icon_pgp.gif b/icon_pgp.gif index 1343aece53d31f647518d060b6a2789e8e334162..857cfbfa6ac03f1f45d1b4ea909fe0510a3cb9d9 100644 GIT binary patch literal 88 zcmZ?wbhEHb6krfwSjfl#1pi?`@h1x-7XuT64oDOv&%mVF(!cWHnioDXioOvacQ<@z hGrOkTdv|(jd)Kr8&3XDKPhEYxF45zgT_gj8H2{KnBBB5Q literal 90 zcmZ?wbhEHb6krfwSjYeZ|Ns97(+r9~Ss1w(m>6_GT#!5ilXi>j%;Vc7W_7;_y`?k7 lp}Z#bL5b$Fmj$6+H8->m<*wc^H|y}kn#X&qtt7b^tN|n)9bo_f diff --git a/src/glyphs.c b/src/glyphs.c index 1b57d85..4e68e9a 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -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 }; #endif // OS_IO_SEPROXYHAL #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[] = { 0x00000000, diff --git a/src/glyphs.h b/src/glyphs.h index aaeebf8..b94b06b 100644 --- a/src/glyphs.h +++ b/src/glyphs.h @@ -13,21 +13,6 @@ extern const bagl_icon_details_t C_badge_back; #endif // GLYPH_badge_back_BPP #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 #define GLYPH_icon_dashboard_WIDTH 14 #define GLYPH_icon_dashboard_HEIGHT 14 diff --git a/src/gpg_api.h b/src/gpg_api.h index 161b4af..33e25e3 100644 --- a/src/gpg_api.h +++ b/src/gpg_api.h @@ -42,6 +42,7 @@ int gpg_apdu_reset_retry_counter(void) ; int gpg_oid2curve(unsigned char* oid, unsigned int len); int gpg_is_pin_verified(int id); int gpg_is_pin_blocked(int id); +void gpg_set_pin_verified(int id, int verified); /* ----------------------------------------------------------------------- */ /* --- IO ---- */ diff --git a/src/gpg_data.c b/src/gpg_data.c index 9eb710d..a4ada98 100644 --- a/src/gpg_data.c +++ b/src/gpg_data.c @@ -69,6 +69,7 @@ int gpg_apdu_get_data(unsigned int ref) { /* Full Application identifier */ case 0x004F: 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; /* Historical bytes, */ case 0x5F52: @@ -261,13 +262,13 @@ 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; nvm_write(&N_gpg_pstate->AID[10], &G_gpg_vstate.work.io_buffer[G_gpg_vstate.io_offset], 4); sw = SW_OK; break; /* ----------------- Extended Header list -----------------*/ case 0x3FFF: { - void *pkey,*vkey; unsigned int len_e,len_p,len_q; unsigned int endof,ksz,reset_cnt; gpg_key_t *keygpg; diff --git a/src/gpg_dispatch.c b/src/gpg_dispatch.c index 74a6eb5..4a63297 100644 --- a/src/gpg_dispatch.c +++ b/src/gpg_dispatch.c @@ -25,6 +25,9 @@ int gpg_is_verified(id) { } 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) { case INS_SELECT: return; @@ -35,11 +38,8 @@ void gpg_check_access_ins() { case INS_VERIFY: return; - case INS_CHANGE_REFERENCE_DATA: - if (gpg_is_verified(ID_PW1) || gpg_is_verified(ID_RC)) { - return; - } - break; + case INS_CHANGE_REFERENCE_DATA: + return; case INS_RESET_RETRY_COUNTER: if (gpg_is_verified(ID_PW3) || gpg_is_verified(ID_RC)) { @@ -60,7 +60,15 @@ void gpg_check_access_ins() { break; 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; } break; @@ -132,7 +140,7 @@ void gpg_check_access_read_DO() { //PW1 case 0x0103: - if (gpg_is_verified(ID_PW1)) { + if (gpg_is_verified(ID_PW2)) { return; } break; @@ -158,7 +166,7 @@ void gpg_check_access_write_DO() { case 0x0101: case 0x0103: case 0x01F2: - if (gpg_is_verified(ID_PW1)) { + if (gpg_is_verified(ID_PW2)) { return; } break; diff --git a/src/gpg_gen.c b/src/gpg_gen.c index d052c34..703d27f 100644 --- a/src/gpg_gen.c +++ b/src/gpg_gen.c @@ -169,7 +169,6 @@ int gpg_apdu_gen() { (keygpg->attributes.value[0] == 19) || (keygpg->attributes.value[0] == 22) ){ unsigned int curve,keepprivate; - unsigned char *d; keepprivate = 0; curve = gpg_oid2curve(keygpg->attributes.value+1, keygpg->attributes.length-1); if ((G_gpg_vstate.io_p2 == 0x01) | (G_gpg_vstate.seed_mode)) { diff --git a/src/gpg_init.c b/src/gpg_init.c index 7861df4..cb042d9 100644 --- a/src/gpg_init.c +++ b/src/gpg_init.c @@ -239,10 +239,10 @@ int gpg_install(unsigned char 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)); - //AID (TODO: set serial) + //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); - 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)); if (app_state == STATE_ACTIVATE) { diff --git a/src/gpg_main.c b/src/gpg_main.c index f309bf1..6458a10 100644 --- a/src/gpg_main.c +++ b/src/gpg_main.c @@ -188,6 +188,9 @@ const bagl_element_t* ui_idle_main_preprocessor(const ux_menu_entry_t* entry, ba /* ------------------------------- 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) { 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; gpg_nvm_write(N_gpg_pstate->magic, magic, 4); gpg_init(); + ui_CCID_reset(); 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, 3, NULL, "", 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 }; void ui_idle_sub_slot_display(unsigned int value) { @@ -496,9 +500,11 @@ void ui_idle_sub_slot_action(unsigned int value) { } else { s = (unsigned char)(value-1); - G_gpg_vstate.slot = s; - G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot]; - + if (s!= 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 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) | (N_gpg_pstate->AID[11] << 16) | (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)); snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "< User: %s / SLOT: %d / Serial: %x >", name, G_gpg_vstate.slot+1, serial); @@ -693,38 +699,44 @@ __attribute__((section(".boot"))) int main(void) { // ensure exception will work as planned os_boot(); - UX_INIT(); + for(;;) { + UX_INIT(); - BEGIN_TRY { - TRY { + BEGIN_TRY { + TRY { - //start communication with MCU - io_seproxyhal_init(); + //start communication with MCU + io_seproxyhal_init(); - USB_CCID_power(1); - - //set up - gpg_init(); + USB_CCID_power(1); - //set up initial screen - ui_idle_init(); - - - - //start the application - //the first exchange will: - // - display the initial screen - // - send the ATR - // - receive the first command - gpg_main(); - } - CATCH_OTHER(e) { - } - FINALLY { + //set up + gpg_init(); + + //set up initial screen + ui_idle_init(); + + + + //start the application + //the first exchange will: + // - display the initial screen + // - send the ATR + // - receive the first command + gpg_main(); + } + CATCH(EXCEPTION_IO_RESET) { + // reset IO and UX + continue; + } + CATCH_ALL { + break; + } + FINALLY { + } } + END_TRY; } - END_TRY; - app_exit(); } diff --git a/src/gpg_pin.c b/src/gpg_pin.c index c108fde..b7f48fb 100644 --- a/src/gpg_pin.c +++ b/src/gpg_pin.c @@ -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; } -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; unsigned int counter; if (pin->counter == 0) { - return -1; + THROW(SW_PIN_BLOCKED); } 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_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, NULL); if (os_memcmp(sha256.acc, pin->value, 32)) { - return 0; + THROW(SW_SECURITY_STATUS_NOT_SATISFIED); } counter = 3; 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) { @@ -102,8 +101,6 @@ int gpg_is_pin_blocked(int id) { } - - /* @return: 1 verified * 0 not verified * -1 blocked @@ -111,32 +108,40 @@ int gpg_is_pin_blocked(int id) { int gpg_apdu_verify(int id) { gpg_pin_t *pin; - gpg_set_verified(id,0); pin = gpg_get_pin(id); - if (gpg_check_pin(pin, - G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset, - G_gpg_vstate.io_lc)) { - gpg_set_verified(id,1); - gpg_io_discard(1); - return SW_OK; + if (pin == NULL) { + THROW(SW_WRONG_DATA); } - 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) { gpg_pin_t *pin; int len, newlen; - - gpg_set_verified(id,0); + pin = gpg_get_pin(id); if (pin == NULL) { THROW(SW_WRONG_DATA); } + gpg_set_pin_verified(id,0); + + // --- RC pin --- if (id == ID_RC) { - newlen = G_gpg_vstate.io_lc; + newlen = G_gpg_vstate.io_length; if (newlen == 0) { gpg_nvm_write(pin, NULL, sizeof(gpg_pin_t)); @@ -154,32 +159,32 @@ int gpg_apdu_change_ref_data(int id) { } // --- PW1/PW3 pin --- - + if (gpg_is_pin_blocked(id)) { + THROW(SW_PIN_BLOCKED); + return 0; + } //avoid any-overflow whitout giving info - if (pin->length > G_gpg_vstate.io_lc) { - len = G_gpg_vstate.io_lc; + if (pin->length > G_gpg_vstate.io_length) { + len = G_gpg_vstate.io_length; } else { len = pin->length; } - if (gpg_check_pin(pin, - G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, - len)) { + gpg_check_pin(pin, + G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, + len); - newlen = G_gpg_vstate.io_lc-len; - if ( (newlen > GPG_MAX_PW_LENGTH) || - ((id == ID_PW1) && (newlen < 6)) || - ((id == ID_PW3) && (newlen < 8)) ) { - 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; + newlen = G_gpg_vstate.io_length-len; + if ( (newlen > GPG_MAX_PW_LENGTH) || + ((id == ID_PW1) && (newlen < 6)) || + ((id == ID_PW3) && (newlen < 8)) ) { + THROW(SW_WRONG_DATA); } - THROW(SW_SECURITY_STATUS_NOT_SATISFIED); - return 0.; + gpg_set_pin(pin, + 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() { @@ -194,21 +199,19 @@ int gpg_apdu_reset_retry_counter() { THROW(SW_SECURITY_STATUS_NOT_SATISFIED); } rc_len = 0; - pw1_len = G_gpg_vstate.io_lc; + pw1_len = G_gpg_vstate.io_length; } else { pin_rc = gpg_get_pin(ID_RC); //avoid any-overflow whitout giving info - if (pin_rc->length > G_gpg_vstate.io_lc) { - rc_len = G_gpg_vstate.io_lc; + if (pin_rc->length > G_gpg_vstate.io_length) { + rc_len = G_gpg_vstate.io_length; } else { rc_len = pin_rc->length; } - pw1_len = G_gpg_vstate.io_lc-rc_len; - if (!gpg_check_pin(pin_rc, - G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, - rc_len)) { - THROW(SW_SECURITY_STATUS_NOT_SATISFIED); - } + pw1_len = G_gpg_vstate.io_length-rc_len; + gpg_check_pin(pin_rc, + G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, + rc_len); } if ((pw1_len > GPG_MAX_PW_LENGTH) ||(pw1_len < 6)) { @@ -219,5 +222,4 @@ int gpg_apdu_reset_retry_counter() { pw1_len); gpg_io_discard(1); return SW_OK; - } diff --git a/src/gpg_pso.c b/src/gpg_pso.c index a54b20d..916dc44 100644 --- a/src/gpg_pso.c +++ b/src/gpg_pso.c @@ -76,7 +76,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,j,rs_len; + unsigned int sz,i,rs_len; unsigned char *rs; key = &sigkey->key.ecfp256; @@ -128,7 +128,6 @@ static int gpg_sign(gpg_key_t *sigkey) { int gpg_apdu_pso(unsigned int pso) { unsigned int t,l,ksz; - unsigned int hid,oidlen; switch(pso) { // --- PSO:CDS --- case 0x9e9a: { diff --git a/src/gpg_types.h b/src/gpg_types.h index 332bc9a..99c17b5 100644 --- a/src/gpg_types.h +++ b/src/gpg_types.h @@ -164,17 +164,17 @@ typedef struct gpg_nv_state_s gpg_nv_state_t; struct gpg_v_state_s { /* app state */ unsigned char selected; - unsigned char slot; /* DO 01F2 */ - gpg_key_slot_t *kslot; - unsigned char seed_mode; + unsigned char slot; /* DO 01F2 */ + gpg_key_slot_t *kslot; + unsigned char seed_mode; /* io state*/ - unsigned char io_cla; - unsigned char io_ins; - unsigned char io_p1; - unsigned char io_p2; - unsigned char io_lc; - unsigned char io_le; + unsigned char io_cla; + unsigned char io_ins; + unsigned char io_p1; + unsigned char io_p2; + unsigned char io_lc; + unsigned char io_le; unsigned short io_length; unsigned short io_offset; unsigned short io_mark; @@ -207,7 +207,7 @@ struct gpg_v_state_s { cx_sha3_t sha3; cx_sha256_t sha256; }; - } md ; + } md; } work; /* 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_FILE_INVALID 0x6983 +#define SW_PIN_BLOCKED 0x6983 #define SW_DATA_INVALID 0x6984 #define SW_CONDITIONS_NOT_SATISFIED 0x6985 #define SW_COMMAND_NOT_ALLOWED 0x6986