Add two levels of reset

- Reset application
- Reset current key slot only
pull/56/head
cslashm 4 years ago
parent 6348318cf0
commit 1151672873

@ -44,8 +44,8 @@ ICONNAME = images/icon_pgp.gif
endif
APPVERSION_M:=1
APPVERSION_N:=3
APPVERSION_P:=3
APPVERSION_N:=4
APPVERSION_P:=0
APPVERSION:=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
SPECVERSION:="3.3.1"
@ -55,7 +55,7 @@ DEFINES += OPENPGP_VERSION=$(APPVERSION)
DEFINES += OPENPGP_NAME=$(APPNAME)
DEFINES += SPEC_VERSION=$(SPECVERSION)
DEFINES += GPG_MULTISLOT=$(GPG_MULTISLOT)
#DEFINES += GPG_LOG
ifeq ($(TARGET_NAME),TARGET_NANOX)

@ -1,11 +1,11 @@
# Copyright 2017 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -171,7 +171,7 @@ class GPGCard() :
data = [x for x in data]
apdu = [x for x in apdu]
#send
if data:
if data:
while len(data) > 0xFE:
apdux = apdu[0:5]+[0xfe]+data[0:0xFE]
apdux[0] |= 0x10
@ -187,7 +187,7 @@ class GPGCard() :
resp, sw1, sw2 = self.connection.transmit(apdu)
sw = (sw1<<8)|sw2
self.alog('recv', resp, sw)
#receive
while sw1==0x61:
apdu = binascii.unhexlify(b"00c00000%.02x"%sw2)
@ -223,6 +223,10 @@ class GPGCard() :
apdu = binascii.unhexlify(b"00E60000")
return self.exchange(apdu)
def get_log(self):
apdu = binascii.unhexlify(b"00040000")
return self.exchange(apdu)
def get_data(self,tag):
apdu = binascii.unhexlify(b"00CA%.04x00"%tag)
return self.exchange(apdu)
@ -330,11 +334,11 @@ class GPGCard() :
self.dec_key,sw = self.get_data(0x00B8)
self.aut_key,sw = self.get_data(0x00A4)
return True
def set_all(self):
self.put_data(0x4f, self.AID[10:14])
self.put_data(0x0101, self.private_01)
self.put_data(0x0102, self.private_02)
@ -413,7 +417,7 @@ class GPGCard() :
self.sig_date, self.dec_date, self.aut_date,
self.cardholder_cert,
self.UIF_SIG, self.UIF_DEC, self.UIF_AUT,
self.sig_key, self.dec_key, self.aut_key) = pickle.load(f)
self.sig_key, self.dec_key, self.aut_key) = pickle.load(f)
self.set_all()
return True
@ -424,7 +428,7 @@ class GPGCard() :
self.exchange(apdu)
apdu = binascii.unhexlify(b"0047800102A400")
self.exchange(apdu)
def decode_AID(self):
return {
@ -556,7 +560,7 @@ class GPGCard() :
#USER Info
def set_serial(self, ser):
ser=binascii.unhexlify(ser)
self.AID = self.AID[0:10]+ser
self.put_data(0x4f, self.AID[10:14])

@ -1,11 +1,11 @@
# Copyright 2018 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -21,17 +21,17 @@ from .gpgcard import GPGCard
def get_argparser():
parser = argparse.ArgumentParser(epilog="""
reset, backup, restore are always executed in THIS order.
reset, backup, restore are always executed in THIS order.
Template identifiers are ed2559, cv25519, rsa2048, rsa3072, rsa4096.
"""
)
parser.add_argument('--adm-pin', metavar='PIN', help='Administrative PIN, if pinpad not used')
parser.add_argument('--backup', help='Perfom a full backup except the key', action='store_true')
parser.add_argument('--backup-keys', help='Perfom keys encrypted backup', action='store_true')
parser.add_argument('--backup', help='Perfom a full backup except the key', action='store_true')
parser.add_argument('--backup-keys', help='Perfom keys encrypted backup', action='store_true')
parser.add_argument('--file', help='basckup/restore file', type=str, default='gpg_backup')
parser.add_argument('--pinpad', help='PIN validation will be deledated to pinpad', action='store_true')
parser.add_argument('--reader', help='PCSC reader', type=str, default='pcsc:Ledger')
parser.add_argument('--reader', help='PCSC reader', type=str, default='pcsc:Ledger')
parser.add_argument('--reset', help='Reset the application. All data are erased', action='store_true')
parser.add_argument('--restore', help='Perfom a full restore except the key', action='store_true')
parser.add_argument('--set-serial', metavar='SERIAL', help='set the four serial bytes')
@ -49,7 +49,7 @@ def banner():
GPG Ledger Admin Tool v0.1.
Copyright 2018 Cedric Mesnil <cslashm@gmail.com>, Ledger SAS
"""
"""
)
@ -95,7 +95,7 @@ try:
if args.reset:
print("Reset application...", end='', flush=True)
gpgcard.terminate()
gpgcard.terminate()
gpgcard.activate()
print("OK")
@ -128,11 +128,11 @@ try:
sig,dec,aut = args.set_templates.split(":")
gpgcard.set_template(templates[sig],templates[dec],templates[aut])
print("OK", flush=True)
if args.seed_key:
print("Seed Key...", end='', flush=True)
gpgcard.seed_key();
print("OK", flush=True)
print("OK", flush=True)
if args.set_fingerprints:
print("Set fingerprints...", end='', flush=True)

