implement factory reset

This commit is contained in:
Michele Balistreri 2023-06-06 10:46:46 +02:00
parent 4a04bdacec
commit 039964e8d0
No known key found for this signature in database
GPG Key ID: E9567DA33A4F791A
1 changed files with 42 additions and 10 deletions

View File

@ -13,6 +13,7 @@ public class KeycardApplet extends Applet {
static final byte INS_GET_STATUS = (byte) 0xF2; static final byte INS_GET_STATUS = (byte) 0xF2;
static final byte INS_INIT = (byte) 0xFE; static final byte INS_INIT = (byte) 0xFE;
static final byte INS_FACTORY_RESET = (byte) 0xFD;
static final byte INS_VERIFY_PIN = (byte) 0x20; static final byte INS_VERIFY_PIN = (byte) 0x20;
static final byte INS_CHANGE_PIN = (byte) 0x21; static final byte INS_CHANGE_PIN = (byte) 0x21;
static final byte INS_UNBLOCK_PIN = (byte) 0x22; static final byte INS_UNBLOCK_PIN = (byte) 0x22;
@ -85,6 +86,9 @@ public class KeycardApplet extends Applet {
static final byte STORE_DATA_P1_NDEF = 0x01; static final byte STORE_DATA_P1_NDEF = 0x01;
static final byte STORE_DATA_P1_CASH = 0x02; static final byte STORE_DATA_P1_CASH = 0x02;
static final byte FACTORY_RESET_P1_MAGIC = (byte) 0xAA;
static final byte FACTORY_RESET_P2_MAGIC = 0x55;
static final byte TLV_SIGNATURE_TEMPLATE = (byte) 0xA0; static final byte TLV_SIGNATURE_TEMPLATE = (byte) 0xA0;
static final byte TLV_KEY_TEMPLATE = (byte) 0xA1; static final byte TLV_KEY_TEMPLATE = (byte) 0xA1;
@ -282,6 +286,9 @@ public class KeycardApplet extends Applet {
case INS_STORE_DATA: case INS_STORE_DATA:
storeData(apdu); storeData(apdu);
break; break;
case INS_FACTORY_RESET:
factoryReset(apdu);
break;
default: default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
break; break;
@ -1008,6 +1015,23 @@ public class KeycardApplet extends Applet {
return (short) ((short)((short) 0x4000 >>> (short) (amount - 1)) | tmp); return (short) ((short)((short) 0x4000 >>> (short) (amount - 1)) | tmp);
} }
/**
* Clear all keys and erases the key UID.
*/
private void clearKeys() {
keyPathLen = 0;
pinlessPathLen = 0;
isExtended = false;
masterPrivate.clearKey();
masterPublic.clearKey();
resetCurveParameters();
Util.arrayFillNonAtomic(masterChainCode, (short) 0, (short) masterChainCode.length, (byte) 0);
Util.arrayFillNonAtomic(altChainCode, (short) 0, (short) altChainCode.length, (byte) 0);
Util.arrayFillNonAtomic(keyPath, (short) 0, (short) keyPath.length, (byte) 0);
Util.arrayFillNonAtomic(pinlessPath, (short) 0, (short) pinlessPath.length, (byte) 0);
Util.arrayFillNonAtomic(keyUID, (short) 0, (short) keyUID.length, (byte) 0);
}
/** /**
* Processes the REMOVE KEY command. Removes the master key and all derived keys. Secure Channel and PIN * Processes the REMOVE KEY command. Removes the master key and all derived keys. Secure Channel and PIN
* authentication are required. * authentication are required.
@ -1022,16 +1046,24 @@ public class KeycardApplet extends Applet {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
} }
keyPathLen = 0; clearKeys();
pinlessPathLen = 0; }
isExtended = false;
masterPrivate.clearKey(); private void factoryReset(APDU apdu) {
masterPublic.clearKey(); byte[] apduBuffer = apdu.getBuffer();
resetCurveParameters();
Util.arrayFillNonAtomic(masterChainCode, (short) 0, (short) masterChainCode.length, (byte) 0); if ((apduBuffer[OFFSET_P1] != FACTORY_RESET_P1_MAGIC) || (apduBuffer[OFFSET_P2] != FACTORY_RESET_P2_MAGIC)) {
Util.arrayFillNonAtomic(altChainCode, (short) 0, (short) altChainCode.length, (byte) 0); ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
Util.arrayFillNonAtomic(keyPath, (short) 0, (short) keyPath.length, (byte) 0); }
Util.arrayFillNonAtomic(pinlessPath, (short) 0, (short) pinlessPath.length, (byte) 0);
clearKeys();
pin = null;
altPIN = null;
puk = null;
secureChannel = null;
crypto.random.generateData(uid, (short) 0, UID_LENGTH);
Util.arrayFillNonAtomic(data, (short) 0, (short) data.length, (byte) 0);
JCSystem.requestObjectDeletion();
} }
/** /**