Functional KDF support
This commit is contained in:
parent
f78db3e999
commit
9b77f6c26b
@ -260,4 +260,25 @@ public final class Persistent {
|
|||||||
|
|
||||||
isTerminated = false;
|
isTerminated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final boolean keyDerivationIsActive() {
|
||||||
|
return ((3 <= key_derivation_function_length) &&
|
||||||
|
(key_derivation_function[0] == (byte)0x81) &&
|
||||||
|
(key_derivation_function[2] != (byte)0));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final byte keyDerivationSize() {
|
||||||
|
if(keyDerivationIsActive() &&
|
||||||
|
(6 <= key_derivation_function_length)) {
|
||||||
|
switch(key_derivation_function[5]) {
|
||||||
|
case (byte)0x08:
|
||||||
|
return (byte)32;
|
||||||
|
case (byte)0x0A:
|
||||||
|
return (byte)64;
|
||||||
|
default:
|
||||||
|
return (byte)0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (byte)0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,9 +149,16 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
private final short writePwStatus(final byte[] buf, short off) {
|
private final short writePwStatus(final byte[] buf, short off) {
|
||||||
buf[off++] = (byte)(data.user_pin_force_verify_signature ? 0x00 : 0x01);
|
buf[off++] = (byte)(data.user_pin_force_verify_signature ? 0x00 : 0x01);
|
||||||
|
|
||||||
buf[off++] = Constants.USER_PIN_MAX_SIZE;
|
if(data.keyDerivationIsActive()) {
|
||||||
buf[off++] = Constants.USER_PUK_MAX_SIZE;
|
final byte size = data.keyDerivationSize();
|
||||||
buf[off++] = Constants.ADMIN_PIN_MAX_SIZE;
|
buf[off++] = size;
|
||||||
|
buf[off++] = size;
|
||||||
|
buf[off++] = size;
|
||||||
|
} else {
|
||||||
|
buf[off++] = Constants.USER_PIN_MAX_SIZE;
|
||||||
|
buf[off++] = Constants.USER_PUK_MAX_SIZE;
|
||||||
|
buf[off++] = Constants.ADMIN_PIN_MAX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
buf[off++] = data.user_pin.getTriesRemaining();
|
buf[off++] = data.user_pin.getTriesRemaining();
|
||||||
buf[off++] = data.user_puk.getTriesRemaining();
|
buf[off++] = data.user_puk.getTriesRemaining();
|
||||||
@ -525,10 +532,17 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
switch(p2) {
|
switch(p2) {
|
||||||
case (byte)0x81:
|
case (byte)0x81:
|
||||||
case (byte)0x82:
|
case (byte)0x82:
|
||||||
if((lc < Constants.USER_PIN_MIN_SIZE) ||
|
if(data.keyDerivationIsActive()) {
|
||||||
(lc > Constants.USER_PIN_MAX_SIZE)) {
|
if(lc != data.keyDerivationSize()) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((lc < Constants.USER_PIN_MIN_SIZE) ||
|
||||||
|
(lc > Constants.USER_PIN_MAX_SIZE)) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p2 == (byte)0x81) {
|
if(p2 == (byte)0x81) {
|
||||||
@ -550,10 +564,17 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case (byte)0x83:
|
case (byte)0x83:
|
||||||
if((lc < Constants.ADMIN_PIN_MIN_SIZE) ||
|
if(data.keyDerivationIsActive()) {
|
||||||
(lc > Constants.ADMIN_PIN_MAX_SIZE)) {
|
if(lc != data.keyDerivationSize()) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((lc < Constants.ADMIN_PIN_MIN_SIZE) ||
|
||||||
|
(lc > Constants.ADMIN_PIN_MAX_SIZE)) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!data.admin_pin.check(transients.buffer, (short)0, (byte)lc)) {
|
if(!data.admin_pin.check(transients.buffer, (short)0, (byte)lc)) {
|
||||||
@ -606,6 +627,7 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
sensitiveData();
|
sensitiveData();
|
||||||
|
|
||||||
byte off;
|
byte off;
|
||||||
|
byte minlen;
|
||||||
|
|
||||||
if(p1 != 0) {
|
if(p1 != 0) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
|
ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
|
||||||
@ -614,28 +636,51 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
|
|
||||||
switch(p2) {
|
switch(p2) {
|
||||||
case (byte)0x81:
|
case (byte)0x81:
|
||||||
if((lc < (Constants.USER_PIN_MIN_SIZE + Constants.USER_PIN_MIN_SIZE)) ||
|
minlen = Constants.USER_PIN_MIN_SIZE;
|
||||||
(lc > (Constants.USER_PIN_MAX_SIZE + Constants.USER_PIN_MAX_SIZE))) {
|
if(data.keyDerivationIsActive()) {
|
||||||
|
minlen += data.keyDerivationSize();
|
||||||
|
} else {
|
||||||
|
minlen += Constants.USER_PIN_MIN_SIZE;
|
||||||
|
}
|
||||||
|
if(lc < minlen) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
transients.setUserPinMode81(false);
|
||||||
|
transients.setUserPinMode82(false);
|
||||||
off = data.user_pin_length;
|
off = data.user_pin_length;
|
||||||
if(!data.user_pin.check(transients.buffer, (short)0, off)) {
|
if(!data.user_pin.check(transients.buffer, (short)0, off)) {
|
||||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
transients.setUserPinMode81(false);
|
minlen = (byte)(lc - off);
|
||||||
transients.setUserPinMode82(false);
|
if(data.keyDerivationIsActive()) {
|
||||||
|
if(data.keyDerivationSize() != minlen) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((minlen < Constants.USER_PIN_MIN_SIZE) ||
|
||||||
|
(minlen > Constants.USER_PIN_MAX_SIZE)) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
JCSystem.beginTransaction();
|
JCSystem.beginTransaction();
|
||||||
data.user_pin_length = (byte)(lc - off);
|
data.user_pin_length = minlen;
|
||||||
data.user_pin.update(transients.buffer, off, data.user_pin_length);
|
data.user_pin.update(transients.buffer, off, data.user_pin_length);
|
||||||
JCSystem.commitTransaction();
|
JCSystem.commitTransaction();
|
||||||
data.user_pin.resetAndUnblock();
|
data.user_pin.resetAndUnblock();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (byte)0x83:
|
case (byte)0x83:
|
||||||
if((lc < (Constants.ADMIN_PIN_MIN_SIZE + Constants.ADMIN_PIN_MIN_SIZE)) ||
|
minlen = Constants.ADMIN_PIN_MIN_SIZE;
|
||||||
(lc > (Constants.ADMIN_PIN_MAX_SIZE + Constants.ADMIN_PIN_MAX_SIZE))) {
|
if(data.keyDerivationIsActive()) {
|
||||||
|
minlen += data.keyDerivationSize();
|
||||||
|
} else {
|
||||||
|
minlen += Constants.ADMIN_PIN_MIN_SIZE;
|
||||||
|
}
|
||||||
|
if(lc < minlen) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -644,11 +689,25 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
minlen = (byte)(lc - off);
|
||||||
|
if(data.keyDerivationIsActive()) {
|
||||||
|
if(data.keyDerivationSize() != minlen) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((minlen < Constants.ADMIN_PIN_MIN_SIZE) ||
|
||||||
|
(minlen > Constants.ADMIN_PIN_MAX_SIZE)) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
JCSystem.beginTransaction();
|
JCSystem.beginTransaction();
|
||||||
data.admin_pin_length = (byte)(lc - off);
|
data.admin_pin_length = minlen;
|
||||||
data.admin_pin.update(transients.buffer, off, data.admin_pin_length);
|
data.admin_pin.update(transients.buffer, off, data.admin_pin_length);
|
||||||
JCSystem.commitTransaction();
|
JCSystem.commitTransaction();
|
||||||
data.admin_pin.resetAndUnblock();;
|
data.admin_pin.resetAndUnblock();
|
||||||
|
data.admin_pin.check(transients.buffer, off, data.admin_pin_length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -663,6 +722,7 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
sensitiveData();
|
sensitiveData();
|
||||||
|
|
||||||
byte off = 0;
|
byte off = 0;
|
||||||
|
byte minlen;
|
||||||
|
|
||||||
if(p2 != (byte)0x81) {
|
if(p2 != (byte)0x81) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
|
ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
|
||||||
@ -671,20 +731,38 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
|
|
||||||
switch(p1) {
|
switch(p1) {
|
||||||
case (byte)0x00:
|
case (byte)0x00:
|
||||||
if((lc < (Constants.USER_PUK_MIN_SIZE + Constants.USER_PIN_MIN_SIZE)) ||
|
minlen = Constants.USER_PUK_MIN_SIZE;
|
||||||
(lc > (Constants.USER_PUK_MAX_SIZE + Constants.USER_PIN_MAX_SIZE))) {
|
if(data.keyDerivationIsActive()) {
|
||||||
|
minlen += data.keyDerivationSize();
|
||||||
|
} else {
|
||||||
|
minlen += Constants.USER_PIN_MIN_SIZE;
|
||||||
|
}
|
||||||
|
if(lc < minlen) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
transients.setUserPinMode81(false);
|
||||||
|
transients.setUserPinMode82(false);
|
||||||
off = data.user_puk_length;
|
off = data.user_puk_length;
|
||||||
if(!data.user_puk.check(transients.buffer, (short)0, off)) {
|
if(!data.user_puk.check(transients.buffer, (short)0, off)) {
|
||||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
transients.setUserPinMode81(false);
|
minlen = (byte)(lc - off);
|
||||||
transients.setUserPinMode82(false);
|
if(data.keyDerivationIsActive()) {
|
||||||
|
if(data.keyDerivationSize() != minlen) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((minlen < Constants.USER_PIN_MIN_SIZE) ||
|
||||||
|
(minlen > Constants.USER_PIN_MAX_SIZE)) {
|
||||||
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
JCSystem.beginTransaction();
|
JCSystem.beginTransaction();
|
||||||
data.user_pin_length = (byte)(lc - off);
|
data.user_pin_length = minlen;
|
||||||
data.user_pin.update(transients.buffer, off, data.user_pin_length);
|
data.user_pin.update(transients.buffer, off, data.user_pin_length);
|
||||||
JCSystem.commitTransaction();
|
JCSystem.commitTransaction();
|
||||||
data.user_pin.resetAndUnblock();
|
data.user_pin.resetAndUnblock();
|
||||||
|
Loading…
Reference in New Issue
Block a user