Update AES use in SmartPGP (ENC/DEC/SM)
This commit is contained in:
parent
a2787abbcf
commit
f8abbd8732
@ -31,9 +31,9 @@ public final class CmacKey {
|
|||||||
protected final byte[] k1;
|
protected final byte[] k1;
|
||||||
protected final byte[] k2;
|
protected final byte[] k2;
|
||||||
|
|
||||||
protected CmacKey() {
|
protected CmacKey(final byte aesKeyLength) {
|
||||||
key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
|
key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
|
||||||
(short)(Constants.aesKeyLength() * 8),
|
(short)(aesKeyLength * 8),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
k1 = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
k1 = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
||||||
|
@ -171,10 +171,6 @@ public final class Constants {
|
|||||||
(byte)0x00 /* MSE not supported */
|
(byte)0x00 /* MSE not supported */
|
||||||
};
|
};
|
||||||
|
|
||||||
protected static final short aesKeyLength() {
|
|
||||||
return (short)(16 * EXTENDED_CAPABILITIES[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static final short challengeMaxLength() {
|
protected static final short challengeMaxLength() {
|
||||||
return Util.getShort(EXTENDED_CAPABILITIES, (short)2);
|
return Util.getShort(EXTENDED_CAPABILITIES, (short)2);
|
||||||
}
|
}
|
||||||
@ -239,7 +235,6 @@ public final class Constants {
|
|||||||
|
|
||||||
protected static final byte[] RSA_EXPONENT = { (byte)0x01, (byte)0x00, (byte)0x01 };
|
protected static final byte[] RSA_EXPONENT = { (byte)0x01, (byte)0x00, (byte)0x01 };
|
||||||
|
|
||||||
|
|
||||||
protected static final short AES_BLOCK_SIZE = (short)16;
|
protected static final short AES_BLOCK_SIZE = (short)16;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -167,13 +167,9 @@ public final class PGPKey {
|
|||||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(is_secure_messaging_key) {
|
if((buf[0] != 0x12) && is_secure_messaging_key) {
|
||||||
if((buf[0] != 0x12) ||
|
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||||
(((short)(Constants.aesKeyLength()* 8) > (short)128) &&
|
return;
|
||||||
(params.nb_bits < 512))) {
|
|
||||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -56,26 +56,26 @@ public final class Persistent {
|
|||||||
protected byte sex;
|
protected byte sex;
|
||||||
|
|
||||||
|
|
||||||
protected byte[] digital_signature_counter;
|
protected final byte[] digital_signature_counter;
|
||||||
|
|
||||||
|
|
||||||
protected byte[] do_0101;
|
protected final byte[] do_0101;
|
||||||
protected short do_0101_length;
|
protected short do_0101_length;
|
||||||
|
|
||||||
protected byte[] do_0102;
|
protected final byte[] do_0102;
|
||||||
protected short do_0102_length;
|
protected short do_0102_length;
|
||||||
|
|
||||||
protected byte[] do_0103;
|
protected final byte[] do_0103;
|
||||||
protected short do_0103_length;
|
protected short do_0103_length;
|
||||||
|
|
||||||
protected byte[] do_0104;
|
protected final 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 final byte[] key_derivation_function;
|
||||||
protected short key_derivation_function_length;
|
protected short key_derivation_function_length;
|
||||||
|
|
||||||
protected final OwnerPIN user_pin; /* PW1 */
|
protected final OwnerPIN user_pin; /* PW1 */
|
||||||
@ -122,9 +122,7 @@ public final class Persistent {
|
|||||||
do_0104 = new byte[Constants.specialDoMaxLength()];
|
do_0104 = new byte[Constants.specialDoMaxLength()];
|
||||||
do_0104_length = 0;
|
do_0104_length = 0;
|
||||||
|
|
||||||
aes_key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
|
aes_key = null;
|
||||||
(short)(Constants.aesKeyLength() * 8),
|
|
||||||
false);
|
|
||||||
|
|
||||||
pgp_keys = new PGPKey[PGP_KEYS_LENGTH];
|
pgp_keys = new PGPKey[PGP_KEYS_LENGTH];
|
||||||
for(byte i = 0; i < pgp_keys.length; ++i) {
|
for(byte i = 0; i < pgp_keys.length; ++i) {
|
||||||
@ -218,7 +216,12 @@ public final class Persistent {
|
|||||||
}
|
}
|
||||||
JCSystem.commitTransaction();
|
JCSystem.commitTransaction();
|
||||||
|
|
||||||
aes_key.clearKey();
|
JCSystem.beginTransaction();
|
||||||
|
if(aes_key != null) {
|
||||||
|
aes_key.clearKey();
|
||||||
|
aes_key = null;
|
||||||
|
}
|
||||||
|
JCSystem.commitTransaction();
|
||||||
|
|
||||||
user_pin_force_verify_signature = Constants.USER_PIN_DEFAULT_FORCE_VERIFY_SIGNATURE;
|
user_pin_force_verify_signature = Constants.USER_PIN_DEFAULT_FORCE_VERIFY_SIGNATURE;
|
||||||
|
|
||||||
|
@ -41,12 +41,11 @@ public final class SecureMessaging {
|
|||||||
private final byte[] mac_chaining;
|
private final byte[] mac_chaining;
|
||||||
|
|
||||||
private final Cipher cipher;
|
private final Cipher cipher;
|
||||||
private final AESKey senc;
|
|
||||||
|
|
||||||
private final CmacSignature macer;
|
private final CmacSignature macer;
|
||||||
private final CmacKey smac;
|
private AESKey senc;
|
||||||
private final CmacKey srmac;
|
private CmacKey smac;
|
||||||
private final CmacKey sreceiptmac;
|
private CmacKey srmac;
|
||||||
|
|
||||||
protected final PGPKey static_key;
|
protected final PGPKey static_key;
|
||||||
|
|
||||||
@ -61,12 +60,9 @@ public final class SecureMessaging {
|
|||||||
mac_chaining = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE,
|
mac_chaining = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE,
|
||||||
JCSystem.CLEAR_ON_DESELECT);
|
JCSystem.CLEAR_ON_DESELECT);
|
||||||
|
|
||||||
senc = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
|
senc = null;
|
||||||
(short)(Constants.aesKeyLength() * 8),
|
smac = null;
|
||||||
false);
|
srmac = null;
|
||||||
smac = new CmacKey();
|
|
||||||
srmac = new CmacKey();
|
|
||||||
sreceiptmac = new CmacKey();
|
|
||||||
|
|
||||||
static_key = new PGPKey(true);
|
static_key = new PGPKey(true);
|
||||||
|
|
||||||
@ -74,10 +70,18 @@ public final class SecureMessaging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final void clearSession(final Transients transients) {
|
protected final void clearSession(final Transients transients) {
|
||||||
senc.clearKey();
|
if(senc != null) {
|
||||||
smac.clearKey();
|
senc.clearKey();
|
||||||
srmac.clearKey();
|
senc = null;
|
||||||
sreceiptmac.clearKey();
|
}
|
||||||
|
if(smac != null) {
|
||||||
|
smac.clearKey();
|
||||||
|
smac = null;
|
||||||
|
}
|
||||||
|
if(srmac != null) {
|
||||||
|
srmac.clearKey();
|
||||||
|
srmac = null;
|
||||||
|
}
|
||||||
macer.clear();
|
macer.clear();
|
||||||
transients.setSecureMessagingEncryptionCounter((short)0);
|
transients.setSecureMessagingEncryptionCounter((short)0);
|
||||||
Util.arrayFillNonAtomic(iv, (short)0, (short)iv.length, (byte)0);
|
Util.arrayFillNonAtomic(iv, (short)0, (short)iv.length, (byte)0);
|
||||||
@ -95,9 +99,17 @@ public final class SecureMessaging {
|
|||||||
|
|
||||||
protected final boolean isSessionAvailable() {
|
protected final boolean isSessionAvailable() {
|
||||||
return isInitialized()
|
return isInitialized()
|
||||||
&& senc.isInitialized()
|
&& (senc != null) && senc.isInitialized()
|
||||||
&& smac.isInitialized()
|
&& (smac != null) && smac.isInitialized()
|
||||||
&& srmac.isInitialized();
|
&& (srmac != null) && srmac.isInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final byte aesKeyLength(final ECParams params) {
|
||||||
|
if(params.nb_bits < (short)512) {
|
||||||
|
return (byte)16;
|
||||||
|
} else {
|
||||||
|
return (byte)32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final short scp11b(final ECParams params,
|
private final short scp11b(final ECParams params,
|
||||||
@ -123,7 +135,7 @@ public final class SecureMessaging {
|
|||||||
|
|
||||||
short off = (short)crt.length;
|
short off = (short)crt.length;
|
||||||
|
|
||||||
if(buf[off] != Constants.aesKeyLength()) {
|
if(buf[off] != aesKeyLength(params)) {
|
||||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -207,10 +219,31 @@ public final class SecureMessaging {
|
|||||||
buf, (short)(len + msglen + keydata_len));
|
buf, (short)(len + msglen + keydata_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final CmacKey sreceiptmac = new CmacKey(aesKeyLength(params));
|
||||||
sreceiptmac.setKey(buf, (short)(len + msglen));
|
sreceiptmac.setKey(buf, (short)(len + msglen));
|
||||||
senc.setKey(buf, (short)(len + msglen + Constants.aesKeyLength()));
|
|
||||||
smac.setKey(buf, (short)(len + msglen + 2 * Constants.aesKeyLength()));
|
if(senc != null) {
|
||||||
srmac.setKey(buf, (short)(len + msglen + 3 * Constants.aesKeyLength()));
|
senc.clearKey();
|
||||||
|
senc = null;
|
||||||
|
}
|
||||||
|
senc = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
|
||||||
|
(short)(aesKeyLength(params) * 8),
|
||||||
|
false);
|
||||||
|
senc.setKey(buf, (short)(len + msglen + aesKeyLength(params)));
|
||||||
|
|
||||||
|
if(smac != null) {
|
||||||
|
smac.clearKey();
|
||||||
|
smac = null;
|
||||||
|
}
|
||||||
|
smac = new CmacKey(aesKeyLength(params));
|
||||||
|
smac.setKey(buf, (short)(len + msglen + 2 * aesKeyLength(params)));
|
||||||
|
|
||||||
|
if(srmac != null) {
|
||||||
|
srmac.clearKey();
|
||||||
|
srmac = null;
|
||||||
|
}
|
||||||
|
srmac = new CmacKey(aesKeyLength(params));
|
||||||
|
srmac.setKey(buf, (short)(len + msglen + 3 * aesKeyLength(params)));
|
||||||
|
|
||||||
Util.arrayFillNonAtomic(buf, len, (short)(msglen + keydata_len), (byte)0);
|
Util.arrayFillNonAtomic(buf, len, (short)(msglen + keydata_len), (byte)0);
|
||||||
|
|
||||||
@ -254,10 +287,7 @@ public final class SecureMessaging {
|
|||||||
final ECParams params = static_key.ecParams(ec);
|
final ECParams params = static_key.ecParams(ec);
|
||||||
|
|
||||||
if(params != null) {
|
if(params != null) {
|
||||||
if(((short)(Constants.aesKeyLength() * 8) == (short)128) ||
|
return scp11b(params, buf, len);
|
||||||
(params.nb_bits >= 512)) {
|
|
||||||
return scp11b(params, buf, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,11 +926,19 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
|
|
||||||
case Constants.TAG_AES_KEY:
|
case Constants.TAG_AES_KEY:
|
||||||
assertAdmin();
|
assertAdmin();
|
||||||
if(lc != Constants.aesKeyLength()) {
|
if((lc != (short)16) && (lc != (short)32)) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
JCSystem.beginTransaction();
|
||||||
|
if(data.aes_key != null) {
|
||||||
|
data.aes_key.clearKey();
|
||||||
|
}
|
||||||
|
data.aes_key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES,
|
||||||
|
(short)(lc * 8),
|
||||||
|
false);
|
||||||
data.aes_key.setKey(buf, (short)0);
|
data.aes_key.setKey(buf, (short)0);
|
||||||
|
JCSystem.commitTransaction();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Constants.TAG_CARDHOLDER_CERTIFICATE:
|
case Constants.TAG_CARDHOLDER_CERTIFICATE:
|
||||||
@ -1164,12 +1172,12 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
|
|
||||||
if(transients.buffer[0] == (byte)0x02) {
|
if(transients.buffer[0] == (byte)0x02) {
|
||||||
|
|
||||||
if(((short)(lc - 1) % Constants.aesKeyLength()) != 0) {
|
if(((short)(lc - 1) % Constants.AES_BLOCK_SIZE) != 0) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!data.aes_key.isInitialized()) {
|
if((data.aes_key == null) || !data.aes_key.isInitialized()) {
|
||||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1196,12 +1204,12 @@ public final class SmartPGPApplet extends Applet {
|
|||||||
|
|
||||||
assertUserMode82();
|
assertUserMode82();
|
||||||
|
|
||||||
if((lc <= 0) || ((lc % Constants.aesKeyLength()) != 0)) {
|
if((lc <= 0) || ((lc % Constants.AES_BLOCK_SIZE) != 0)) {
|
||||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!data.aes_key.isInitialized()) {
|
if((data.aes_key == null) || !data.aes_key.isInitialized()) {
|
||||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user