Fix Signatrure counter:  now incremented
Fix PIN status init: was not correctly initialized
Fix "only once" CDS management: PIN was not invalidated after signing
Change all return 0 by corresponding THROW error code
PIN API refacto
This commit is contained in:
Cédric Mesnil 2017-06-12 14:26:10 +02:00
parent 2e0d755fb6
commit 9dec68f892
13 changed files with 246 additions and 203 deletions

View File

@ -23,7 +23,7 @@ APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_
APPVERSION_M=1 APPVERSION_M=1
APPVERSION_N=0 APPVERSION_N=0
APPVERSION_P=RC6 APPVERSION_P=RC7
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
ICONNAME=icon_pgp.gif ICONNAME=icon_pgp.gif

View File

@ -16,6 +16,7 @@
#ifndef GPG_API_H #ifndef GPG_API_H
#define GPG_API_H #define GPG_API_H
int gpg_oid2curve(unsigned char* oid, unsigned int len);
void gpg_init(void); void gpg_init(void);
void gpg_init_ux(void); void gpg_init_ux(void);
@ -34,17 +35,17 @@ int gpg_apdu_get_challenge(void) ;
int gpg_apdu_select(void) ; int gpg_apdu_select(void) ;
int gpg_apdu_verify(int id) ; int gpg_apdu_verify(void) ;
int gpg_apdu_change_ref_data(int id) ; int gpg_apdu_change_ref_data(void) ;
int gpg_apdu_reset_retry_counter(void) ; int gpg_apdu_reset_retry_counter(void) ;
gpg_pin_t *gpg_pin_get_pin(int id);
int gpg_oid2curve(unsigned char* oid, unsigned int len); int gpg_pin_is_verified(gpg_pin_t *pin);
int gpg_is_pin_verified(int id); int gpg_pin_is_blocked(gpg_pin_t *pin);
int gpg_is_pin_blocked(int id); int gpg_pin_set_verified(gpg_pin_t *pin, int verified);
int gpg_set_pin_verified(int id, int verified); int gpg_pin_check(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len);
int gpg_check_pin(int id, unsigned char *pin_val, unsigned int pin_len); void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len);
void gpg_change_pin(int id, unsigned char *pin_val, unsigned int pin_len); void gpg_pin_sync12(void) ;
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* --- IO ---- */ /* --- IO ---- */

View File

