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

154
Makefile
View File

@ -13,14 +13,18 @@
# limitations under the License.
#
#extract TARGET_ID from the SDK to allow for makefile choices
APPNAME = "OpenPGP"
APPVERSION = "1.0RC1"
TARGET_ID = 0x31100002
$(info TARGET_ID=$(TARGET_ID))
ifeq ($(BOLOS_SDK),)
$(error Environment variable BOLOS_SDK is not set)
endif
include $(BOLOS_SDK)/Makefile.defines
APP_LOAD_PARAMS=--appFlags 0 --path "2152157255" --curve secp256k1
LOADFLAGS = --params --appVersion $(APPVERSION)
APPNAME = "OpenPGP"
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
@ -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
@ -66,111 +48,37 @@ DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME)
##############
# Compiler #
##############
GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/
CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin
CC := $(CLANGPATH)/clang
#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 += -O0 -gdwarf-2 -gstrict-dwarf
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
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
LD := $(GCCPATH)arm-none-eabi-gcc
#LDFLAGS += -O0 -gdwarf-2 -gstrict-dwarf
LDFLAGS += -O3 -Os
LDLIBS += -lm -lgcc -lc
#LDLIBS += -Wl,--end-group
# -mno-unaligned-access
#-pg --coverage
# import rules to compile glyphs(/pone)
include $(BOLOS_SDK)/Makefile.glyphs
### 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))))))
APP_SOURCE_PATH += src
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
ifeq ($(filter clean,$(MAKECMDGOALS)),)
-include $(DEPEND_FILES)
endif
clean:
rm -fr obj bin debug dep
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)
load: all
python -m ledgerblue.loadApp $(APP_LOAD_PARAMS)
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
@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)
# import generic rules from the sdk
include $(BOLOS_SDK)/Makefile.rules
dep/%.d: %.c Makefile
@echo "[DEP] $@"
@mkdir -p dep
$(call log,$(call dep_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@))
#add dependency on custom makefile filename
dep/%.d: %.c Makefile.genericwallet
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 };
#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,

View File

@ -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

View File

@ -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 ---- */

View File

@ -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;

View File

@ -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;
@ -36,10 +39,7 @@ void gpg_check_access_ins() {
return;
case INS_CHANGE_REFERENCE_DATA:
if (gpg_is_verified(ID_PW1) || gpg_is_verified(ID_RC)) {
return;
}
break;
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;

View File

@ -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)) {

View File

@ -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) {

View File

@ -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);
}
@ -496,9 +500,11 @@ void ui_idle_sub_slot_action(unsigned int value) {
}
else {
s = (unsigned char)(value-1);
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,6 +699,7 @@ __attribute__((section(".boot"))) int main(void) {
// ensure exception will work as planned
os_boot();
for(;;) {
UX_INIT();
BEGIN_TRY {
@ -718,13 +725,18 @@ __attribute__((section(".boot"))) int main(void) {
// - receive the first command
gpg_main();
}
CATCH_OTHER(e) {
CATCH(EXCEPTION_IO_RESET) {
// reset IO and UX
continue;
}
CATCH_ALL {
break;
}
FINALLY {
}
}
END_TRY;
}
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;
}
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,
if (pin == NULL) {
THROW(SW_WRONG_DATA);
}
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_lc)) {
gpg_set_verified(id,1);
G_gpg_vstate.io_length);
gpg_set_pin_verified(id,1);
gpg_io_discard(1);
return SW_OK;
}
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
return 0;
}
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,19 +159,22 @@ 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,
gpg_check_pin(pin,
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) ||
((id == ID_PW1) && (newlen < 6)) ||
((id == ID_PW3) && (newlen < 8)) ) {
@ -178,9 +186,6 @@ int gpg_apdu_change_ref_data(int id) {
gpg_io_discard(1);
return SW_OK;
}
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
return 0.;
}
int gpg_apdu_reset_retry_counter() {
gpg_pin_t *pin_pw1;
@ -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,
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)) {
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
}
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;
}

View File

@ -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: {

View File

@ -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