@ -24,7 +24,8 @@ unsigned int gpg_curve2domainlen(unsigned int cv);
void gpg_init(void);
void gpg_init_ux(void);
int gpg_install(unsigned char app_state);
void gpg_install(unsigned char app_state);
void gpg_install_slot(gpg_key_slot_t *slot);
int gpg_dispatch(void);
int gpg_apdu_select_data(unsigned int ref, int reccord);

@ -30,6 +30,11 @@ void gpg_check_access_ins() {
return;
}
break;
#ifdef GPG_LOG
#warning GPG_LOG activated
case INS_GET_LOG:
return;
#endif
case INS_SELECT:
return;
@ -256,6 +261,13 @@ int gpg_dispatch() {
tag = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2;
switch (G_gpg_vstate.io_ins) {
#ifdef GPG_LOG
case INS_GET_LOG:
gpg_io_discard(1);
gpg_io_insert(G_gpg_vstate.log_buffer, 32);
return SW_OK;
#endif
/* --- SELECT --- */
case INS_SELECT:
sw = gpg_apdu_select();

@ -252,7 +252,7 @@ const unsigned char C_default_AlgoAttr_dec[] = {
// Default template: NIST P256 132A8648CE3D030107 / 122A8648CE3D030107
#if 0
const unsigned char C_default_AlgoAttr_sig[] = {
// ecdsa
// ecdsa
0x13,
// NIST-P256
0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07
@ -268,7 +268,7 @@ const unsigned char C_default_AlgoAttr_dec[] = {
// Default template: Ed/Cv-25519 162B06010401DA470F01 / 122B060104019755010501
#if 0
const unsigned char C_default_AlgoAttr_sig[] = {
// eddsa
// eddsa
0x16,
// ed25519
0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01,
@ -323,10 +323,35 @@ void gpg_init_ux() {
/* ----------------------------------------------------------------------- */
/* --- Install/ReInstall GPGapp --- */
/* ----------------------------------------------------------------------- */
int gpg_install(unsigned char app_state) {
gpg_pin_t pin;
void gpg_install_slot(gpg_key_slot_t *slot) {
unsigned char tmp[4];
unsigned int l;
gpg_nvm_write(slot, 0, sizeof(gpg_key_slot_t));
cx_rng(tmp, 4);
gpg_nvm_write((void *)(slot->serial), tmp, 4);
l = sizeof(C_default_AlgoAttr_sig);
gpg_nvm_write((void *)(&slot->sig.attributes.value), (void *)C_default_AlgoAttr_sig, l);
gpg_nvm_write((void *)(&slot->sig.attributes.length), &l, sizeof(unsigned int));
gpg_nvm_write((void *)(&slot->aut.attributes.value), (void *)C_default_AlgoAttr_sig, l);
gpg_nvm_write((void *)(&slot->aut.attributes.length), &l, sizeof(unsigned int));
l = sizeof(C_default_AlgoAttr_dec);
gpg_nvm_write((void *)(&slot->dec.attributes.value), (void *)C_default_AlgoAttr_dec, l);
gpg_nvm_write((void *)(&slot->dec.attributes.length), &l, sizeof(unsigned int));
tmp[0] = 0x00;
tmp[1] = 0x20;
gpg_nvm_write((void *)(&slot->sig.UIF), &tmp, 2);
gpg_nvm_write((void *)(&slot->dec.UIF), &tmp, 2);
gpg_nvm_write((void *)(&slot->aut.UIF), &tmp, 2);
}
void gpg_install(unsigned char app_state) {
gpg_pin_t pin;
// full reset data
gpg_nvm_write((void *)(N_gpg_pstate), NULL, sizeof(gpg_nv_state_t));
@ -339,11 +364,6 @@ int gpg_install(unsigned char app_state) {
os_memmove(G_gpg_vstate.work.io_buffer, C_default_AID, sizeof(C_default_AID));
gpg_nvm_write((void *)(N_gpg_pstate->AID), &G_gpg_vstate.work.io_buffer, sizeof(C_default_AID));
// Serial
cx_rng(G_gpg_vstate.work.io_buffer, 4 * GPG_KEYS_SLOTS);
for (int s = 0; s < GPG_KEYS_SLOTS; s++) {
gpg_nvm_write((void *)(N_gpg_pstate->keys[s].serial), G_gpg_vstate.work.io_buffer + 4 * s, 4);
}
if (app_state == STATE_ACTIVATE) {
// default sex: none
@ -390,25 +410,10 @@ int gpg_install(unsigned char app_state) {
USBD_CCID_activate_pinpad(3);
// default key template: RSA 2048)
for (int s = 0; s < GPG_KEYS_SLOTS; s++) {
unsigned char uif[2];
uif[0] = 0x00;
uif[1] = 0x20;
l = sizeof(C_default_AlgoAttr_sig);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].sig.attributes.value), (void *)C_default_AlgoAttr_sig, l);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].sig.attributes.length), &l, sizeof(unsigned int));
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].aut.attributes.value), (void *)C_default_AlgoAttr_sig, l);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].aut.attributes.length), &l, sizeof(unsigned int));
l = sizeof(C_default_AlgoAttr_dec);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].dec.attributes.value), (void *)C_default_AlgoAttr_dec, l);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].dec.attributes.length), &l, sizeof(unsigned int));
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].sig.UIF), &uif, 2);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].dec.UIF), &uif, 2);
gpg_nvm_write((void *)(&N_gpg_pstate->keys[s].aut.UIF), &uif, 2);
gpg_install_slot(&N_gpg_pstate->keys[s]);
}
}
return 0;
}
#define USBD_OFFSET_CfgDesc_bPINSupport (sizeof(USBD_CfgDesc) - 16)

