On the road to 1.1.0

Fix PIN management

Add 3.3.1 spec addons
  - VERIFY with get status
  - MSE
  - ECC public key import
  - AES PSO:ENC
  - AES multi blcok
This commit is contained in:
Cédric Mesnil 2017-08-31 17:03:27 +02:00
parent 582928a16d
commit a1c8e7766c
9 changed files with 179 additions and 130 deletions

View File

@ -22,10 +22,11 @@ APPNAME = "OpenPGP"
APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_LOAD_PARAMS)
APPVERSION_M=1
APPVERSION_N=0
APPVERSION_P=1
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
APPVERSION_N=1
APPVERSION_P=0
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
SPECVERSION="3.3.1"
ICONNAME=images/icon_pgp.gif
@ -43,7 +44,7 @@ DEFINES += HAVE_BAGL HAVE_PRINTF HAVE_SPRINTF
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=7 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
DEFINES += HAVE_USB_CLASS_CCID
DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME)
DEFINES += $(GPG_CONFIG) GPG_VERSION=$(APPVERSION) GPG_NAME=$(APPNAME) SPEC_VERSION=$(SPECVERSION)
##############
# Compiler #

View File

@ -40,12 +40,14 @@ int gpg_apdu_change_ref_data(void) ;
int gpg_apdu_reset_retry_counter(void) ;
gpg_pin_t *gpg_pin_get_pin(int id);
int gpg_pin_is_verified(gpg_pin_t *pin);
int gpg_pin_is_blocked(gpg_pin_t *pin);
int gpg_pin_set_verified(gpg_pin_t *pin, int verified);
int gpg_pin_check(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len);
int gpg_pin_is_verified(int pinID);
int gpg_pin_set_verified(int pinID, int verified);
int gpg_pin_check(gpg_pin_t *pin, int pinID,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_pin_sync12(void) ;
int gpg_mse_reset();
int gpg_apdu_mse();
/* ----------------------------------------------------------------------- */
/* --- IO ---- */

View File

@ -316,7 +316,7 @@ int gpg_apdu_put_data(unsigned int ref) {
break;
default:
THROW(SW_REFERENCED_DATA_NOT_FOUND);
break;
return 0;
}
//fecth 7f78
gpg_io_fetch_tl(&t,&l);
@ -343,6 +343,7 @@ int gpg_apdu_put_data(unsigned int ref) {
case 0x95:
case 0x96:
case 0x97:
case 0x99:
break;
default:
THROW(SW_REFERENCED_DATA_NOT_FOUND);

View File

@ -23,12 +23,7 @@
void gpg_check_access_ins() {
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 ;
switch (G_gpg_vstate.io_ins) {
@ -45,7 +40,7 @@ void gpg_check_access_ins() {
return;
case INS_RESET_RETRY_COUNTER:
if (gpg_pin_is_verified(pin_pw3) || gpg_pin_is_verified(pin_rc)) {
if (gpg_pin_is_verified(PIN_ID_PW3) || gpg_pin_is_verified(PIN_ID_RC)) {
return;
}
@ -57,27 +52,30 @@ void gpg_check_access_ins() {
if (G_gpg_vstate.io_p1 == 0x81) {
return;
}
if (gpg_pin_is_verified(pin_pw3)) {
if (gpg_pin_is_verified(PIN_ID_PW3)) {
return;
}
break;
case INS_MSE:
return ;
case INS_PSO:
if ((ref == 0x9e9a) && gpg_pin_is_verified(pin_pw1)) {
if ((ref == 0x9e9a) && gpg_pin_is_verified(PIN_ID_PW1)) {
//pso:sign
if (N_gpg_pstate->PW_status[0] == 0) {
gpg_pin_set_verified(pin_pw1, 0);
gpg_pin_set_verified(PIN_ID_PW1, 0);
}
return;
}
if ((ref == 0x8086 ) && gpg_pin_is_verified(pin_pw2)) {
//pso:dec
if (((ref == 0x8086 )||(ref == 0x8680)) && gpg_pin_is_verified(PIN_ID_PW2)) {
//pso:dec/enc
return;
}
break;
case INS_INTERNAL_AUTHENTICATE:
if (gpg_pin_is_verified(pin_pw2)) {
if (gpg_pin_is_verified(PIN_ID_PW2)) {
return;
}
break;
@ -86,7 +84,7 @@ void gpg_check_access_ins() {
return;
case INS_TERMINATE_DF:
if (gpg_pin_is_verified(pin_pw3)) {
if (gpg_pin_is_verified(PIN_ID_PW3)) {
return;
}
break;
@ -99,10 +97,6 @@ void gpg_check_access_ins() {
void gpg_check_access_read_DO() {
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 ;
@ -152,14 +146,14 @@ void gpg_check_access_read_DO() {
//PW1
case 0x0103:
if (gpg_pin_is_verified(pin_pw2)) {
if (gpg_pin_is_verified(PIN_ID_PW2)) {
return;
}
break;
//PW3
case 0x0104:
if (gpg_pin_is_verified(pin_pw3)) {
if (gpg_pin_is_verified(PIN_ID_PW3)) {
return;
}
break;
@ -183,7 +177,7 @@ void gpg_check_access_write_DO() {
case 0x0101:
case 0x0103:
case 0x01F2:
if (gpg_pin_is_verified(pin_pw2)) {
if (gpg_pin_is_verified(PIN_ID_PW2)) {
return;
}
break;
@ -225,7 +219,7 @@ void gpg_check_access_write_DO() {
case 0x00D6:
case 0x00D7:
case 0x00D8:
if (gpg_pin_is_verified(pin_pw3)) {
if (gpg_pin_is_verified(PIN_ID_PW3)) {
return;
}
break;
@ -242,7 +236,10 @@ int gpg_dispatch() {
unsigned int tag,t,l;
int sw;
if ((G_gpg_vstate.io_cla != 0x00) && (G_gpg_vstate.io_cla != 0x10)) {
THROW(SW_CLA_NOT_SUPPORTED);
return SW_CLA_NOT_SUPPORTED;
}
tag = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
@ -265,7 +262,7 @@ int gpg_dispatch() {
case INS_TERMINATE_DF:
gpg_io_discard(0);
if (gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW3)) || (N_gpg_pstate->PW3.counter == 0)) {
if (gpg_pin_is_verified(PIN_ID_PW3) || (N_gpg_pstate->PW3.counter == 0)) {
gpg_install(STATE_TERMINATE);
return(SW_OK);
break;
@ -361,7 +358,7 @@ int gpg_dispatch() {
THROW(SW_INCORRECT_P1P2);
case INS_RESET_RETRY_COUNTER:
if ((G_gpg_vstate.io_p2 == 0x81) &&
if ((G_gpg_vstate.io_p2 == 0x81) &&
( (G_gpg_vstate.io_p1 == 0) ||
(G_gpg_vstate.io_p1 == 2) )
) {
@ -375,6 +372,11 @@ int gpg_dispatch() {
sw = gpg_apdu_gen();
break;
/* --- MSE --- */
case INS_MSE:
sw = gpg_apdu_mse(tag);
break;
/* --- PSO --- */
case INS_PSO:
sw = gpg_apdu_pso(tag);

View File

@ -18,7 +18,7 @@
#include "gpg_types.h"
#include "gpg_api.h"
#include "gpg_vars.h"
#include "usbd_ccid_impl.h"
#define SHORT(x) ((x)>>8)&0xFF, (x)&0xFF
/* ----------------------*/
/* -- A Kind of Magic -- */
@ -171,13 +171,13 @@ const unsigned char C_default_AlgoAttrECC_dec[] = {
#else
const unsigned char C_default_AlgoAttrECC_sig[] = {
// eddsa
22,
0x16,
// ed25519
0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01,
};
const unsigned char C_default_AlgoAttrECC_dec[] = {
// ecdh
18,
0x12,
//cv25519
0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01,
};
@ -211,11 +211,11 @@ void gpg_init() {
gpg_nvm_write(N_gpg_pstate->magic, (void*)C_MAGIC, sizeof(C_MAGIC));
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
G_gpg_vstate.slot = N_gpg_pstate->config_slot[1];
G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot];
gpg_mse_reset();
//pin conf
G_gpg_vstate.pinmode = N_gpg_pstate->config_pin[0];
//ux conf
@ -260,8 +260,6 @@ int gpg_install(unsigned char app_state) {
pin.counter = 3;
pin.ref = PIN_ID_PW1;
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
os_memmove(pin.value, C_sha256_PW2, sizeof(C_sha256_PW2));
@ -288,8 +286,15 @@ int gpg_install(unsigned char app_state) {
nvm_write(&N_gpg_pstate->default_RSA_exponent, &l, sizeof(unsigned int));
//config pin
#if 1
G_gpg_vstate.work.io_buffer[0] = PIN_MODE_CONFIRM;
gpg_nvm_write(&N_gpg_pstate->config_pin, G_gpg_vstate.work.io_buffer, 1);
USBD_CCID_activate_pinpad(3);
#else
G_gpg_vstate.work.io_buffer[0] = PIN_MODE_HOST;
gpg_nvm_write(&N_gpg_pstate->config_pin, G_gpg_vstate.work.io_buffer, 1);
USBD_CCID_activate_pinpad(0);
#endif
//default key template: RSA 2048)

View File

@ -21,12 +21,11 @@
#include "gpg_ux_nanos.h"
gpg_pin_t *gpg_pin_get_pin(int id) {
switch (id) {
gpg_pin_t *gpg_pin_get_pin(int pinref) {
switch (pinref) {
case PIN_ID_PW1 :
return &N_gpg_pstate->PW1;
case PIN_ID_PW2 :
return &N_gpg_pstate->PW2;
return &N_gpg_pstate->PW1;
case PIN_ID_PW3:
return &N_gpg_pstate->PW3;
case PIN_ID_RC:
@ -37,8 +36,8 @@ gpg_pin_t *gpg_pin_get_pin(int id) {
static int gpg_pin_get_index(unsigned int id) {
switch (id) {
static int gpg_pin_get_state_index(unsigned int pinref) {
switch (pinref) {
case PIN_ID_PW1 :
return 1;
case PIN_ID_PW2 :
@ -52,28 +51,10 @@ static int gpg_pin_get_index(unsigned int id) {
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) {
static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
cx_sha256_t sha256;
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) {
return SW_PIN_BLOCKED;
@ -81,9 +62,6 @@ static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pi
counter = pin->counter-1;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
if (brother) {
gpg_nvm_write(&(brother->counter), &counter, sizeof(int));
}
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)) {
@ -92,29 +70,28 @@ static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pi
counter = 3;
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
if (brother) {
gpg_nvm_write(&(brother->counter), &counter, sizeof(int));
}
return SW_OK;
}
static void gpg_pin_check_throw(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
static void gpg_pin_check_throw(gpg_pin_t *pin, int pinID,
unsigned char *pin_val, int pin_len) {
int sw;
gpg_pin_set_verified(pin,0);
gpg_pin_set_verified(pinID,0);
sw = gpg_pin_check_internal(pin,pin_val,pin_len);
if (sw == SW_OK) {
gpg_pin_set_verified(pin,1);
gpg_pin_set_verified(pinID,1);
return;
}
THROW(sw);
}
int gpg_pin_check(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
int gpg_pin_check(gpg_pin_t *pin, int pinID,
unsigned char *pin_val, unsigned int pin_len) {
int sw;
gpg_pin_set_verified(pinID,0);
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);
gpg_pin_set_verified(pinID,1);
}
return sw;
}
@ -130,12 +107,11 @@ void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
newpin.counter = 3;
gpg_nvm_write(pin, &newpin, sizeof(gpg_pin_t));
gpg_pin_sync12();
}
int gpg_pin_set_verified(gpg_pin_t *pin, int verified) {
int gpg_pin_set_verified(int pinID, int verified) {
int idx;
idx = gpg_pin_get_index(pin->ref);
idx = gpg_pin_get_state_index(pinID);
if (idx >= 0) {
G_gpg_vstate.verified_pin[idx]=verified;
return verified;
@ -143,9 +119,9 @@ int gpg_pin_set_verified(gpg_pin_t *pin, int verified) {
return 0;
}
int gpg_pin_is_verified(gpg_pin_t *pin) {
int gpg_pin_is_verified(int pinID) {
int idx;
idx = gpg_pin_get_index(pin->ref);
idx = gpg_pin_get_state_index(pinID);
if (idx >= 0) {
return G_gpg_vstate.verified_pin[idx];
}
@ -167,12 +143,15 @@ int gpg_apdu_verify() {
return SW_WRONG_DATA;
}
gpg_pin_set_verified(pin,0);
if (gpg_pin_is_blocked(pin)) {
THROW(SW_PIN_BLOCKED);
return SW_PIN_BLOCKED;
}
if (G_gpg_vstate.io_length == 0) {
//PINPAD
if (G_gpg_vstate.io_cla==0xFF) {
if (gpg_pin_is_blocked(pin)) {
THROW(SW_PIN_BLOCKED);
return SW_PIN_BLOCKED;
}
if (G_gpg_vstate.pinmode == PIN_MODE_SCREEN) {
//Delegate pin check to ui
gpg_io_discard(1);
@ -186,16 +165,46 @@ int gpg_apdu_verify() {
return 0;
}
if (G_gpg_vstate.pinmode == PIN_MODE_TRUST) {
gpg_pin_set_verified(pin,1);
gpg_pin_set_verified(G_gpg_vstate.io_p2,1);
gpg_io_discard(1);
return SW_OK;
}
THROW(SW_WRONG_DATA);
return SW_WRONG_DATA;
}
gpg_pin_check_throw(pin,
G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset,
G_gpg_vstate.io_length);
//NORMAL CHECK
if ((G_gpg_vstate.io_p1==0) && G_gpg_vstate.io_length) {
if (gpg_pin_is_blocked(pin)) {
THROW(SW_PIN_BLOCKED);
return SW_PIN_BLOCKED;
}
gpg_pin_check_throw(pin, G_gpg_vstate.io_p2,
G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset,
G_gpg_vstate.io_length);
gpg_io_discard(1);
return SW_OK;
}
gpg_io_discard(1);
return SW_OK;
//STATUS REQUEST
if ((G_gpg_vstate.io_p1==0) && G_gpg_vstate.io_length==0) {
if (gpg_pin_is_verified(G_gpg_vstate.io_p2)) {
return SW_OK;
}
return 0x63C0 | pin->counter;
}
//RESET REQUEST
if ((G_gpg_vstate.io_p1==0xFF) && G_gpg_vstate.io_length==0) {
gpg_pin_set_verified(G_gpg_vstate.io_p2,0);
return SW_OK;
}
THROW(SW_WRONG_DATA);
return SW_WRONG_DATA;
}
int gpg_apdu_change_ref_data() {
@ -208,7 +217,7 @@ int gpg_apdu_change_ref_data() {
return SW_WRONG_DATA;
}
gpg_pin_set_verified(pin,0);
gpg_pin_set_verified(pin->ref,0);
// --- RC pin ---
@ -252,7 +261,7 @@ int gpg_apdu_change_ref_data() {
len = pin->length;
}
gpg_pin_check_throw(pin,
gpg_pin_check_throw(pin, pin->ref,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
len);
@ -281,7 +290,7 @@ int gpg_apdu_reset_retry_counter() {
pin_rc = gpg_pin_get_pin(PIN_ID_RC);
if (G_gpg_vstate.io_p1 == 2) {
if (!gpg_pin_is_verified(pin_pw3)) {
if (!gpg_pin_is_verified(PIN_ID_PW3)) {
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
return SW_SECURITY_STATUS_NOT_SATISFIED;
}
@ -296,7 +305,7 @@ int gpg_apdu_reset_retry_counter() {
rc_len = pin_rc->length;
}
pw1_len = G_gpg_vstate.io_length-rc_len;
gpg_pin_check_throw(pin_rc,
gpg_pin_check_throw(pin_rc,pin_rc->ref,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
rc_len);
}

View File

@ -28,7 +28,7 @@ const unsigned char gpg_oid_sha512[] = {
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);
gpg_pin_set_verified(PIN_ID_PW1,0);
}
}
@ -134,7 +134,6 @@ static int gpg_sign(gpg_key_t *sigkey) {
return SW_REFERENCED_DATA_NOT_FOUND;
}
int gpg_apdu_pso(unsigned int pso) {
unsigned int t,l,ksz;
switch(pso) {
@ -147,6 +146,27 @@ int gpg_apdu_pso(unsigned int pso) {
nvm_write(&G_gpg_vstate.kslot->sig_count,&cnt,sizeof(unsigned int));
return sw;
}
// --- PSO:ENC ---
case 0x8680: {
unsigned int msg_len;
cx_aes_key_t *key;
unsigned int sz;
key = &G_gpg_vstate.kslot->AES_dec;
if (!(key->size != 16)) {
THROW(SW_CONDITIONS_NOT_SATISFIED+5);
return SW_CONDITIONS_NOT_SATISFIED;
}
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
sz = cx_aes(key,
CX_ENCRYPT|CX_CHAIN_CBC|CX_LAST,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, msg_len,
G_gpg_vstate.work.io_buffer+1);
//send
gpg_io_discard(0);
G_gpg_vstate.work.io_buffer[0] = 0x02;
gpg_io_inserted(1+sz);
return SW_OK;
}
// --- PSO:DEC ---
case 0x8086: {
@ -159,25 +179,25 @@ int gpg_apdu_pso(unsigned int pso) {
// --- PSO:DEC:RSA
case 0x00: {
cx_rsa_private_key_t *key;
if (G_gpg_vstate.kslot->dec.attributes.value[0] != 0x01) {
if (G_gpg_vstate.mse_dec->attributes.value[0] != 0x01) {
THROW(SW_CONDITIONS_NOT_SATISFIED);
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.mse_dec->attributes.value[1]<<8) | G_gpg_vstate.mse_dec->attributes.value[2];
ksz = ksz>>3;
key = NULL;
switch(ksz) {
case 1024/8:
key = (cx_rsa_private_key_t *)&G_gpg_vstate.kslot->dec.key.rsa1024;
key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa1024;
break;
case 2048/8:
key = (cx_rsa_private_key_t *)&G_gpg_vstate.kslot->dec.key.rsa2048;
key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa2048;
break;
case 3072/8:
key = (cx_rsa_private_key_t *)&G_gpg_vstate.kslot->dec.key.rsa3072;
key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa3072;
break;
case 4096/8:
key = (cx_rsa_private_key_t *)&G_gpg_vstate.kslot->dec.key.rsa4096;
key = (cx_rsa_private_key_t *)&G_gpg_vstate.mse_dec->key.rsa4096;
break;
}
@ -208,7 +228,7 @@ int gpg_apdu_pso(unsigned int pso) {
}
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
sz = cx_aes(key,
CX_DECRYPT|CX_LAST,
CX_DECRYPT|CX_CHAIN_CBC|CX_LAST,
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset, msg_len,
G_gpg_vstate.work.io_buffer);
//send
@ -222,11 +242,11 @@ int gpg_apdu_pso(unsigned int pso) {
cx_ecfp_private_key_t *key;
unsigned int sz;
unsigned int curve;
if (G_gpg_vstate.kslot->dec.attributes.value[0] != 18) {
if (G_gpg_vstate.mse_dec->attributes.value[0] != 0x12) {
THROW(SW_CONDITIONS_NOT_SATISFIED);
return SW_CONDITIONS_NOT_SATISFIED;
}
key = &G_gpg_vstate.kslot->dec.key.ecfp256;
key = &G_gpg_vstate.mse_dec->key.ecfp256;
if (key->d_len != 32) {
THROW(SW_CONDITIONS_NOT_SATISFIED);
return SW_CONDITIONS_NOT_SATISFIED;
@ -243,7 +263,7 @@ int gpg_apdu_pso(unsigned int pso) {
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.mse_dec->attributes.value+1, G_gpg_vstate.mse_dec->attributes.length-1);
if (curve == CX_CURVE_Curve25519) {
unsigned int i;
@ -290,14 +310,11 @@ int gpg_apdu_pso(unsigned int pso) {
int gpg_apdu_internal_authenticate() {
gpg_key_t *sigkey;
sigkey = &G_gpg_vstate.kslot->aut;
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.mse_aut->attributes.value[0] == 1) {
if ( G_gpg_vstate.io_length > ((G_gpg_vstate.mse_aut->attributes.value[1]<<8)|G_gpg_vstate.mse_aut->attributes.value[2])*40/100) {
THROW(SW_WRONG_LENGTH);
return SW_WRONG_LENGTH;
}
}
return gpg_sign(&G_gpg_vstate.kslot->aut);
return gpg_sign(G_gpg_vstate.mse_aut);
}

View File

@ -152,7 +152,6 @@ struct gpg_nv_state_s {
/* PINs */
gpg_pin_t PW1;
gpg_pin_t PW2;
gpg_pin_t PW3;
gpg_pin_t RC;
@ -174,7 +173,9 @@ struct gpg_v_state_s {
/* app state */
unsigned char selected;
unsigned char slot; /* DO 01F2 */
gpg_key_slot_t *kslot;
gpg_key_slot_t *kslot;
gpg_key_t *mse_aut;
gpg_key_t *mse_dec;
unsigned char seed_mode;
/* io state*/
@ -285,6 +286,7 @@ typedef struct gpg_v_state_s gpg_v_state_t;
#define INS_PUT_DATA_ODD 0xdb
#define INS_VERIFY 0x20
#define INS_MSE 0x22
#define INS_CHANGE_REFERENCE_DATA 0x24
#define INS_RESET_RETRY_COUNTER 0x2c

View File

@ -152,12 +152,12 @@ unsigned int ui_pinconfirm_nanos_button(unsigned int button_mask, unsigned int b
sw = 0x6985;
switch(button_mask) {
case BUTTON_EVT_RELEASED|BUTTON_LEFT: // CANCEL
gpg_pin_set_verified(gpg_pin_get_pin(G_gpg_vstate.io_p2),0);
gpg_pin_set_verified(G_gpg_vstate.io_p2,0);
sw = 0x6985;
break;
case BUTTON_EVT_RELEASED|BUTTON_RIGHT: // OK
gpg_pin_set_verified(gpg_pin_get_pin(G_gpg_vstate.io_p2),1);
gpg_pin_set_verified(G_gpg_vstate.io_p2,1);
sw = 0x9000;
break;
default:
@ -240,9 +240,17 @@ unsigned int ui_pinentry_prepro(const bagl_element_t* element) {
else if (element->component.userid == 2) {
unsigned int i;
G_gpg_vstate.menu[0] = ' ';
#if 1
for (i = 1; i<= G_gpg_vstate.ux_pinentry[0]; i++) {
G_gpg_vstate.menu[i] = C_pin_digit[G_gpg_vstate.ux_pinentry[i]];
G_gpg_vstate.menu[i] = C_pin_digit[G_gpg_vstate.ux_pinentry[i]];
}
#else
for (i = 1; i< G_gpg_vstate.ux_pinentry[0]; i++) {
G_gpg_vstate.menu[i] = '*';
}
G_gpg_vstate.menu[i] = C_pin_digit[G_gpg_vstate.ux_pinentry[i]];
i++;
#endif
for (; i<= GPG_MAX_PW_LENGTH;i++) {
G_gpg_vstate.menu[i] = '-';
}
@ -325,15 +333,16 @@ static unsigned int validate_pin() {
if (G_gpg_vstate.io_ins == 0x20) {
pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
sw = gpg_pin_check(pin, (unsigned char*)(G_gpg_vstate.menu+1), G_gpg_vstate.ux_pinentry[0]);
sw = gpg_pin_check(pin, G_gpg_vstate.io_p2, (unsigned char*)(G_gpg_vstate.menu+1), G_gpg_vstate.ux_pinentry[0]);
gpg_io_discard(1);
gpg_io_insert_u16(sw);
gpg_io_do(IO_RETURN_AFTER_TX);
if (sw == SW_CONDITIONS_NOT_SATISFIED) {
if (sw != SW_OK) {
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), " %d tries remaining", pin->counter );
ui_info(WRONG_PIN, G_gpg_vstate.menu, ui_menu_main_display, 0);
} else {
ui_menu_main_display(0);
}
return 0;
}
if (G_gpg_vstate.io_ins == 0x24) {
@ -344,7 +353,7 @@ static unsigned int validate_pin() {
}
if (G_gpg_vstate.io_p1 == 3) {
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) {
if (gpg_pin_check(pin, G_gpg_vstate.io_p2, G_gpg_vstate.work.io_buffer+1, G_gpg_vstate.work.io_buffer[0])!=SW_OK) {
gpg_io_discard(1);
gpg_io_insert_u16(SW_CONDITIONS_NOT_SATISFIED);
gpg_io_do(IO_RETURN_AFTER_TX);
@ -662,7 +671,7 @@ void ui_menu_pinmode_action(unsigned int value) {
case PIN_MODE_HOST:
case PIN_MODE_SCREEN:
case PIN_MODE_CONFIRM:
if (!gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW1))) {
if (!gpg_pin_is_verified(PIN_ID_PW2)) {
ui_info(PIN_USER, NOT_VERIFIED, ui_menu_pinmode_display,0);
return;
}
@ -670,7 +679,7 @@ void ui_menu_pinmode_action(unsigned int value) {
case PIN_MODE_TRUST:
if (!gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW3))) {
if (!gpg_pin_is_verified(PIN_ID_PW3)) {
ui_info(PIN_ADMIN, NOT_VERIFIED, ui_menu_pinmode_display,0);
return;
}
@ -767,6 +776,7 @@ void ui_menu_slot_action(unsigned int value) {
if (s!= G_gpg_vstate.slot) {
G_gpg_vstate.slot = s;
G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot];
gpg_mse_reset();
ui_CCID_reset();
}
}
@ -785,7 +795,7 @@ void ui_menu_slot_action(unsigned int value) {
const ux_menu_entry_t ui_menu_info[] = {
{NULL, NULL, -1, NULL, "OpenPGP Card", NULL, 0, 0},
{NULL, NULL, -1, NULL, "(c) Ledger SAS", NULL, 0, 0},
{NULL, NULL, -1, NULL, "Spec 3.0", NULL, 0, 0},
{NULL, NULL, -1, NULL, "Spec " XSTR(SPEC_VERSION),NULL, 0, 0},
{NULL, NULL, -1, NULL, "App " XSTR(GPG_VERSION), NULL, 0, 0},
{NULL, ui_menu_main_display, 3, &C_badge_back, "Back", NULL, 61, 40},
UX_MENU_END