@ -29,7 +29,7 @@ int gpg_apdu_get_challenge() {
} }
if (olen > GPG_EXT_CHALLENGE_LENTH) { if (olen > GPG_EXT_CHALLENGE_LENTH) {
THROW(SW_WRONG_LENGTH); THROW(SW_WRONG_LENGTH);
return 0; return SW_WRONG_LENGTH;
} }
if ((G_gpg_vstate.io_p1&0x82) == 0x82) { if ((G_gpg_vstate.io_p1&0x82) == 0x82) {

View File

@ -654,7 +654,7 @@ int gpg_apdu_put_data(unsigned int ref) {
/* ----------------- RC ----------------- */ /* ----------------- RC ----------------- */
case 0xD3: case 0xD3:
sw = gpg_apdu_change_ref_data(PIN_ID_RC); sw = gpg_apdu_change_ref_data();
break; break;
/* ----------------- UIF ----------------- */ /* ----------------- UIF ----------------- */

View File

@ -20,12 +20,15 @@
#include "gpg_vars.h" #include "gpg_vars.h"
int gpg_is_verified(id) {
return G_gpg_vstate.verified_pin[id] ;
}
void gpg_check_access_ins() { void gpg_check_access_ins() {
unsigned int ref; unsigned int ref;
gpg_pin_t *pin_pw1, *pin_pw2, *pin_pw3, *pin_rc;
pin_pw1 = gpg_pin_get_pin(PIN_ID_PW1);
pin_pw2 = gpg_pin_get_pin(PIN_ID_PW2);
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
pin_rc = gpg_pin_get_pin(PIN_ID_RC);
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ; ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
switch (G_gpg_vstate.io_ins) { switch (G_gpg_vstate.io_ins) {
@ -42,7 +45,7 @@ void gpg_check_access_ins() {
return; return;
case INS_RESET_RETRY_COUNTER: case INS_RESET_RETRY_COUNTER:
if (gpg_is_verified(PIN_ID_PW3) || gpg_is_verified(PIN_ID_RC)) { if (gpg_pin_is_verified(pin_pw3) || gpg_pin_is_verified(pin_rc)) {
return; return;
} }
@ -54,27 +57,27 @@ void gpg_check_access_ins() {
if (G_gpg_vstate.io_p1 == 0x81) { if (G_gpg_vstate.io_p1 == 0x81) {
return; return;
} }
if (gpg_is_verified(PIN_ID_PW3)) { if (gpg_pin_is_verified(pin_pw3)) {
return; return;
} }
break; break;
case INS_PSO: case INS_PSO:
if ((ref == 0x9e9a) && gpg_is_verified(PIN_ID_PW1)) { if ((ref == 0x9e9a) && gpg_pin_is_verified(pin_pw1)) {
//pso:sign //pso:sign
if (N_gpg_pstate->PW_status[0] == 0) { if (N_gpg_pstate->PW_status[0] == 0) {
gpg_set_pin_verified(PIN_ID_PW1,0); gpg_pin_set_verified(pin_pw1, 0);
} }
return; return;
} }
if ((ref == 0x8086 ) && gpg_is_verified(PIN_ID_PW2)) { if ((ref == 0x8086 ) && gpg_pin_is_verified(pin_pw2)) {
//pso:dec //pso:dec
return; return;
} }
break; break;
case INS_INTERNAL_AUTHENTICATE: case INS_INTERNAL_AUTHENTICATE:
if (gpg_is_verified(PIN_ID_PW2)) { if (gpg_pin_is_verified(pin_pw2)) {
return; return;
} }
break; break;
@ -83,7 +86,7 @@ void gpg_check_access_ins() {
return; return;
case INS_TERMINATE_DF: case INS_TERMINATE_DF:
if (gpg_is_pin_verified(PIN_ID_PW3) || gpg_is_pin_blocked(PIN_ID_PW3)) { if (gpg_pin_is_verified(pin_pw3)) {
return; return;
} }
break; break;
@ -96,6 +99,11 @@ void gpg_check_access_ins() {
void gpg_check_access_read_DO() { void gpg_check_access_read_DO() {
unsigned int ref; unsigned int ref;
gpg_pin_t *pin_pw2, *pin_pw3;
pin_pw2 = gpg_pin_get_pin(PIN_ID_PW2);
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ; ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
switch(ref) { switch(ref) {
@ -144,14 +152,14 @@ void gpg_check_access_read_DO() {
//PW1 //PW1
case 0x0103: case 0x0103:
if (gpg_is_verified(PIN_ID_PW2)) { if (gpg_pin_is_verified(pin_pw2)) {
return; return;
} }
break; break;
//PW3 //PW3
case 0x0104: case 0x0104:
if (gpg_is_verified(PIN_ID_PW3)) { if (gpg_pin_is_verified(pin_pw3)) {
return; return;
} }
break; break;
@ -164,15 +172,18 @@ char debugbuff[5];
void gpg_check_access_write_DO() { void gpg_check_access_write_DO() {
unsigned int ref; unsigned int ref;
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ; gpg_pin_t *pin_pw2, *pin_pw3;
pin_pw2 = gpg_pin_get_pin(PIN_ID_PW2);
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
switch(ref) { switch(ref) {
//PW1 //PW1
case 0x0101: case 0x0101:
case 0x0103: case 0x0103:
case 0x01F2: case 0x01F2:
if (gpg_is_verified(PIN_ID_PW2)) { if (gpg_pin_is_verified(pin_pw2)) {
return; return;
} }
break; break;
@ -214,7 +225,7 @@ void gpg_check_access_write_DO() {
case 0x00D6: case 0x00D6:
case 0x00D7: case 0x00D7:
case 0x00D8: case 0x00D8:
if (gpg_is_verified(PIN_ID_PW3)) { if (gpg_pin_is_verified(pin_pw3)) {
return; return;
} }
break; break;
@ -254,7 +265,7 @@ int gpg_dispatch() {
case INS_TERMINATE_DF: case INS_TERMINATE_DF:
gpg_io_discard(0); gpg_io_discard(0);
if (G_gpg_vstate.verified_pin[PIN_ID_PW3] || (N_gpg_pstate->PW3.counter == 0)) { if (gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW3)) || (N_gpg_pstate->PW3.counter == 0)) {
gpg_install(STATE_TERMINATE); gpg_install(STATE_TERMINATE);
return(SW_OK); return(SW_OK);
break; break;
@ -335,17 +346,16 @@ int gpg_dispatch() {
(G_gpg_vstate.io_p2 == 0x82) || (G_gpg_vstate.io_p2 == 0x82) ||
(G_gpg_vstate.io_p2 == 0x83) (G_gpg_vstate.io_p2 == 0x83)
) { ) {
sw = gpg_apdu_verify(G_gpg_vstate.io_p2&0x0F); sw = gpg_apdu_verify();
break; break;
} }
THROW(0x9BF0); THROW(SW_INCORRECT_P1P2);
//THROW(SW_INCORRECT_P1P2);
case INS_CHANGE_REFERENCE_DATA: case INS_CHANGE_REFERENCE_DATA:
if ((G_gpg_vstate.io_p2 == 0x81) || if ((G_gpg_vstate.io_p2 == 0x81) ||
(G_gpg_vstate.io_p2 == 0x83) (G_gpg_vstate.io_p2 == 0x83)
) { ) {
sw = gpg_apdu_change_ref_data(G_gpg_vstate.io_p2&0x0F); sw = gpg_apdu_change_ref_data();
break; break;
} }
THROW(SW_INCORRECT_P1P2); THROW(SW_INCORRECT_P1P2);

View File

@ -69,12 +69,12 @@ int gpg_apdu_gen() {
break; break;
default: default:
THROW(SW_INCORRECT_P1P2); THROW(SW_INCORRECT_P1P2);
return 0; return SW_INCORRECT_P1P2;
} }
if (G_gpg_vstate.io_lc != 2){ if (G_gpg_vstate.io_lc != 2){
THROW(SW_WRONG_LENGTH); THROW(SW_WRONG_LENGTH);
return 0; return SW_WRONG_LENGTH;
} }
gpg_io_fetch_tl(&t,&l); gpg_io_fetch_tl(&t,&l);
@ -96,7 +96,7 @@ int gpg_apdu_gen() {
break; break;
default: default:
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
switch ((G_gpg_vstate.io_p1<<8)|G_gpg_vstate.io_p2) { switch ((G_gpg_vstate.io_p1<<8)|G_gpg_vstate.io_p2) {
@ -210,28 +210,28 @@ int gpg_apdu_gen() {
case 1024/8: case 1024/8:
if (keygpg->key.rsa1024.size == 0) { if (keygpg->key.rsa1024.size == 0) {
THROW (SW_REFERENCED_DATA_NOT_FOUND); THROW (SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa1024.n); gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa1024.n);
break; break;
case 2048/8: case 2048/8:
if (keygpg->key.rsa2048.size == 0) { if (keygpg->key.rsa2048.size == 0) {
THROW (SW_REFERENCED_DATA_NOT_FOUND); THROW (SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa2048.n); gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa2048.n);
break; break;
case 3072/8: case 3072/8:
if (keygpg->key.rsa3072.size == 0) { if (keygpg->key.rsa3072.size == 0) {
THROW (SW_REFERENCED_DATA_NOT_FOUND); THROW (SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa3072.n); gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa3072.n);
break; break;
case 4096/8: case 4096/8:
if (keygpg->key.rsa4096.size == 0) { if (keygpg->key.rsa4096.size == 0) {
THROW (SW_REFERENCED_DATA_NOT_FOUND); THROW (SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa4096.n); gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa4096.n);
break; break;
@ -285,5 +285,5 @@ int gpg_apdu_gen() {
} }
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }

View File

@ -211,6 +211,8 @@ void gpg_init() {
gpg_nvm_write(N_gpg_pstate->magic, (void*)C_MAGIC, sizeof(C_MAGIC)); gpg_nvm_write(N_gpg_pstate->magic, (void*)C_MAGIC, sizeof(C_MAGIC));
os_memset(&G_gpg_vstate, 0, sizeof(gpg_v_state_t)); os_memset(&G_gpg_vstate, 0, sizeof(gpg_v_state_t));
} }
//ensure pin1 and pin2 are sync in case of powerloss
gpg_pin_sync12();
//key conf //key conf
G_gpg_vstate.slot = N_gpg_pstate->config_slot[1]; G_gpg_vstate.slot = N_gpg_pstate->config_slot[1];
G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot]; G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot];
@ -252,16 +254,20 @@ int gpg_install(unsigned char app_state) {
G_gpg_vstate.work.io_buffer[0] = 0x39; G_gpg_vstate.work.io_buffer[0] = 0x39;
gpg_nvm_write(&N_gpg_pstate->sex, G_gpg_vstate.work.io_buffer, 1); gpg_nvm_write(&N_gpg_pstate->sex, G_gpg_vstate.work.io_buffer, 1);
//default PW1: 1 2 3 4 5 6 //default PW1/PW2: 1 2 3 4 5 6
os_memmove(pin.value, C_sha256_PW1, sizeof(C_sha256_PW1)); os_memmove(pin.value, C_sha256_PW1, sizeof(C_sha256_PW1));
pin.length = 6; pin.length = 6;
pin.counter = 3; pin.counter = 3;
pin.ref = PIN_ID_PW1;
gpg_nvm_write(&N_gpg_pstate->PW1, &pin, sizeof(gpg_pin_t)); gpg_nvm_write(&N_gpg_pstate->PW1, &pin, sizeof(gpg_pin_t));
pin.ref = PIN_ID_PW2;
gpg_nvm_write(&N_gpg_pstate->PW2, &pin, sizeof(gpg_pin_t));
//default PW3: 1 2 3 4 5 6 7 8 //default PW3: 1 2 3 4 5 6 7 8
os_memmove(pin.value, C_sha256_PW2, sizeof(C_sha256_PW2)); os_memmove(pin.value, C_sha256_PW2, sizeof(C_sha256_PW2));
pin.length = 8; pin.length = 8;
pin.counter = 3; pin.counter = 3;
pin.ref = PIN_ID_PW3;
gpg_nvm_write(&N_gpg_pstate->PW3, &pin, sizeof(gpg_pin_t)); gpg_nvm_write(&N_gpg_pstate->PW3, &pin, sizeof(gpg_pin_t));
//PWs status //PWs status
@ -269,7 +275,7 @@ int gpg_install(unsigned char app_state) {
G_gpg_vstate.work.io_buffer[1] = GPG_MAX_PW_LENGTH; G_gpg_vstate.work.io_buffer[1] = GPG_MAX_PW_LENGTH;
G_gpg_vstate.work.io_buffer[2] = GPG_MAX_PW_LENGTH; G_gpg_vstate.work.io_buffer[2] = GPG_MAX_PW_LENGTH;
G_gpg_vstate.work.io_buffer[3] = GPG_MAX_PW_LENGTH; G_gpg_vstate.work.io_buffer[3] = GPG_MAX_PW_LENGTH;
gpg_nvm_write(&N_gpg_pstate->config_slot, G_gpg_vstate.work.io_buffer, 4); gpg_nvm_write(&N_gpg_pstate->PW_status, G_gpg_vstate.work.io_buffer, 4);
//config slot //config slot
G_gpg_vstate.work.io_buffer[0] = GPG_KEYS_SLOTS; G_gpg_vstate.work.io_buffer[0] = GPG_KEYS_SLOTS;

View File

@ -42,6 +42,7 @@ void gpg_io_set_offset(unsigned int offset) {
} }
else { else {
THROW(ERROR_IO_OFFSET); THROW(ERROR_IO_OFFSET);
return ;
} }
} }
@ -76,6 +77,7 @@ void gpg_io_clear() {
void gpg_io_hole(unsigned int sz) { void gpg_io_hole(unsigned int sz) {
if ((G_gpg_vstate.io_length + sz) > GPG_IO_BUFFER_LENGTH) { if ((G_gpg_vstate.io_length + sz) > GPG_IO_BUFFER_LENGTH) {
THROW(ERROR_IO_FULL); THROW(ERROR_IO_FULL);
return ;
} }
os_memmove(G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+sz, os_memmove(G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+sz,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
@ -340,7 +342,7 @@ int gpg_io_do(unsigned int io_flags) {
(G_io_apdu_buffer[2] != G_gpg_vstate.io_p1) || (G_io_apdu_buffer[2] != G_gpg_vstate.io_p1) ||
(G_io_apdu_buffer[3] != G_gpg_vstate.io_p2) ) { (G_io_apdu_buffer[3] != G_gpg_vstate.io_p2) ) {
THROW(SW_COMMAND_NOT_ALLOWED); THROW(SW_COMMAND_NOT_ALLOWED);
return 0; return SW_COMMAND_NOT_ALLOWED;
} }
G_gpg_vstate.io_cla = G_io_apdu_buffer[0]; G_gpg_vstate.io_cla = G_io_apdu_buffer[0];
G_gpg_vstate.io_lc = G_io_apdu_buffer[4]; G_gpg_vstate.io_lc = G_io_apdu_buffer[4];

View File

@ -21,11 +21,12 @@
#include "gpg_ux_nanos.h" #include "gpg_ux_nanos.h"
static gpg_pin_t *gpg_get_pin(int id) { gpg_pin_t *gpg_pin_get_pin(int id) {
switch (id) { switch (id) {
case PIN_ID_PW1 : case PIN_ID_PW1 :
case PIN_ID_PW2 :
return &N_gpg_pstate->PW1; return &N_gpg_pstate->PW1;
case PIN_ID_PW2 :
return &N_gpg_pstate->PW2;
case PIN_ID_PW3: case PIN_ID_PW3:
return &N_gpg_pstate->PW3; return &N_gpg_pstate->PW3;
case PIN_ID_RC: case PIN_ID_RC:
@ -36,38 +37,89 @@ static gpg_pin_t *gpg_get_pin(int id) {
static int gpg_pin_get_index(unsigned int id) {
switch (id) {
case PIN_ID_PW1 :
return 1;
case PIN_ID_PW2 :
return 2;
case PIN_ID_PW3 :
return 3;
case PIN_ID_RC :
return 4;
static int gpg_check_pin_internal(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) { }
return -1;
}
void gpg_pin_sync12() {
gpg_pin_t *pin1, *pin2;
pin1 = gpg_pin_get_pin(PIN_ID_PW1);
pin2 = gpg_pin_get_pin(PIN_ID_PW2);
if (os_memcmp(pin1, pin2, sizeof(gpg_pin_t))) {
pin1 = gpg_pin_get_pin(PIN_ID_PW1);
pin2 = gpg_pin_get_pin(PIN_ID_PW2);
gpg_nvm_write(pin2, pin1, sizeof(gpg_pin_t));
}
}
static int gpg_pin_check_internal(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;
gpg_pin_t *brother;
brother = NULL;
if (pin->ref == PIN_ID_PW1) {
brother = gpg_pin_get_pin(PIN_ID_PW2);
} else if (pin->ref == PIN_ID_PW2) {
brother = gpg_pin_get_pin(PIN_ID_PW1);
}
if (pin->counter == 0) { if (pin->counter == 0) {
THROW(SW_PIN_BLOCKED); return SW_PIN_BLOCKED;
} }
counter = pin->counter-1; counter = pin->counter-1;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int)); gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
if (brother) {
gpg_nvm_write(&(brother->counter), &counter, sizeof(int));
}
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; return 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; if (brother) {
gpg_nvm_write(&(brother->counter), &counter, sizeof(int));
}
return SW_OK;
} }
static void gpg_checkthrow_pin(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) { static void gpg_pin_check_throw(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
int sw;
if (gpg_check_pin_internal(pin,pin_val,pin_len)) { gpg_pin_set_verified(pin,0);
sw = gpg_pin_check_internal(pin,pin_val,pin_len);
if (sw == SW_OK) {
gpg_pin_set_verified(pin,1);
return; return;
} }
THROW(SW_SECURITY_STATUS_NOT_SATISFIED); THROW(sw);
} }
static void gpg_set_pin(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) { int gpg_pin_check(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
int sw;
sw = gpg_pin_check_internal(pin,pin_val,pin_len);
gpg_pin_set_verified(pin,0);
if (sw == SW_OK) {
gpg_pin_set_verified(pin,1);
}
return sw;
}
void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
cx_sha256_t sha256; cx_sha256_t sha256;
gpg_pin_t newpin; gpg_pin_t newpin;
@ -78,74 +130,47 @@ static void gpg_set_pin(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin
newpin.counter = 3; newpin.counter = 3;
gpg_nvm_write(pin, &newpin, sizeof(gpg_pin_t)); gpg_nvm_write(pin, &newpin, sizeof(gpg_pin_t));
gpg_pin_sync12();
} }
/* int gpg_pin_set_verified(gpg_pin_t *pin, int verified) {
static void gpg_unblock_pin(int id) { int idx;
gpg_pin_t *pin; idx = gpg_pin_get_index(pin->ref);
int counter; if (idx >= 0) {
pin = gpg_get_pin(id); G_gpg_vstate.verified_pin[idx]=verified;
counter = 3;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
}
*/
int gpg_set_pin_verified(int id, int verified) {
G_gpg_vstate.verified_pin[id] = verified;
return verified; return verified;
}
return 0;
}
int gpg_pin_is_verified(gpg_pin_t *pin) {
int idx;
idx = gpg_pin_get_index(pin->ref);
if (idx >= 0) {
return G_gpg_vstate.verified_pin[idx];
}
return 0;
} }
int gpg_check_pin(int id, unsigned char *pin_val, unsigned int pin_len) { int gpg_pin_is_blocked(gpg_pin_t *pin) {
gpg_pin_t *pin;
pin = gpg_get_pin(id);
return gpg_set_pin_verified(id, gpg_check_pin_internal(pin,pin_val,pin_len)?1:0);
}
/*
*
*/
void gpg_change_pin(int id, unsigned char *pin_val, unsigned int pin_len) {
gpg_pin_t *pin;
pin = gpg_get_pin(id);
gpg_set_pin(pin, pin_val, pin_len);
}
/*
*
*/
int gpg_is_pin_verified(int id) {
return G_gpg_vstate.verified_pin[id] != 0;
}
/*
*
*/
int gpg_is_pin_blocked(int id) {
gpg_pin_t *pin;
pin = gpg_get_pin(id);
return pin->counter == 0; return pin->counter == 0;
} }
/* @return: 1 verified int gpg_apdu_verify() {
* 0 not verified
* -1 blocked
*/
int gpg_apdu_verify(int id) {
gpg_pin_t *pin; gpg_pin_t *pin;
pin = gpg_get_pin(id); pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
if (pin == NULL) { if (pin == NULL) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
gpg_set_pin_verified(id,0); gpg_pin_set_verified(pin,0);
if (gpg_is_pin_blocked(id)) { if (gpg_pin_is_blocked(pin)) {
THROW(SW_PIN_BLOCKED); THROW(SW_PIN_BLOCKED);
return 0; return SW_PIN_BLOCKED;
} }
if (G_gpg_vstate.io_length == 0) { if (G_gpg_vstate.io_length == 0) {
if (G_gpg_vstate.pinmode == PIN_MODE_SCREEN) { if (G_gpg_vstate.pinmode == PIN_MODE_SCREEN) {
@ -161,34 +186,33 @@ int gpg_apdu_verify(int id) {
return 0; return 0;
} }
if (G_gpg_vstate.pinmode == PIN_MODE_TRUST) { if (G_gpg_vstate.pinmode == PIN_MODE_TRUST) {
gpg_set_pin_verified(id,1); gpg_pin_set_verified(pin,1);
gpg_io_discard(1); gpg_io_discard(1);
return SW_OK; return SW_OK;
} }
} }
gpg_checkthrow_pin(pin, gpg_pin_check_throw(pin,
G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset,
G_gpg_vstate.io_length); G_gpg_vstate.io_length);
gpg_set_pin_verified(id,1);
gpg_io_discard(1); gpg_io_discard(1);
return SW_OK; return SW_OK;
} }
int gpg_apdu_change_ref_data(int id) { int gpg_apdu_change_ref_data() {
gpg_pin_t *pin; gpg_pin_t *pin;
int len, newlen; int len, newlen;
pin = gpg_get_pin(id); pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
if (pin == NULL) { if (pin == NULL) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
gpg_set_pin_verified(id,0); gpg_pin_set_verified(pin,0);
// --- RC pin --- // --- RC pin ---
if (id == PIN_ID_RC) { if (pin->ref == PIN_ID_RC) {
newlen = G_gpg_vstate.io_length; 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));
@ -197,9 +221,9 @@ int gpg_apdu_change_ref_data(int id) {
else if ((newlen > GPG_MAX_PW_LENGTH) || else if ((newlen > GPG_MAX_PW_LENGTH) ||
(newlen < 8)) { (newlen < 8)) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} else { } else {
gpg_set_pin(pin, gpg_pin_set(pin,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
newlen); newlen);
} }
@ -208,9 +232,9 @@ int gpg_apdu_change_ref_data(int id) {
} }
// --- PW1/PW3 pin --- // --- PW1/PW3 pin ---
if (gpg_is_pin_blocked(id)) { if (gpg_pin_is_blocked(pin)) {
THROW(SW_PIN_BLOCKED); THROW(SW_PIN_BLOCKED);
return 0; return SW_PIN_BLOCKED;
} }
//avoid any-overflow whitout giving info //avoid any-overflow whitout giving info
if (G_gpg_vstate.io_length == 0) { if (G_gpg_vstate.io_length == 0) {
@ -228,18 +252,18 @@ int gpg_apdu_change_ref_data(int id) {
len = pin->length; len = pin->length;
} }
gpg_checkthrow_pin(pin, gpg_pin_check_throw(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_length-len; newlen = G_gpg_vstate.io_length-len;
if ( (newlen > GPG_MAX_PW_LENGTH) || if ( (newlen > GPG_MAX_PW_LENGTH) ||
((id == PIN_ID_PW1) && (newlen < 6)) || ((pin->ref == PIN_ID_PW1) && (newlen < 6)) ||
((id == PIN_ID_PW3) && (newlen < 8)) ) { ((pin->ref == PIN_ID_PW3) && (newlen < 8)) ) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
gpg_set_pin(pin, gpg_pin_set(pin,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+len, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+len,
newlen); newlen);
gpg_io_discard(1); gpg_io_discard(1);
@ -248,20 +272,23 @@ int gpg_apdu_change_ref_data(int id) {
int gpg_apdu_reset_retry_counter() { int gpg_apdu_reset_retry_counter() {
gpg_pin_t *pin_pw1; gpg_pin_t *pin_pw1;
gpg_pin_t *pin_pw3;
gpg_pin_t *pin_rc; gpg_pin_t *pin_rc;
int rc_len, pw1_len; int rc_len, pw1_len;
pin_pw1 = gpg_get_pin(PIN_ID_PW1); pin_pw1 = gpg_pin_get_pin(PIN_ID_PW1);
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
pin_rc = gpg_pin_get_pin(PIN_ID_RC);
if (G_gpg_vstate.io_p1 == 2) { if (G_gpg_vstate.io_p1 == 2) {
if (!G_gpg_vstate.verified_pin[PIN_ID_PW3]) { if (!gpg_pin_is_verified(pin_pw3)) {
THROW(SW_SECURITY_STATUS_NOT_SATISFIED); THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
return 0; return SW_SECURITY_STATUS_NOT_SATISFIED;
} }
rc_len = 0; rc_len = 0;
pw1_len = G_gpg_vstate.io_length; pw1_len = G_gpg_vstate.io_length;
} else { } else {
pin_rc = gpg_get_pin(PIN_ID_RC);
//avoid any-overflow whitout giving info //avoid any-overflow whitout giving info
if (pin_rc->length > G_gpg_vstate.io_length) { if (pin_rc->length > G_gpg_vstate.io_length) {
rc_len = G_gpg_vstate.io_length; rc_len = G_gpg_vstate.io_length;
@ -269,16 +296,16 @@ int gpg_apdu_reset_retry_counter() {
rc_len = pin_rc->length; rc_len = pin_rc->length;
} }
pw1_len = G_gpg_vstate.io_length-rc_len; pw1_len = G_gpg_vstate.io_length-rc_len;
gpg_checkthrow_pin(pin_rc, gpg_pin_check_throw(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);
} }
if ((pw1_len > GPG_MAX_PW_LENGTH) ||(pw1_len < 6)) { if ((pw1_len > GPG_MAX_PW_LENGTH) ||(pw1_len < 6)) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
gpg_set_pin(pin_pw1, gpg_pin_set(pin_pw1,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+rc_len, G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+rc_len,
pw1_len); pw1_len);
gpg_io_discard(1); gpg_io_discard(1);

View File

@ -26,6 +26,11 @@ const unsigned char gpg_oid_sha512[] = {
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
}; };
static void gpg_pso_reset_PW1() {
if (N_gpg_pstate->PW_status[0] ==0) {
gpg_pin_set_verified(gpg_pin_get_pin(PIN_ID_PW1),0);
}
}
static int gpg_sign(gpg_key_t *sigkey) { static int gpg_sign(gpg_key_t *sigkey) {
// --- RSA // --- RSA
@ -50,7 +55,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
} }
if (key->size != ksz) { if (key->size != ksz) {
THROW(SW_CONDITIONS_NOT_SATISFIED); THROW(SW_CONDITIONS_NOT_SATISFIED);
return 0; return SW_CONDITIONS_NOT_SATISFIED;
} }
//sign //sign
@ -71,6 +76,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
//send //send
gpg_io_discard(0); gpg_io_discard(0);
gpg_io_inserted(ksz); gpg_io_inserted(ksz);
gpg_pso_reset_PW1();
return SW_OK; return SW_OK;
} }
// --- ECDSA/EdDSA // --- ECDSA/EdDSA
@ -83,7 +89,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
key = &sigkey->key.ecfp256; key = &sigkey->key.ecfp256;
if (key->d_len != 32) { if (key->d_len != 32) {
THROW(SW_CONDITIONS_NOT_SATISFIED); THROW(SW_CONDITIONS_NOT_SATISFIED);
return 0; return SW_CONDITIONS_NOT_SATISFIED;
} }
//sign //sign
if (sigkey->attributes.value[0] == 19) { if (sigkey->attributes.value[0] == 19) {
@ -120,11 +126,12 @@ static int gpg_sign(gpg_key_t *sigkey) {
} }
//send //send
gpg_pso_reset_PW1();
return SW_OK; return SW_OK;
} }
// --- PSO:CDS NOT SUPPORTED // --- PSO:CDS NOT SUPPORTED
THROW(SW_REFERENCED_DATA_NOT_FOUND); THROW(SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
@ -133,7 +140,12 @@ int gpg_apdu_pso(unsigned int pso) {
switch(pso) { switch(pso) {
// --- PSO:CDS --- // --- PSO:CDS ---
case 0x9e9a: { case 0x9e9a: {
return gpg_sign(&G_gpg_vstate.kslot->sig); unsigned int cnt;
int sw;
sw = gpg_sign(&G_gpg_vstate.kslot->sig);
cnt = G_gpg_vstate.kslot->sig_count+1;
nvm_write(&G_gpg_vstate.kslot->sig_count,&cnt,sizeof(unsigned int));
return sw;
} }
// --- PSO:DEC --- // --- PSO:DEC ---
@ -149,7 +161,7 @@ int gpg_apdu_pso(unsigned int pso) {
cx_rsa_private_key_t *key; cx_rsa_private_key_t *key;
if (G_gpg_vstate.kslot->dec.attributes.value[0] != 0x01) { if (G_gpg_vstate.kslot->dec.attributes.value[0] != 0x01) {
THROW(SW_CONDITIONS_NOT_SATISFIED); THROW(SW_CONDITIONS_NOT_SATISFIED);
return 0; return SW_CONDITIONS_NOT_SATISFIED;
} }
ksz = (G_gpg_vstate.kslot->dec.attributes.value[1]<<8) | G_gpg_vstate.kslot->dec.attributes.value[2]; ksz = (G_gpg_vstate.kslot->dec.attributes.value[1]<<8) | G_gpg_vstate.kslot->dec.attributes.value[2];
ksz = ksz>>3; ksz = ksz>>3;
@ -192,7 +204,7 @@ int gpg_apdu_pso(unsigned int pso) {
key = &G_gpg_vstate.kslot->AES_dec; key = &G_gpg_vstate.kslot->AES_dec;
if (!(key->size != 16)) { if (!(key->size != 16)) {
THROW(SW_CONDITIONS_NOT_SATISFIED+5); THROW(SW_CONDITIONS_NOT_SATISFIED+5);
return 0; return SW_CONDITIONS_NOT_SATISFIED;
} }
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset; msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
sz = cx_aes(key, sz = cx_aes(key,
@ -212,23 +224,23 @@ int gpg_apdu_pso(unsigned int pso) {
unsigned int curve; unsigned int curve;
if (G_gpg_vstate.kslot->dec.attributes.value[0] != 18) { if (G_gpg_vstate.kslot->dec.attributes.value[0] != 18) {
THROW(SW_CONDITIONS_NOT_SATISFIED); THROW(SW_CONDITIONS_NOT_SATISFIED);
return 0; return SW_CONDITIONS_NOT_SATISFIED;
} }
key = &G_gpg_vstate.kslot->dec.key.ecfp256; key = &G_gpg_vstate.kslot->dec.key.ecfp256;
if (key->d_len != 32) { if (key->d_len != 32) {
THROW(SW_CONDITIONS_NOT_SATISFIED); THROW(SW_CONDITIONS_NOT_SATISFIED);
return 0; return SW_CONDITIONS_NOT_SATISFIED;
} }
gpg_io_fetch_l(&l); gpg_io_fetch_l(&l);
gpg_io_fetch_tl(&t, &l); gpg_io_fetch_tl(&t, &l);
if (t != 0x7f49) { if (t != 0x7f49) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
gpg_io_fetch_tl(&t, &l); gpg_io_fetch_tl(&t, &l);
if (t != 0x86) { if (t != 0x86) {
THROW(SW_WRONG_DATA); THROW(SW_WRONG_DATA);
return 0; return SW_WRONG_DATA;
} }
curve = gpg_oid2curve(G_gpg_vstate.kslot->dec.attributes.value+1, G_gpg_vstate.kslot->dec.attributes.length-1); curve = gpg_oid2curve(G_gpg_vstate.kslot->dec.attributes.value+1, G_gpg_vstate.kslot->dec.attributes.length-1);
@ -262,7 +274,7 @@ int gpg_apdu_pso(unsigned int pso) {
// --- PSO:DEC:xx NOT SUPPORTDED // --- PSO:DEC:xx NOT SUPPORTDED
default: default:
THROW(SW_REFERENCED_DATA_NOT_FOUND); THROW(SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
} }
@ -270,10 +282,10 @@ int gpg_apdu_pso(unsigned int pso) {
//--- PSO:yy NOT SUPPPORTED --- //--- PSO:yy NOT SUPPPORTED ---
default: default:
THROW(SW_REFERENCED_DATA_NOT_FOUND); THROW(SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
THROW(SW_REFERENCED_DATA_NOT_FOUND); THROW(SW_REFERENCED_DATA_NOT_FOUND);
return 0; return SW_REFERENCED_DATA_NOT_FOUND;
} }
@ -284,7 +296,7 @@ int gpg_apdu_internal_authenticate() {
if (G_gpg_vstate.kslot->aut.attributes.value[0] == 1) { if (G_gpg_vstate.kslot->aut.attributes.value[0] == 1) {
if ( G_gpg_vstate.io_length > ((G_gpg_vstate.kslot->aut.attributes.value[1]<<8)|G_gpg_vstate.kslot->aut.attributes.value[2])*40/100) { if ( G_gpg_vstate.io_length > ((G_gpg_vstate.kslot->aut.attributes.value[1]<<8)|G_gpg_vstate.kslot->aut.attributes.value[2])*40/100) {
THROW(SW_WRONG_LENGTH); THROW(SW_WRONG_LENGTH);
return 0; return SW_WRONG_LENGTH;
} }
} }
return gpg_sign(&G_gpg_vstate.kslot->aut); return gpg_sign(&G_gpg_vstate.kslot->aut);

View File

@ -22,22 +22,24 @@
int gpg_apdu_select() { int gpg_apdu_select() {
int sw; int sw;
if ( (G_gpg_vstate.io_length = 6) && 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) ) { (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_current = 0;
G_gpg_vstate.DO_reccord = 0; G_gpg_vstate.DO_reccord = 0;
G_gpg_vstate.DO_offset = 0; G_gpg_vstate.DO_offset = 0;
if ( G_gpg_vstate.selected == 0) { if ( G_gpg_vstate.selected == 0) {
G_gpg_vstate.verified_pin[PIN_ID_PW1] = 0; G_gpg_vstate.verified_pin[0] = 0;
G_gpg_vstate.verified_pin[PIN_ID_PW2] = 0; G_gpg_vstate.verified_pin[1] = 0;
G_gpg_vstate.verified_pin[PIN_ID_PW3] = 0; G_gpg_vstate.verified_pin[2] = 0;
G_gpg_vstate.verified_pin[PIN_ID_RC] = 0; G_gpg_vstate.verified_pin[3] = 0;
G_gpg_vstate.verified_pin[4] = 0;
} }
gpg_io_discard(0); gpg_io_discard(0);
sw = SW_OK; sw = SW_OK;
} else { } else {
THROW(SW_FILE_NOT_FOUND); THROW(SW_FILE_NOT_FOUND);
return 0; return SW_FILE_NOT_FOUND;
} }
return sw; return sw;
} }

View File

@ -39,6 +39,7 @@
#define GPG_RSA_DEFAULT_PUB 0x010001U #define GPG_RSA_DEFAULT_PUB 0x010001U
struct gpg_pin_s { struct gpg_pin_s {
unsigned int ref;
//initial pin length, 0 means not set //initial pin length, 0 means not set
unsigned int length; unsigned int length;
unsigned int counter; unsigned int counter;
@ -151,6 +152,7 @@ struct gpg_nv_state_s {
/* PINs */ /* PINs */
gpg_pin_t PW1; gpg_pin_t PW1;
gpg_pin_t PW2;
gpg_pin_t PW3; gpg_pin_t PW3;
gpg_pin_t RC; gpg_pin_t RC;
@ -259,10 +261,10 @@ typedef struct gpg_v_state_s gpg_v_state_t;
#define IO_OFFSET_END (unsigned int)-1 #define IO_OFFSET_END (unsigned int)-1
#define IO_OFFSET_MARK (unsigned int)-2 #define IO_OFFSET_MARK (unsigned int)-2
#define PIN_ID_PW1 1 #define PIN_ID_PW1 0x81
#define PIN_ID_PW2 2 #define PIN_ID_PW2 0x82
#define PIN_ID_PW3 3 #define PIN_ID_PW3 0x83
#define PIN_ID_RC 4 #define PIN_ID_RC 0x84
#define PIN_MODE_HOST 1 #define PIN_MODE_HOST 1
#define PIN_MODE_SCREEN 2 #define PIN_MODE_SCREEN 2

View File

@ -32,26 +32,6 @@
/* --- NanoS UI layout --- */ /* --- NanoS UI layout --- */
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
#define PICSTR(x) ((char*)PIC(x))
#define TEMPLATE_TYPE PICSTR(C_TEMPLATE_TYPE)
#define TEMPLATE_KEY PICSTR(C_TEMPLATE_KEY)
#define INVALID_SELECTION PICSTR(C_INVALID_SELECTION)
#define OK PICSTR(C_OK)
#define NOK PICSTR(C_NOK)
#define WRONG_PIN PICSTR(C_WRONG_PIN)
#define RIGHT_PIN PICSTR(C_RIGHT_PIN)
#define PIN_CHANGED PICSTR(C_PIN_CHANGED)
#define PIN_DIFFERS PICSTR(C_PIN_DIFFERS)
#define PIN_USER PICSTR(C_PIN_USER)
#define PIN_ADMIN PICSTR(C_PIN_ADMIN)
#define VERIFIED PICSTR(C_VERIFIED)
#define NOT_VERIFIED PICSTR(C_NOT_VERIFIED)
#define ALLOWED PICSTR(C_ALLOWED)
#define NOT_ALLOWED PICSTR(C_NOT_ALLOWED)
#define DEFAULT_MODE PICSTR(C_DEFAULT_MODE)
const ux_menu_entry_t ui_menu_template[]; const ux_menu_entry_t ui_menu_template[];
void ui_menu_template_display(unsigned int value); void ui_menu_template_display(unsigned int value);
@ -172,12 +152,12 @@ unsigned int ui_pinconfirm_nanos_button(unsigned int button_mask, unsigned int b
sw = 0x6985; sw = 0x6985;
switch(button_mask) { switch(button_mask) {
case BUTTON_EVT_RELEASED|BUTTON_LEFT: // CANCEL case BUTTON_EVT_RELEASED|BUTTON_LEFT: // CANCEL
gpg_set_pin_verified(G_gpg_vstate.io_p2&0x0F,0); gpg_pin_set_verified(gpg_pin_get_pin(G_gpg_vstate.io_p2),0);
sw = 0x6985; sw = 0x6985;
break; break;
case BUTTON_EVT_RELEASED|BUTTON_RIGHT: // OK case BUTTON_EVT_RELEASED|BUTTON_RIGHT: // OK
gpg_set_pin_verified(G_gpg_vstate.io_p2&0x0F,1); gpg_pin_set_verified(gpg_pin_get_pin(G_gpg_vstate.io_p2),1);
sw = 0x9000; sw = 0x9000;
break; break;
default: default:
@ -336,24 +316,22 @@ unsigned int ui_pinentry_nanos_button(unsigned int button_mask, unsigned int but
// >= 0 // >= 0
static unsigned int validate_pin() { static unsigned int validate_pin() {
unsigned int offset, len, sw; unsigned int offset, len, sw;
gpg_pin_t *pin;
for (offset = 1; offset< G_gpg_vstate.ux_pinentry[0];offset++) { for (offset = 1; offset< G_gpg_vstate.ux_pinentry[0];offset++) {
G_gpg_vstate.menu[offset] = C_pin_digit[G_gpg_vstate.ux_pinentry[offset]]; G_gpg_vstate.menu[offset] = C_pin_digit[G_gpg_vstate.ux_pinentry[offset]];
} }
if (G_gpg_vstate.io_ins == 0x20) { if (G_gpg_vstate.io_ins == 0x20) {
if (gpg_check_pin(G_gpg_vstate.io_p2&0x0F, (unsigned char*)(G_gpg_vstate.menu+1), G_gpg_vstate.ux_pinentry[0])) { pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
sw = SW_OK; sw = gpg_pin_check(pin, (unsigned char*)(G_gpg_vstate.menu+1), G_gpg_vstate.ux_pinentry[0]);
} else {
sw = SW_CONDITIONS_NOT_SATISFIED;
}
gpg_io_discard(1); gpg_io_discard(1);
gpg_io_insert_u16(sw); gpg_io_insert_u16(sw);
gpg_io_do(IO_RETURN_AFTER_TX); gpg_io_do(IO_RETURN_AFTER_TX);
if (sw == SW_CONDITIONS_NOT_SATISFIED) { if (sw == SW_CONDITIONS_NOT_SATISFIED) {
ui_info(WRONG_PIN, NULL, ui_menu_main_display, 0); snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), " %d tries remaining", pin->counter );
} else { ui_info(WRONG_PIN, G_gpg_vstate.menu, ui_menu_main_display, 0);
ui_info(RIGHT_PIN, NULL, ui_menu_main_display, 0);
} }
return 0; return 0;
} }
@ -365,10 +343,12 @@ static unsigned int validate_pin() {
G_gpg_vstate.io_p1++; G_gpg_vstate.io_p1++;
} }
if (G_gpg_vstate.io_p1 == 3) { if (G_gpg_vstate.io_p1 == 3) {
if (!gpg_check_pin(G_gpg_vstate.io_p2&0x0F, G_gpg_vstate.work.io_buffer+1, G_gpg_vstate.work.io_buffer[0])) { pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
if (gpg_pin_check(pin, G_gpg_vstate.work.io_buffer+1, G_gpg_vstate.work.io_buffer[0])!=SW_OK) {
gpg_io_discard(1); gpg_io_discard(1);
gpg_io_insert_u16(SW_CONDITIONS_NOT_SATISFIED); gpg_io_insert_u16(SW_CONDITIONS_NOT_SATISFIED);
gpg_io_do(IO_RETURN_AFTER_TX); gpg_io_do(IO_RETURN_AFTER_TX);
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), " %d tries remaining", pin->counter );
ui_info(WRONG_PIN, NULL, ui_menu_main_display, 0); ui_info(WRONG_PIN, NULL, ui_menu_main_display, 0);
return 0; return 0;
} }
@ -381,11 +361,12 @@ static unsigned int validate_pin() {
gpg_io_do(IO_RETURN_AFTER_TX); gpg_io_do(IO_RETURN_AFTER_TX);
ui_info(PIN_DIFFERS, NULL, ui_menu_main_display, 0); ui_info(PIN_DIFFERS, NULL, ui_menu_main_display, 0);
} else { } else {
gpg_change_pin(G_gpg_vstate.io_p2&0x0F, G_gpg_vstate.work.io_buffer+offset+ 1, len); gpg_pin_set(gpg_pin_get_pin(G_gpg_vstate.io_p2), G_gpg_vstate.work.io_buffer+offset+ 1, len);
gpg_io_discard(1); gpg_io_discard(1);
gpg_io_insert_u16(SW_OK); gpg_io_insert_u16(SW_OK);
gpg_io_do(IO_RETURN_AFTER_TX); gpg_io_do(IO_RETURN_AFTER_TX);
ui_info(PIN_CHANGED, NULL, ui_menu_main_display, 0); //ui_info(PIN_CHANGED, NULL, ui_menu_main_display, 0);
ui_menu_main_display(0);
} }
return 0; return 0;
} else { } else {
@ -680,7 +661,7 @@ void ui_menu_pinmode_action(unsigned int value) {
switch (value) { switch (value) {
case PIN_MODE_HOST: case PIN_MODE_HOST:
case PIN_MODE_SCREEN: case PIN_MODE_SCREEN:
if (!gpg_is_pin_verified(PIN_ID_PW1)) { if (!gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW2))) {
ui_info(PIN_USER, NOT_VERIFIED, ui_menu_pinmode_display,0); ui_info(PIN_USER, NOT_VERIFIED, ui_menu_pinmode_display,0);
return; return;
} }
@ -688,7 +669,7 @@ void ui_menu_pinmode_action(unsigned int value) {
case PIN_MODE_CONFIRM: case PIN_MODE_CONFIRM:
case PIN_MODE_TRUST: case PIN_MODE_TRUST:
if (!gpg_is_pin_verified(PIN_ID_PW3)) { if (!gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW3))) {
ui_info(PIN_ADMIN, NOT_VERIFIED, ui_menu_pinmode_display,0); ui_info(PIN_ADMIN, NOT_VERIFIED, ui_menu_pinmode_display,0);
return; return;
} }
@ -709,8 +690,8 @@ const ux_menu_entry_t ui_menu_reset[] = {
#error menu definition not correct for current value of GPG_KEYS_SLOTS #error menu definition not correct for current value of GPG_KEYS_SLOTS
#endif #endif
{NULL, NULL, 0, NULL, "Really Reset ?", NULL, 0, 0}, {NULL, NULL, 0, NULL, "Really Reset ?", NULL, 0, 0},
{NULL, ui_menu_main_display, 0, &C_badge_back, "Oh No!", NULL, 61, 40}, {NULL, ui_menu_main_display, 0, &C_badge_back, "No", NULL, 61, 40},
{NULL, ui_menu_reset_action, 0, NULL, "Yes!", NULL, 0, 0}, {NULL, ui_menu_reset_action, 0, NULL, "Yes", NULL, 0, 0},
UX_MENU_END UX_MENU_END
}; };