@ -207,7 +207,6 @@ struct gpg_v_state_s {
unsigned short io_mark;
union {
unsigned char io_buffer[GPG_IO_BUFFER_LENGTH];
struct {
union {
cx_rsa_public_key_t public;
@ -279,6 +278,9 @@ struct gpg_v_state_s {
char ux_buff5[32];
#endif
#ifdef GPG_LOG
unsigned char log_buffer[32];
#endif
#ifdef GPG_DEBUG
unsigned char print;
#endif
@ -316,6 +318,9 @@ typedef struct gpg_v_state_s gpg_v_state_t;
/* --- INS --- */
#define INS_EXIT 0x02
#ifdef GPG_LOG
#define INS_GET_LOG 0x04
#endif
#define INS_SELECT 0xa4
#define INS_TERMINATE_DF 0xe6

@ -96,44 +96,21 @@ unsigned int ui_uifconfirm_prepro(const bagl_element_t *element);
const bagl_element_t ui_uifconfirm_nanos[] = {
// type userid x y w h str rad fill fg bg font_id icon_id
{{BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0}, NULL, 0, 0, 0, NULL, NULL, NULL},
{{BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0},
NULL},
{{BAGL_ICON, 0x00, 3, 12, 7, 7, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CROSS},
NULL,
0,
0,
0,
NULL,
NULL,
NULL},
{{BAGL_ICON, 0x00, 117, 13, 8, 6, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CHECK},
NULL,
0,
0,
0,
NULL,
NULL,
NULL},
{{BAGL_LABELINE, 0x01, 0, 12, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
G_gpg_vstate.menu,
0,
0,
0,
NULL,
NULL,
NULL},
G_gpg_vstate.menu},
{{BAGL_LABELINE, 0x02, 0, 26, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
G_gpg_vstate.menu,
0,
0,
0,
NULL,
NULL,
NULL},
G_gpg_vstate.menu},
};
void ui_menu_uifconfirm_display(unsigned int value) {
@ -218,44 +195,21 @@ unsigned int ui_uifconfirm_nanos_button(unsigned int button_mask, unsigned int b
const bagl_element_t ui_pinconfirm_nanos[] = {
// type userid x y w h str rad fill fg bg font_id icon_id
{{BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0}, NULL, 0, 0, 0, NULL, NULL, NULL},
{{BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0},
NULL},
{{BAGL_ICON, 0x00, 3, 12, 7, 7, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CROSS},
NULL,
0,
0,
0,
NULL,
NULL,
NULL},
{{BAGL_ICON, 0x00, 117, 13, 8, 6, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_CHECK},
NULL,
0,
0,
0,
NULL,
NULL,
NULL},
{{BAGL_LABELINE, 0x01, 0, 12, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
G_gpg_vstate.menu,
0,
0,
0,
NULL,
NULL,
NULL},
G_gpg_vstate.menu},
{{BAGL_LABELINE, 0x02, 0, 26, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
G_gpg_vstate.menu,
0,
0,
0,
NULL,
NULL,
NULL},
G_gpg_vstate.menu},
};
void ui_menu_pinconfirm_display(unsigned int value) {
@ -308,44 +262,21 @@ unsigned int ui_pinconfirm_nanos_button(unsigned int button_mask, unsigned int b
const bagl_element_t ui_pinentry_nanos[] = {
// type userid x y w h str rad fill fg bg font_id icon_id
{{BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0}, NULL, 0, 0, 0, NULL, NULL, NULL},
{{BAGL_RECTANGLE, 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0},
NULL},
{{BAGL_ICON, 0x00, 3, 12, 7, 7, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_DOWN},
NULL,
0,
0,
0,
NULL,
NULL,
NULL},
{{BAGL_ICON, 0x00, 117, 13, 8, 6, 0, 0, 0, 0xFFFFFF, 0x000000, 0, BAGL_GLYPH_ICON_UP},
NULL,
0,
0,
0,
NULL,
NULL,
NULL},
{{BAGL_LABELINE, 0x01, 0, 12, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_EXTRABOLD_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
G_gpg_vstate.menu,
0,
0,
0,
NULL,
NULL,
NULL},
G_gpg_vstate.menu},
{{BAGL_LABELINE, 0x02, 0, 26, 128, 32, 0, 0, 0, 0xFFFFFF, 0x000000,
BAGL_FONT_OPEN_SANS_REGULAR_11px | BAGL_FONT_ALIGNMENT_CENTER, 0},
G_gpg_vstate.menu,
0,
0,
0,
NULL,
NULL,
NULL},
G_gpg_vstate.menu},
};
static const char C_pin_digit[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '<', 'A', 'V'};
@ -941,13 +872,29 @@ void ui_menu_reset_action(unsigned int value) {
ui_CCID_reset();
ui_menu_main_display(0);
}
/* ------------------------------ RESET KEY SLOT ----------------------------- */
void ui_menu_reset_slot_action(unsigned int value);
const ux_menu_entry_t ui_menu_reset_slot[] = {{NULL, NULL, 0, NULL, "Really Reset ?", NULL, 0, 0},
{NULL, ui_menu_main_display, 0, &C_badge_back, "No", NULL, 61, 40},
{NULL, ui_menu_reset_slot_action, 0, NULL, "Yes", NULL, 0, 0},
UX_MENU_END};
void ui_menu_reset_slot_action(unsigned int value) {
gpg_install_slot(G_gpg_vstate.kslot);
ui_menu_main_display(0);
}
/* ------------------------------- SETTINGS UX ------------------------------- */
const ux_menu_entry_t ui_menu_settings[] = {{NULL, ui_menu_template_display, 0, NULL, "Key template", NULL, 0, 0},
{NULL, ui_menu_seed_display, 0, NULL, "Seed mode", NULL, 0, 0},
{NULL, ui_menu_pinmode_display, 0, NULL, "PIN mode", NULL, 0, 0},
{NULL, ui_menu_uifmode_display, 0, NULL, "UIF mode", NULL, 0, 0},
{ui_menu_reset, NULL, 0, NULL, "Reset", NULL, 0, 0},
{ui_menu_reset, NULL, 0, NULL, "Reset App", NULL, 0, 0},
{ui_menu_reset_slot, NULL, 0, NULL, "Reset Slot", NULL, 0, 0},
{NULL, ui_menu_main_display, 2, &C_badge_back, "Back", NULL, 61, 40},
UX_MENU_END};
@ -1030,7 +977,7 @@ const ux_menu_entry_t ui_menu_main[] = {{NULL, NULL, 0, NULL, "", "", 0, 0},
#endif
{ui_menu_settings, NULL, 0, NULL, "Settings", NULL, 0, 0},
{ui_menu_info, NULL, 0, NULL, "About", NULL, 0, 0},
{NULL, os_sched_exit, 0, &C_icon_dashboard, "Quit app", NULL, 50, 29},
{NULL, (void*)os_sched_exit, 0, &C_icon_dashboard, "Quit app", NULL, 50, 29},
UX_MENU_END};
extern const uint8_t N_USBD_CfgDesc[];
const bagl_element_t *ui_menu_main_preprocessor(const ux_menu_entry_t *entry, bagl_element_t *element) {

@ -980,6 +980,25 @@ void ui_menu_reset_action(unsigned int value) {
ui_menu_main_display(0);
}
/* ------------------------------ RESET SLOT UX ------------------------------ */
void ui_menu_reset_slot_action(unsigned int value);
UX_STEP_CB(ux_menu_reset_slot_1_step, bnn, ui_menu_settings_display(4), {"Ooops, NO!", "Do not reset", "the key slot"});
UX_STEP_CB(ux_menu_reset_slot_2_step, bn, ui_menu_reset_slot_action(0), {"YES!", "Reset the slot"});
UX_FLOW(ux_flow_reset_slot, &ux_menu_reset_slot_1_step, &ux_menu_reset_slot_2_step);
void ui_menu_reset_slot_display(unsigned int value) {
ux_flow_init(value, ux_flow_reset_slot, NULL);
}
void ui_menu_reset_slot_action(unsigned int value) {
gpg_install_slot(G_gpg_vstate.kslot);
ui_menu_main_display(0);
}
/* ------------------------------- SETTINGS UX ------------------------------- */
const char *const settings_getter_values[] = {"Key template", "Seed mode", "PIN mode", "UIF mode", "Reset", "Back"};

Loading…
Cancel
Save