RC7
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:
parent
2e0d755fb6
commit
9dec68f892
2
Makefile
2
Makefile
@ -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
|
||||||
|
@ -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 ---- */
|
||||||
|
@ -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) {
|
||||||
|
@ -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 ----------------- */
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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];
|
||||||
|
215
src/gpg_pin.c
215
src/gpg_pin.c
@ -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;
|
return verified;
|
||||||
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
int gpg_pin_is_verified(gpg_pin_t *pin) {
|
||||||
int gpg_set_pin_verified(int id, int verified) {
|
int idx;
|
||||||
G_gpg_vstate.verified_pin[id] = verified;
|
idx = gpg_pin_get_index(pin->ref);
|
||||||
return verified;
|
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,20 +221,20 @@ 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);
|
||||||
}
|
}
|
||||||
gpg_io_discard(1);
|
gpg_io_discard(1);
|
||||||
return SW_OK;
|
return SW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,10 @@
|
|||||||
#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;
|
||||||
//only store sha256 of PIN/RC
|
//only store sha256 of PIN/RC
|
||||||
unsigned char value[32];
|
unsigned char value[32];
|
||||||
};
|
};
|
||||||
@ -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
|
||||||
|
@ -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,13 +152,13 @@ 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:
|
||||||
return 0;
|
return 0;
|
||||||
@ -249,7 +229,7 @@ unsigned int ui_pinentry_prepro(const bagl_element_t* element) {
|
|||||||
case 2:
|
case 2:
|
||||||
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Confirm %s PIN", (G_gpg_vstate.io_p2 == 0x83)?"Admin":"User");
|
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "Confirm %s PIN", (G_gpg_vstate.io_p2 == 0x83)?"Admin":"User");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "WAT %s PIN", (G_gpg_vstate.io_p2 == 0x83)?"Admin":"User");
|
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), "WAT %s PIN", (G_gpg_vstate.io_p2 == 0x83)?"Admin":"User");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user