OpenPGP card v3.3 : support KDF-DO

This commit is contained in:
Arnaud Fontaine 2017-05-22 16:18:56 +02:00
parent b92c7f3dec
commit d37a471067
3 changed files with 49 additions and 2 deletions

View File

@ -32,6 +32,11 @@ public final class Constants {
protected static final short APDU_MAX_LENGTH = (short)256; protected static final short APDU_MAX_LENGTH = (short)256;
protected static final short KEY_DERIVATION_FUNCTION_MIN_LENGTH = 2;
protected static final short KEY_DERIVATION_FUNCTION_MAX_LENGTH = 160;
protected static final byte[] KEY_DERIVATION_FUNCTION_DEFAULT = {
(byte)0xF9, (byte)0x00
};
protected static final byte USER_PIN_RETRY_COUNT = 3; protected static final byte USER_PIN_RETRY_COUNT = 3;
protected static final byte USER_PIN_MIN_SIZE = 0x06; protected static final byte USER_PIN_MIN_SIZE = 0x06;
@ -100,6 +105,7 @@ public final class Constants {
protected static final short TAG_PRIVATE_DO_0103 = (short)0x0103; protected static final short TAG_PRIVATE_DO_0103 = (short)0x0103;
protected static final short TAG_PRIVATE_DO_0104 = (short)0x0104; protected static final short TAG_PRIVATE_DO_0104 = (short)0x0104;
protected static final short TAG_AES_KEY = (short)0x00d5; protected static final short TAG_AES_KEY = (short)0x00d5;
protected static final short TAG_KEY_DERIVATION_FUNCTION = (short)0x00f9;
protected static final short CRT_AUTHENTICATION_KEY = (short)0xa400; protected static final short CRT_AUTHENTICATION_KEY = (short)0xa400;
protected static final short CRT_SECURE_MESSAGING_KEY = (short)0xa600; protected static final short CRT_SECURE_MESSAGING_KEY = (short)0xa600;
@ -157,7 +163,8 @@ public final class Constants {
0x10 | /* support pw status changes */ 0x10 | /* support pw status changes */
0x08 | /* support private DOs (0101-0104) */ 0x08 | /* support private DOs (0101-0104) */
0x04 | /* support algorithm attributes changes */ 0x04 | /* support algorithm attributes changes */
0x02), /* support PSO:DEC AES */ 0x02 | /* support PSO:DEC AES */
0x01), /* support KDF-DO */
(byte)0x01, /* SM 0x01 = 128 bits, 0x02 = 256 bits */ (byte)0x01, /* SM 0x01 = 128 bits, 0x02 = 256 bits */
(byte)0x00, (byte)0x20, /* max length get challenge */ (byte)0x00, (byte)0x20, /* max length get challenge */
(byte)0x04, (byte)0x80, /* max length of carholder certificate */ (byte)0x04, (byte)0x80, /* max length of carholder certificate */

View File

@ -71,9 +71,12 @@ public final class Persistent {
protected byte[] do_0104; protected byte[] do_0104;
protected short do_0104_length; protected short do_0104_length;
protected AESKey aes_key; protected AESKey aes_key;
protected byte[] key_derivation_function;
protected short key_derivation_function_length;
protected final OwnerPIN user_pin; /* PW1 */ protected final OwnerPIN user_pin; /* PW1 */
protected byte user_pin_length; protected byte user_pin_length;
@ -128,6 +131,9 @@ public final class Persistent {
pgp_keys[i] = new PGPKey(false); pgp_keys[i] = new PGPKey(false);
} }
key_derivation_function = new byte[Constants.KEY_DERIVATION_FUNCTION_MAX_LENGTH];
key_derivation_function_length = 0;
user_pin = new OwnerPIN(Constants.USER_PIN_RETRY_COUNT, Constants.USER_PIN_MAX_SIZE); user_pin = new OwnerPIN(Constants.USER_PIN_RETRY_COUNT, Constants.USER_PIN_MAX_SIZE);
user_puk = new OwnerPIN(Constants.USER_PUK_RETRY_COUNT, Constants.USER_PUK_MAX_SIZE); user_puk = new OwnerPIN(Constants.USER_PUK_RETRY_COUNT, Constants.USER_PUK_MAX_SIZE);
admin_pin = new OwnerPIN(Constants.ADMIN_PIN_RETRY_COUNT, Constants.ADMIN_PIN_MAX_SIZE); admin_pin = new OwnerPIN(Constants.ADMIN_PIN_RETRY_COUNT, Constants.ADMIN_PIN_MAX_SIZE);
@ -169,7 +175,9 @@ public final class Persistent {
if(lang_length > 0) { if(lang_length > 0) {
Util.arrayFillNonAtomic(lang, (short)0, lang_length, (byte)0); Util.arrayFillNonAtomic(lang, (short)0, lang_length, (byte)0);
} }
Util.arrayCopyNonAtomic(Constants.LANG_DEFAULT, (short)0, lang, (short)0, (short)Constants.LANG_DEFAULT.length); Util.arrayCopyNonAtomic(Constants.LANG_DEFAULT, (short)0,
lang, (short)0,
(short)Constants.LANG_DEFAULT.length);
lang_length = (byte)Constants.LANG_DEFAULT.length; lang_length = (byte)Constants.LANG_DEFAULT.length;
JCSystem.commitTransaction(); JCSystem.commitTransaction();
@ -214,6 +222,16 @@ public final class Persistent {
user_pin_force_verify_signature = Constants.USER_PIN_DEFAULT_FORCE_VERIFY_SIGNATURE; user_pin_force_verify_signature = Constants.USER_PIN_DEFAULT_FORCE_VERIFY_SIGNATURE;
JCSystem.beginTransaction();
if(key_derivation_function_length > 0) {
Util.arrayFillNonAtomic(key_derivation_function, (short)0, key_derivation_function_length, (byte)0);
}
Util.arrayCopyNonAtomic(Constants.KEY_DERIVATION_FUNCTION_DEFAULT, (short)0,
key_derivation_function, (short)0,
(short)Constants.KEY_DERIVATION_FUNCTION_DEFAULT.length);
key_derivation_function_length = (short)Constants.KEY_DERIVATION_FUNCTION_DEFAULT.length;
JCSystem.commitTransaction();
JCSystem.beginTransaction(); JCSystem.beginTransaction();
user_pin_length = (byte)Constants.USER_PIN_DEFAULT.length; user_pin_length = (byte)Constants.USER_PIN_DEFAULT.length;
user_pin.update(Constants.USER_PIN_DEFAULT, (short)0, user_pin_length); user_pin.update(Constants.USER_PIN_DEFAULT, (short)0, user_pin_length);

View File

@ -447,6 +447,12 @@ public final class SmartPGPApplet extends Applet {
k.certificate_length); k.certificate_length);
break; break;
case Constants.TAG_KEY_DERIVATION_FUNCTION:
off = Util.arrayCopyNonAtomic(data.key_derivation_function, (short)0,
buf, off,
data.key_derivation_function_length);
break;
default: default:
ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND); ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND);
return 0; return 0;
@ -1031,6 +1037,22 @@ public final class SmartPGPApplet extends Applet {
JCSystem.commitTransaction(); JCSystem.commitTransaction();
break; break;
case Constants.TAG_KEY_DERIVATION_FUNCTION:
assertAdmin();
if((lc < Constants.KEY_DERIVATION_FUNCTION_MIN_LENGTH) ||
(lc > Constants.KEY_DERIVATION_FUNCTION_MAX_LENGTH)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
return;
}
JCSystem.beginTransaction();
if(data.key_derivation_function_length > 0) {
Util.arrayFillNonAtomic(data.key_derivation_function, (short)0, data.key_derivation_function_length, (byte)0);
}
Util.arrayCopyNonAtomic(buf, (short)0, data.key_derivation_function, (short)0, lc);
data.key_derivation_function_length = (byte)lc;
JCSystem.commitTransaction();
break;
default: default:
ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND); ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND);
return; return;