Version without elliptic curves and secure messaging compatible with JavaCard 3.0.1
This commit is contained in:
parent
ab7baa6a55
commit
309dbbad8a
@ -1,85 +0,0 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/SmartPGP
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
import javacard.framework.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.apdu.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public final class CmacKey {
|
||||
|
||||
protected final AESKey key;
|
||||
protected final byte[] k1;
|
||||
protected final byte[] k2;
|
||||
|
||||
protected CmacKey(final short aesKeyLength) {
|
||||
key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
|
||||
(short)(aesKeyLength * 8),
|
||||
false);
|
||||
|
||||
k1 = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
||||
|
||||
k2 = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
||||
}
|
||||
|
||||
protected final boolean isInitialized() {
|
||||
return key.isInitialized();
|
||||
}
|
||||
|
||||
protected final void clearKey() {
|
||||
key.clearKey();
|
||||
Util.arrayFillNonAtomic(k1, (short)0, (short)k1.length, (byte)0);
|
||||
Util.arrayFillNonAtomic(k2, (short)0, (short)k2.length, (byte)0);
|
||||
}
|
||||
|
||||
protected final short getSize() {
|
||||
return key.getSize();
|
||||
}
|
||||
|
||||
protected final void setKey(final byte[] buf, final short bufOff) {
|
||||
key.setKey(buf, bufOff);
|
||||
|
||||
final Cipher cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
|
||||
|
||||
cipher.init(key, Cipher.MODE_ENCRYPT);
|
||||
|
||||
Util.arrayFillNonAtomic(k2, (short)0, Constants.AES_BLOCK_SIZE, (byte)0);
|
||||
cipher.doFinal(k2, (short)0, Constants.AES_BLOCK_SIZE,
|
||||
k1, (short)0);
|
||||
|
||||
final boolean mark = ((k1[0] & (byte)0x80) != (byte)0);
|
||||
Common.arrayLeftShift(k1, (short)0,
|
||||
k1, (short)0,
|
||||
Constants.AES_BLOCK_SIZE);
|
||||
if(mark) {
|
||||
k1[(short)(Constants.AES_BLOCK_SIZE - 1)] = (byte)(k1[(short)(Constants.AES_BLOCK_SIZE - 1)] ^ (byte)0x87);
|
||||
}
|
||||
|
||||
Common.arrayLeftShift(k1, (short)0,
|
||||
k2, (short)0,
|
||||
Constants.AES_BLOCK_SIZE);
|
||||
if((k1[0] & (byte)0x80) != (byte)0) {
|
||||
k2[(short)(Constants.AES_BLOCK_SIZE - 1)] = (byte)(k2[(short)(Constants.AES_BLOCK_SIZE - 1)] ^ (byte)0x87);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,234 +0,0 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/SmartPGP
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
import javacard.framework.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.apdu.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public final class CmacSignature {
|
||||
|
||||
private CmacKey key;
|
||||
|
||||
private final Cipher cipher;
|
||||
|
||||
private final byte[] block_prev;
|
||||
private final byte[] block;
|
||||
|
||||
private final byte[] bytes;
|
||||
private static final byte BYTE_OFFSET_BLOCK_LEN = 0;
|
||||
private static final byte BYTES_SIZE = BYTE_OFFSET_BLOCK_LEN + 1;
|
||||
|
||||
|
||||
protected CmacSignature() {
|
||||
key = null;
|
||||
|
||||
cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
|
||||
|
||||
block_prev = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
||||
block = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
||||
|
||||
bytes = JCSystem.makeTransientByteArray(BYTES_SIZE, JCSystem.CLEAR_ON_DESELECT);
|
||||
}
|
||||
|
||||
protected final void clear() {
|
||||
if(key != null) {
|
||||
if(key.isInitialized()) {
|
||||
key.clearKey();
|
||||
}
|
||||
key = null;
|
||||
}
|
||||
}
|
||||
|
||||
private final byte blockLen() {
|
||||
return bytes[BYTE_OFFSET_BLOCK_LEN];
|
||||
}
|
||||
|
||||
private final void setBlockLen(final byte len) {
|
||||
bytes[BYTE_OFFSET_BLOCK_LEN] = len;
|
||||
}
|
||||
|
||||
|
||||
protected final boolean isInitialized() {
|
||||
return (key != null)
|
||||
&& key.isInitialized();
|
||||
}
|
||||
|
||||
private final void initBlock() {
|
||||
Util.arrayFillNonAtomic(block_prev, (short)0, (short)block_prev.length, (byte)0);
|
||||
Util.arrayFillNonAtomic(block, (short)0, (short)block.length, (byte)0);
|
||||
Util.arrayFillNonAtomic(bytes, (short)0, (short)bytes.length, (byte)0);
|
||||
}
|
||||
|
||||
protected final void init(final CmacKey key) {
|
||||
if((key == null) || !key.isInitialized()) {
|
||||
CryptoException.throwIt(CryptoException.UNINITIALIZED_KEY);
|
||||
return;
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
|
||||
cipher.init(key.key, Cipher.MODE_ENCRYPT);
|
||||
|
||||
initBlock();
|
||||
}
|
||||
|
||||
private final void commitBlock() {
|
||||
setBlockLen((byte)0);
|
||||
|
||||
Common.arrayXor(block_prev, (short)0,
|
||||
block, (short)0,
|
||||
block, (short)0,
|
||||
Constants.AES_BLOCK_SIZE);
|
||||
|
||||
cipher.doFinal(block, (short)0, Constants.AES_BLOCK_SIZE,
|
||||
block_prev, (short)0);
|
||||
}
|
||||
|
||||
protected final void update(final byte[] inBuf, short inOff, short inLen) {
|
||||
|
||||
if(!isInitialized()) {
|
||||
CryptoException.throwIt(CryptoException.INVALID_INIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if(inLen <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
short bl = (short)blockLen();
|
||||
|
||||
short remLen = (short)(Constants.AES_BLOCK_SIZE - bl);
|
||||
|
||||
while(inLen >= remLen) {
|
||||
Util.arrayCopyNonAtomic(inBuf, inOff,
|
||||
block, bl,
|
||||
remLen);
|
||||
commitBlock();
|
||||
|
||||
inLen -= remLen;
|
||||
inOff += remLen;
|
||||
|
||||
remLen = Constants.AES_BLOCK_SIZE;
|
||||
bl = (short)0;
|
||||
}
|
||||
|
||||
if(inLen > 0) {
|
||||
Util.arrayCopyNonAtomic(inBuf, inOff,
|
||||
block, bl,
|
||||
inLen);
|
||||
|
||||
bl = (short)(bl + inLen);
|
||||
}
|
||||
|
||||
setBlockLen((byte)bl);
|
||||
}
|
||||
|
||||
protected final void updateByte(final byte b) {
|
||||
if(!isInitialized()) {
|
||||
CryptoException.throwIt(CryptoException.INVALID_INIT);
|
||||
return;
|
||||
}
|
||||
|
||||
short bl = blockLen();
|
||||
|
||||
block[bl++] = b;
|
||||
|
||||
if(bl == Constants.AES_BLOCK_SIZE) {
|
||||
commitBlock();
|
||||
} else {
|
||||
setBlockLen((byte)bl);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void updateShort(final short s) {
|
||||
updateByte((byte)((s >> 8) & (byte)0xff));
|
||||
updateByte((byte)(s & (byte)0xff));
|
||||
}
|
||||
|
||||
private final void compute(final byte[] inBuf, short inOff, short inLen) {
|
||||
if(!isInitialized()) {
|
||||
CryptoException.throwIt(CryptoException.INVALID_INIT);
|
||||
return;
|
||||
}
|
||||
|
||||
if(inLen < 0) {
|
||||
CryptoException.throwIt(CryptoException.ILLEGAL_USE);
|
||||
return;
|
||||
}
|
||||
|
||||
short bl = blockLen();
|
||||
|
||||
if(inLen > 0) {
|
||||
final short il = (short)(inLen - 1);
|
||||
|
||||
update(inBuf, inOff, il);
|
||||
|
||||
bl = blockLen();
|
||||
|
||||
block[bl++] = inBuf[(short)(inOff + il)];
|
||||
|
||||
setBlockLen((byte)bl);
|
||||
}
|
||||
|
||||
if(bl == Constants.AES_BLOCK_SIZE) {
|
||||
Common.arrayXor(key.k1, (short)0,
|
||||
block, (short)0,
|
||||
block, (short)0,
|
||||
Constants.AES_BLOCK_SIZE);
|
||||
} else {
|
||||
block[bl++] = (byte)0x80;
|
||||
Util.arrayFillNonAtomic(block, bl, (short)(Constants.AES_BLOCK_SIZE - bl), (byte)0);
|
||||
Common.arrayXor(key.k2, (short)0,
|
||||
block, (short)0,
|
||||
block, (short)0,
|
||||
Constants.AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
commitBlock();
|
||||
}
|
||||
|
||||
protected final short sign(final byte[] inBuf, short inOff, short inLen,
|
||||
final byte[] sigBuf, final short sigOff, final short sigLen) {
|
||||
|
||||
if(!isInitialized()) {
|
||||
CryptoException.throwIt(CryptoException.INVALID_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((sigLen < 0) || (sigLen > Constants.AES_BLOCK_SIZE)) {
|
||||
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
compute(inBuf, inOff, inLen);
|
||||
|
||||
Util.arrayCopyNonAtomic(block_prev, (short)0,
|
||||
sigBuf, sigOff,
|
||||
sigLen);
|
||||
|
||||
init(key);
|
||||
|
||||
return sigLen;
|
||||
}
|
||||
|
||||
}
|
@ -83,14 +83,6 @@ public final class Common {
|
||||
}
|
||||
}
|
||||
|
||||
protected static final short aesKeyLength(final ECParams params) {
|
||||
if(params.nb_bits < (short)512) {
|
||||
return (short)16;
|
||||
} else {
|
||||
return (short)32;
|
||||
}
|
||||
}
|
||||
|
||||
protected static final short writeLength(final byte[] buf, short off, final short len) {
|
||||
if(len > 0xff) {
|
||||
buf[off] = (byte)0x82;
|
||||
|
@ -107,7 +107,6 @@ public final class Constants {
|
||||
protected static final short TAG_ALGORITHM_ATTRIBUTES_SIG = (short)0x00c1;
|
||||
protected static final short TAG_ALGORITHM_ATTRIBUTES_DEC = (short)0x00c2;
|
||||
protected static final short TAG_ALGORITHM_ATTRIBUTES_AUT = (short)0x00c3;
|
||||
protected static final short TAG_ALGORITHM_ATTRIBUTES_SM = (short)0x00d4;
|
||||
protected static final short TAG_PW_STATUS = (short)0x00c4;
|
||||
protected static final short TAG_KEY_FINGERPRINTS = (short)0x00c5;
|
||||
protected static final short TAG_CA_FINGERPRINTS = (short)0x00c6;
|
||||
@ -131,12 +130,10 @@ public final class Constants {
|
||||
protected static final short TAG_KEY_DERIVATION_FUNCTION = (short)0x00f9;
|
||||
|
||||
protected static final short CRT_AUTHENTICATION_KEY = (short)0xa400;
|
||||
protected static final short CRT_SECURE_MESSAGING_KEY = (short)0xa600;
|
||||
protected static final short CRT_SIGNATURE_KEY = (short)0xb600;
|
||||
protected static final short CRT_DECRYPTION_KEY = (short)0xb800;
|
||||
|
||||
protected static final byte CLA_MASK_CHAINING = (byte)0x10;
|
||||
protected static final byte CLA_MASK_SECURE_MESSAGING = (byte)0x04;
|
||||
|
||||
|
||||
protected static final byte INS_SELECT_DATA = (byte)0xA5;
|
||||
@ -188,7 +185,7 @@ public final class Constants {
|
||||
0x04 | /* support algorithm attributes changes */
|
||||
0x02 | /* support PSO:DEC/ENC AES */
|
||||
0x01), /* support KDF-DO */
|
||||
(byte)0x03, /* SM 0x01 = 128 bits, 0x02 = 256 bits, 0x03 = SCP11b */
|
||||
(byte)0x00, /* SM 0x01 = 128 bits, 0x02 = 256 bits, 0x03 = SCP11b */
|
||||
(byte)0x00, (byte)0x20, /* max length get challenge */
|
||||
(byte)0x04, (byte)0x80, /* max length of carholder certificate */
|
||||
(byte)0x00, (byte)0xff, /* max length of special DOs (private, login, url, KDF-DO) */
|
||||
@ -252,12 +249,6 @@ public final class Constants {
|
||||
(byte)0x03 /* crt form with modulus */
|
||||
};
|
||||
|
||||
protected static final byte[] ALGORITHM_ATTRIBUTES_DEFAULT_SECURE_MESSAGING = {
|
||||
(byte)0x12, /* ECDH */
|
||||
(byte)0x2A, (byte)0x86, (byte)0x48, (byte)0xCE, (byte)0x3D, (byte)0x03, (byte)0x01, (byte)0x07, /* ansix9p256r1 */
|
||||
(byte)0xFF /* with public key */
|
||||
};
|
||||
|
||||
protected static final byte[] RSA_EXPONENT = { (byte)0x01, (byte)0x00, (byte)0x01 };
|
||||
|
||||
protected static final short AES_BLOCK_SIZE = (short)16;
|
||||
|
@ -1,605 +0,0 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/SmartPGP
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
public final class ECConstants {
|
||||
|
||||
protected static final byte[] ansix9p256r1_oid =
|
||||
{ (byte)0x2A, (byte)0x86, (byte)0x48, (byte)0xCE, (byte)0x3D, (byte)0x03, (byte)0x01, (byte)0x07 };
|
||||
|
||||
protected static final byte[] ansix9p256r1_field = {
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p256r1_a = {
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFC
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p256r1_b = {
|
||||
(byte)0x5A, (byte)0xC6, (byte)0x35, (byte)0xD8,
|
||||
(byte)0xAA, (byte)0x3A, (byte)0x93, (byte)0xE7,
|
||||
(byte)0xB3, (byte)0xEB, (byte)0xBD, (byte)0x55,
|
||||
(byte)0x76, (byte)0x98, (byte)0x86, (byte)0xBC,
|
||||
(byte)0x65, (byte)0x1D, (byte)0x06, (byte)0xB0,
|
||||
(byte)0xCC, (byte)0x53, (byte)0xB0, (byte)0xF6,
|
||||
(byte)0x3B, (byte)0xCE, (byte)0x3C, (byte)0x3E,
|
||||
(byte)0x27, (byte)0xD2, (byte)0x60, (byte)0x4B
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p256r1_g = {
|
||||
(byte)0x04,
|
||||
(byte)0x6B, (byte)0x17, (byte)0xD1, (byte)0xF2,
|
||||
(byte)0xE1, (byte)0x2C, (byte)0x42, (byte)0x47,
|
||||
(byte)0xF8, (byte)0xBC, (byte)0xE6, (byte)0xE5,
|
||||
(byte)0x63, (byte)0xA4, (byte)0x40, (byte)0xF2,
|
||||
(byte)0x77, (byte)0x03, (byte)0x7D, (byte)0x81,
|
||||
(byte)0x2D, (byte)0xEB, (byte)0x33, (byte)0xA0,
|
||||
(byte)0xF4, (byte)0xA1, (byte)0x39, (byte)0x45,
|
||||
(byte)0xD8, (byte)0x98, (byte)0xC2, (byte)0x96,
|
||||
(byte)0x4F, (byte)0xE3, (byte)0x42, (byte)0xE2,
|
||||
(byte)0xFE, (byte)0x1A, (byte)0x7F, (byte)0x9B,
|
||||
(byte)0x8E, (byte)0xE7, (byte)0xEB, (byte)0x4A,
|
||||
(byte)0x7C, (byte)0x0F, (byte)0x9E, (byte)0x16,
|
||||
(byte)0x2B, (byte)0xCE, (byte)0x33, (byte)0x57,
|
||||
(byte)0x6B, (byte)0x31, (byte)0x5E, (byte)0xCE,
|
||||
(byte)0xCB, (byte)0xB6, (byte)0x40, (byte)0x68,
|
||||
(byte)0x37, (byte)0xBF, (byte)0x51, (byte)0xF5
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p256r1_r = {
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xBC, (byte)0xE6, (byte)0xFA, (byte)0xAD,
|
||||
(byte)0xA7, (byte)0x17, (byte)0x9E, (byte)0x84,
|
||||
(byte)0xF3, (byte)0xB9, (byte)0xCA, (byte)0xC2,
|
||||
(byte)0xFC, (byte)0x63, (byte)0x25, (byte)0x51
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected static final byte[] ansix9p384r1_oid =
|
||||
{ (byte)0x2B, (byte)0x81, (byte)0x04, (byte)0x00, (byte)0x22 };
|
||||
|
||||
protected static final byte[] ansix9p384r1_field = {
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFE,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p384r1_a = {
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFE,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFC
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p384r1_b = {
|
||||
(byte)0xB3, (byte)0x31, (byte)0x2F, (byte)0xA7,
|
||||
(byte)0xE2, (byte)0x3E, (byte)0xE7, (byte)0xE4,
|
||||
(byte)0x98, (byte)0x8E, (byte)0x05, (byte)0x6B,
|
||||
(byte)0xE3, (byte)0xF8, (byte)0x2D, (byte)0x19,
|
||||
(byte)0x18, (byte)0x1D, (byte)0x9C, (byte)0x6E,
|
||||
(byte)0xFE, (byte)0x81, (byte)0x41, (byte)0x12,
|
||||
(byte)0x03, (byte)0x14, (byte)0x08, (byte)0x8F,
|
||||
(byte)0x50, (byte)0x13, (byte)0x87, (byte)0x5A,
|
||||
(byte)0xC6, (byte)0x56, (byte)0x39, (byte)0x8D,
|
||||
(byte)0x8A, (byte)0x2E, (byte)0xD1, (byte)0x9D,
|
||||
(byte)0x2A, (byte)0x85, (byte)0xC8, (byte)0xED,
|
||||
(byte)0xD3, (byte)0xEC, (byte)0x2A, (byte)0xEF
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p384r1_g = {
|
||||
(byte)0x04,
|
||||
(byte)0xAA, (byte)0x87, (byte)0xCA, (byte)0x22,
|
||||
(byte)0xBE, (byte)0x8B, (byte)0x05, (byte)0x37,
|
||||
(byte)0x8E, (byte)0xB1, (byte)0xC7, (byte)0x1E,
|
||||
(byte)0xF3, (byte)0x20, (byte)0xAD, (byte)0x74,
|
||||
(byte)0x6E, (byte)0x1D, (byte)0x3B, (byte)0x62,
|
||||
(byte)0x8B, (byte)0xA7, (byte)0x9B, (byte)0x98,
|
||||
(byte)0x59, (byte)0xF7, (byte)0x41, (byte)0xE0,
|
||||
(byte)0x82, (byte)0x54, (byte)0x2A, (byte)0x38,
|
||||
(byte)0x55, (byte)0x02, (byte)0xF2, (byte)0x5D,
|
||||
(byte)0xBF, (byte)0x55, (byte)0x29, (byte)0x6C,
|
||||
(byte)0x3A, (byte)0x54, (byte)0x5E, (byte)0x38,
|
||||
(byte)0x72, (byte)0x76, (byte)0x0A, (byte)0xB7,
|
||||
(byte)0x36, (byte)0x17, (byte)0xDE, (byte)0x4A,
|
||||
(byte)0x96, (byte)0x26, (byte)0x2C, (byte)0x6F,
|
||||
(byte)0x5D, (byte)0x9E, (byte)0x98, (byte)0xBF,
|
||||
(byte)0x92, (byte)0x92, (byte)0xDC, (byte)0x29,
|
||||
(byte)0xF8, (byte)0xF4, (byte)0x1D, (byte)0xBD,
|
||||
(byte)0x28, (byte)0x9A, (byte)0x14, (byte)0x7C,
|
||||
(byte)0xE9, (byte)0xDA, (byte)0x31, (byte)0x13,
|
||||
(byte)0xB5, (byte)0xF0, (byte)0xB8, (byte)0xC0,
|
||||
(byte)0x0A, (byte)0x60, (byte)0xB1, (byte)0xCE,
|
||||
(byte)0x1D, (byte)0x7E, (byte)0x81, (byte)0x9D,
|
||||
(byte)0x7A, (byte)0x43, (byte)0x1D, (byte)0x7C,
|
||||
(byte)0x90, (byte)0xEA, (byte)0x0E, (byte)0x5F
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p384r1_r = {
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xC7, (byte)0x63, (byte)0x4D, (byte)0x81,
|
||||
(byte)0xF4, (byte)0x37, (byte)0x2D, (byte)0xDF,
|
||||
(byte)0x58, (byte)0x1A, (byte)0x0D, (byte)0xB2,
|
||||
(byte)0x48, (byte)0xB0, (byte)0xA7, (byte)0x7A,
|
||||
(byte)0xEC, (byte)0xEC, (byte)0x19, (byte)0x6A,
|
||||
(byte)0xCC, (byte)0xC5, (byte)0x29, (byte)0x73
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected static final byte[] ansix9p521r1_oid =
|
||||
{ (byte)0x2B, (byte)0x81, (byte)0x04, (byte)0x00, (byte)0x23 };
|
||||
|
||||
protected static final byte[] ansix9p521r1_field = {
|
||||
(byte)0x01, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p521r1_a = {
|
||||
(byte)0x01, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFC
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p521r1_b = {
|
||||
(byte)0x00, (byte)0x51, (byte)0x95, (byte)0x3E,
|
||||
(byte)0xB9, (byte)0x61, (byte)0x8E, (byte)0x1C,
|
||||
(byte)0x9A, (byte)0x1F, (byte)0x92, (byte)0x9A,
|
||||
(byte)0x21, (byte)0xA0, (byte)0xB6, (byte)0x85,
|
||||
(byte)0x40, (byte)0xEE, (byte)0xA2, (byte)0xDA,
|
||||
(byte)0x72, (byte)0x5B, (byte)0x99, (byte)0xB3,
|
||||
(byte)0x15, (byte)0xF3, (byte)0xB8, (byte)0xB4,
|
||||
(byte)0x89, (byte)0x91, (byte)0x8E, (byte)0xF1,
|
||||
(byte)0x09, (byte)0xE1, (byte)0x56, (byte)0x19,
|
||||
(byte)0x39, (byte)0x51, (byte)0xEC, (byte)0x7E,
|
||||
(byte)0x93, (byte)0x7B, (byte)0x16, (byte)0x52,
|
||||
(byte)0xC0, (byte)0xBD, (byte)0x3B, (byte)0xB1,
|
||||
(byte)0xBF, (byte)0x07, (byte)0x35, (byte)0x73,
|
||||
(byte)0xDF, (byte)0x88, (byte)0x3D, (byte)0x2C,
|
||||
(byte)0x34, (byte)0xF1, (byte)0xEF, (byte)0x45,
|
||||
(byte)0x1F, (byte)0xD4, (byte)0x6B, (byte)0x50,
|
||||
(byte)0x3F, (byte)0x00
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p521r1_g = {
|
||||
(byte)0x04,
|
||||
(byte)0x00, (byte)0xC6, (byte)0x85, (byte)0x8E,
|
||||
(byte)0x06, (byte)0xB7, (byte)0x04, (byte)0x04,
|
||||
(byte)0xE9, (byte)0xCD, (byte)0x9E, (byte)0x3E,
|
||||
(byte)0xCB, (byte)0x66, (byte)0x23, (byte)0x95,
|
||||
(byte)0xB4, (byte)0x42, (byte)0x9C, (byte)0x64,
|
||||
(byte)0x81, (byte)0x39, (byte)0x05, (byte)0x3F,
|
||||
(byte)0xB5, (byte)0x21, (byte)0xF8, (byte)0x28,
|
||||
(byte)0xAF, (byte)0x60, (byte)0x6B, (byte)0x4D,
|
||||
(byte)0x3D, (byte)0xBA, (byte)0xA1, (byte)0x4B,
|
||||
(byte)0x5E, (byte)0x77, (byte)0xEF, (byte)0xE7,
|
||||
(byte)0x59, (byte)0x28, (byte)0xFE, (byte)0x1D,
|
||||
(byte)0xC1, (byte)0x27, (byte)0xA2, (byte)0xFF,
|
||||
(byte)0xA8, (byte)0xDE, (byte)0x33, (byte)0x48,
|
||||
(byte)0xB3, (byte)0xC1, (byte)0x85, (byte)0x6A,
|
||||
(byte)0x42, (byte)0x9B, (byte)0xF9, (byte)0x7E,
|
||||
(byte)0x7E, (byte)0x31, (byte)0xC2, (byte)0xE5,
|
||||
(byte)0xBD, (byte)0x66,
|
||||
(byte)0x01, (byte)0x18, (byte)0x39, (byte)0x29,
|
||||
(byte)0x6A, (byte)0x78, (byte)0x9A, (byte)0x3B,
|
||||
(byte)0xC0, (byte)0x04, (byte)0x5C, (byte)0x8A,
|
||||
(byte)0x5F, (byte)0xB4, (byte)0x2C, (byte)0x7D,
|
||||
(byte)0x1B, (byte)0xD9, (byte)0x98, (byte)0xF5,
|
||||
(byte)0x44, (byte)0x49, (byte)0x57, (byte)0x9B,
|
||||
(byte)0x44, (byte)0x68, (byte)0x17, (byte)0xAF,
|
||||
(byte)0xBD, (byte)0x17, (byte)0x27, (byte)0x3E,
|
||||
(byte)0x66, (byte)0x2C, (byte)0x97, (byte)0xEE,
|
||||
(byte)0x72, (byte)0x99, (byte)0x5E, (byte)0xF4,
|
||||
(byte)0x26, (byte)0x40, (byte)0xC5, (byte)0x50,
|
||||
(byte)0xB9, (byte)0x01, (byte)0x3F, (byte)0xAD,
|
||||
(byte)0x07, (byte)0x61, (byte)0x35, (byte)0x3C,
|
||||
(byte)0x70, (byte)0x86, (byte)0xA2, (byte)0x72,
|
||||
(byte)0xC2, (byte)0x40, (byte)0x88, (byte)0xBE,
|
||||
(byte)0x94, (byte)0x76, (byte)0x9F, (byte)0xD1,
|
||||
(byte)0x66, (byte)0x50
|
||||
};
|
||||
|
||||
protected static final byte[] ansix9p521r1_r = {
|
||||
(byte)0x01, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
|
||||
(byte)0xFF, (byte)0xFA, (byte)0x51, (byte)0x86,
|
||||
(byte)0x87, (byte)0x83, (byte)0xBF, (byte)0x2F,
|
||||
(byte)0x96, (byte)0x6B, (byte)0x7F, (byte)0xCC,
|
||||
(byte)0x01, (byte)0x48, (byte)0xF7, (byte)0x09,
|
||||
(byte)0xA5, (byte)0xD0, (byte)0x3B, (byte)0xB5,
|
||||
(byte)0xC9, (byte)0xB8, (byte)0x89, (byte)0x9C,
|
||||
(byte)0x47, (byte)0xAE, (byte)0xBB, (byte)0x6F,
|
||||
(byte)0xB7, (byte)0x1E, (byte)0x91, (byte)0x38,
|
||||
(byte)0x64, (byte)0x09
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected static final byte[] brainpoolP256r1_oid =
|
||||
{ (byte)0x2B, (byte)0x24, (byte)0x03, (byte)0x03, (byte)0x02, (byte)0x08, (byte)0x01, (byte)0x01, (byte)0x07 };
|
||||
|
||||
protected static final byte[] brainpoolP256r1_field = {
|
||||
(byte)0xA9, (byte)0xFB, (byte)0x57, (byte)0xDB,
|
||||
(byte)0xA1, (byte)0xEE, (byte)0xA9, (byte)0xBC,
|
||||
(byte)0x3E, (byte)0x66, (byte)0x0A, (byte)0x90,
|
||||
(byte)0x9D, (byte)0x83, (byte)0x8D, (byte)0x72,
|
||||
(byte)0x6E, (byte)0x3B, (byte)0xF6, (byte)0x23,
|
||||
(byte)0xD5, (byte)0x26, (byte)0x20, (byte)0x28,
|
||||
(byte)0x20, (byte)0x13, (byte)0x48, (byte)0x1D,
|
||||
(byte)0x1F, (byte)0x6E, (byte)0x53, (byte)0x77
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP256r1_a = {
|
||||
(byte)0x7D, (byte)0x5A, (byte)0x09, (byte)0x75,
|
||||
(byte)0xFC, (byte)0x2C, (byte)0x30, (byte)0x57,
|
||||
(byte)0xEE, (byte)0xF6, (byte)0x75, (byte)0x30,
|
||||
(byte)0x41, (byte)0x7A, (byte)0xFF, (byte)0xE7,
|
||||
(byte)0xFB, (byte)0x80, (byte)0x55, (byte)0xC1,
|
||||
(byte)0x26, (byte)0xDC, (byte)0x5C, (byte)0x6C,
|
||||
(byte)0xE9, (byte)0x4A, (byte)0x4B, (byte)0x44,
|
||||
(byte)0xF3, (byte)0x30, (byte)0xB5, (byte)0xD9
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP256r1_b = {
|
||||
(byte)0x26, (byte)0xDC, (byte)0x5C, (byte)0x6C,
|
||||
(byte)0xE9, (byte)0x4A, (byte)0x4B, (byte)0x44,
|
||||
(byte)0xF3, (byte)0x30, (byte)0xB5, (byte)0xD9,
|
||||
(byte)0xBB, (byte)0xD7, (byte)0x7C, (byte)0xBF,
|
||||
(byte)0x95, (byte)0x84, (byte)0x16, (byte)0x29,
|
||||
(byte)0x5C, (byte)0xF7, (byte)0xE1, (byte)0xCE,
|
||||
(byte)0x6B, (byte)0xCC, (byte)0xDC, (byte)0x18,
|
||||
(byte)0xFF, (byte)0x8C, (byte)0x07, (byte)0xB6
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP256r1_g = {
|
||||
(byte)0x04,
|
||||
(byte)0x8B, (byte)0xD2, (byte)0xAE, (byte)0xB9,
|
||||
(byte)0xCB, (byte)0x7E, (byte)0x57, (byte)0xCB,
|
||||
(byte)0x2C, (byte)0x4B, (byte)0x48, (byte)0x2F,
|
||||
(byte)0xFC, (byte)0x81, (byte)0xB7, (byte)0xAF,
|
||||
(byte)0xB9, (byte)0xDE, (byte)0x27, (byte)0xE1,
|
||||
(byte)0xE3, (byte)0xBD, (byte)0x23, (byte)0xC2,
|
||||
(byte)0x3A, (byte)0x44, (byte)0x53, (byte)0xBD,
|
||||
(byte)0x9A, (byte)0xCE, (byte)0x32, (byte)0x62,
|
||||
(byte)0x54, (byte)0x7E, (byte)0xF8, (byte)0x35,
|
||||
(byte)0xC3, (byte)0xDA, (byte)0xC4, (byte)0xFD,
|
||||
(byte)0x97, (byte)0xF8, (byte)0x46, (byte)0x1A,
|
||||
(byte)0x14, (byte)0x61, (byte)0x1D, (byte)0xC9,
|
||||
(byte)0xC2, (byte)0x77, (byte)0x45, (byte)0x13,
|
||||
(byte)0x2D, (byte)0xED, (byte)0x8E, (byte)0x54,
|
||||
(byte)0x5C, (byte)0x1D, (byte)0x54, (byte)0xC7,
|
||||
(byte)0x2F, (byte)0x04, (byte)0x69, (byte)0x97
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP256r1_r = {
|
||||
(byte)0xA9, (byte)0xFB, (byte)0x57, (byte)0xDB,
|
||||
(byte)0xA1, (byte)0xEE, (byte)0xA9, (byte)0xBC,
|
||||
(byte)0x3E, (byte)0x66, (byte)0x0A, (byte)0x90,
|
||||
(byte)0x9D, (byte)0x83, (byte)0x8D, (byte)0x71,
|
||||
(byte)0x8C, (byte)0x39, (byte)0x7A, (byte)0xA3,
|
||||
(byte)0xB5, (byte)0x61, (byte)0xA6, (byte)0xF7,
|
||||
(byte)0x90, (byte)0x1E, (byte)0x0E, (byte)0x82,
|
||||
(byte)0x97, (byte)0x48, (byte)0x56, (byte)0xA7
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected static final byte[] brainpoolP384r1_oid =
|
||||
{ (byte)0x2B, (byte)0x24, (byte)0x03, (byte)0x03, (byte)0x02, (byte)0x08, (byte)0x01, (byte)0x01, (byte)0x0B };
|
||||
|
||||
protected static final byte[] brainpoolP384r1_field = {
|
||||
(byte)0x8C, (byte)0xB9, (byte)0x1E, (byte)0x82,
|
||||
(byte)0xA3, (byte)0x38, (byte)0x6D, (byte)0x28,
|
||||
(byte)0x0F, (byte)0x5D, (byte)0x6F, (byte)0x7E,
|
||||
(byte)0x50, (byte)0xE6, (byte)0x41, (byte)0xDF,
|
||||
(byte)0x15, (byte)0x2F, (byte)0x71, (byte)0x09,
|
||||
(byte)0xED, (byte)0x54, (byte)0x56, (byte)0xB4,
|
||||
(byte)0x12, (byte)0xB1, (byte)0xDA, (byte)0x19,
|
||||
(byte)0x7F, (byte)0xB7, (byte)0x11, (byte)0x23,
|
||||
(byte)0xAC, (byte)0xD3, (byte)0xA7, (byte)0x29,
|
||||
(byte)0x90, (byte)0x1D, (byte)0x1A, (byte)0x71,
|
||||
(byte)0x87, (byte)0x47, (byte)0x00, (byte)0x13,
|
||||
(byte)0x31, (byte)0x07, (byte)0xEC, (byte)0x53
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP384r1_a = {
|
||||
(byte)0x7B, (byte)0xC3, (byte)0x82, (byte)0xC6,
|
||||
(byte)0x3D, (byte)0x8C, (byte)0x15, (byte)0x0C,
|
||||
(byte)0x3C, (byte)0x72, (byte)0x08, (byte)0x0A,
|
||||
(byte)0xCE, (byte)0x05, (byte)0xAF, (byte)0xA0,
|
||||
(byte)0xC2, (byte)0xBE, (byte)0xA2, (byte)0x8E,
|
||||
(byte)0x4F, (byte)0xB2, (byte)0x27, (byte)0x87,
|
||||
(byte)0x13, (byte)0x91, (byte)0x65, (byte)0xEF,
|
||||
(byte)0xBA, (byte)0x91, (byte)0xF9, (byte)0x0F,
|
||||
(byte)0x8A, (byte)0xA5, (byte)0x81, (byte)0x4A,
|
||||
(byte)0x50, (byte)0x3A, (byte)0xD4, (byte)0xEB,
|
||||
(byte)0x04, (byte)0xA8, (byte)0xC7, (byte)0xDD,
|
||||
(byte)0x22, (byte)0xCE, (byte)0x28, (byte)0x26
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP384r1_b = {
|
||||
(byte)0x04, (byte)0xA8, (byte)0xC7, (byte)0xDD,
|
||||
(byte)0x22, (byte)0xCE, (byte)0x28, (byte)0x26,
|
||||
(byte)0x8B, (byte)0x39, (byte)0xB5, (byte)0x54,
|
||||
(byte)0x16, (byte)0xF0, (byte)0x44, (byte)0x7C,
|
||||
(byte)0x2F, (byte)0xB7, (byte)0x7D, (byte)0xE1,
|
||||
(byte)0x07, (byte)0xDC, (byte)0xD2, (byte)0xA6,
|
||||
(byte)0x2E, (byte)0x88, (byte)0x0E, (byte)0xA5,
|
||||
(byte)0x3E, (byte)0xEB, (byte)0x62, (byte)0xD5,
|
||||
(byte)0x7C, (byte)0xB4, (byte)0x39, (byte)0x02,
|
||||
(byte)0x95, (byte)0xDB, (byte)0xC9, (byte)0x94,
|
||||
(byte)0x3A, (byte)0xB7, (byte)0x86, (byte)0x96,
|
||||
(byte)0xFA, (byte)0x50, (byte)0x4C, (byte)0x11
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP384r1_g = {
|
||||
(byte)0x04,
|
||||
(byte)0x1D, (byte)0x1C, (byte)0x64, (byte)0xF0,
|
||||
(byte)0x68, (byte)0xCF, (byte)0x45, (byte)0xFF,
|
||||
(byte)0xA2, (byte)0xA6, (byte)0x3A, (byte)0x81,
|
||||
(byte)0xB7, (byte)0xC1, (byte)0x3F, (byte)0x6B,
|
||||
(byte)0x88, (byte)0x47, (byte)0xA3, (byte)0xE7,
|
||||
(byte)0x7E, (byte)0xF1, (byte)0x4F, (byte)0xE3,
|
||||
(byte)0xDB, (byte)0x7F, (byte)0xCA, (byte)0xFE,
|
||||
(byte)0x0C, (byte)0xBD, (byte)0x10, (byte)0xE8,
|
||||
(byte)0xE8, (byte)0x26, (byte)0xE0, (byte)0x34,
|
||||
(byte)0x36, (byte)0xD6, (byte)0x46, (byte)0xAA,
|
||||
(byte)0xEF, (byte)0x87, (byte)0xB2, (byte)0xE2,
|
||||
(byte)0x47, (byte)0xD4, (byte)0xAF, (byte)0x1E,
|
||||
(byte)0x8A, (byte)0xBE, (byte)0x1D, (byte)0x75,
|
||||
(byte)0x20, (byte)0xF9, (byte)0xC2, (byte)0xA4,
|
||||
(byte)0x5C, (byte)0xB1, (byte)0xEB, (byte)0x8E,
|
||||
(byte)0x95, (byte)0xCF, (byte)0xD5, (byte)0x52,
|
||||
(byte)0x62, (byte)0xB7, (byte)0x0B, (byte)0x29,
|
||||
(byte)0xFE, (byte)0xEC, (byte)0x58, (byte)0x64,
|
||||
(byte)0xE1, (byte)0x9C, (byte)0x05, (byte)0x4F,
|
||||
(byte)0xF9, (byte)0x91, (byte)0x29, (byte)0x28,
|
||||
(byte)0x0E, (byte)0x46, (byte)0x46, (byte)0x21,
|
||||
(byte)0x77, (byte)0x91, (byte)0x81, (byte)0x11,
|
||||
(byte)0x42, (byte)0x82, (byte)0x03, (byte)0x41,
|
||||
(byte)0x26, (byte)0x3C, (byte)0x53, (byte)0x15
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP384r1_r = {
|
||||
(byte)0x8C, (byte)0xB9, (byte)0x1E, (byte)0x82,
|
||||
(byte)0xA3, (byte)0x38, (byte)0x6D, (byte)0x28,
|
||||
(byte)0x0F, (byte)0x5D, (byte)0x6F, (byte)0x7E,
|
||||
(byte)0x50, (byte)0xE6, (byte)0x41, (byte)0xDF,
|
||||
(byte)0x15, (byte)0x2F, (byte)0x71, (byte)0x09,
|
||||
(byte)0xED, (byte)0x54, (byte)0x56, (byte)0xB3,
|
||||
(byte)0x1F, (byte)0x16, (byte)0x6E, (byte)0x6C,
|
||||
(byte)0xAC, (byte)0x04, (byte)0x25, (byte)0xA7,
|
||||
(byte)0xCF, (byte)0x3A, (byte)0xB6, (byte)0xAF,
|
||||
(byte)0x6B, (byte)0x7F, (byte)0xC3, (byte)0x10,
|
||||
(byte)0x3B, (byte)0x88, (byte)0x32, (byte)0x02,
|
||||
(byte)0xE9, (byte)0x04, (byte)0x65, (byte)0x65
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected static final byte[] brainpoolP512r1_oid =
|
||||
{ (byte)0x2B, (byte)0x24, (byte)0x03, (byte)0x03, (byte)0x02, (byte)0x08, (byte)0x01, (byte)0x01, (byte)0x0D };
|
||||
|
||||
protected static final byte[] brainpoolP512r1_field = {
|
||||
(byte)0xAA, (byte)0xDD, (byte)0x9D, (byte)0xB8,
|
||||
(byte)0xDB, (byte)0xE9, (byte)0xC4, (byte)0x8B,
|
||||
(byte)0x3F, (byte)0xD4, (byte)0xE6, (byte)0xAE,
|
||||
(byte)0x33, (byte)0xC9, (byte)0xFC, (byte)0x07,
|
||||
(byte)0xCB, (byte)0x30, (byte)0x8D, (byte)0xB3,
|
||||
(byte)0xB3, (byte)0xC9, (byte)0xD2, (byte)0x0E,
|
||||
(byte)0xD6, (byte)0x63, (byte)0x9C, (byte)0xCA,
|
||||
(byte)0x70, (byte)0x33, (byte)0x08, (byte)0x71,
|
||||
(byte)0x7D, (byte)0x4D, (byte)0x9B, (byte)0x00,
|
||||
(byte)0x9B, (byte)0xC6, (byte)0x68, (byte)0x42,
|
||||
(byte)0xAE, (byte)0xCD, (byte)0xA1, (byte)0x2A,
|
||||
(byte)0xE6, (byte)0xA3, (byte)0x80, (byte)0xE6,
|
||||
(byte)0x28, (byte)0x81, (byte)0xFF, (byte)0x2F,
|
||||
(byte)0x2D, (byte)0x82, (byte)0xC6, (byte)0x85,
|
||||
(byte)0x28, (byte)0xAA, (byte)0x60, (byte)0x56,
|
||||
(byte)0x58, (byte)0x3A, (byte)0x48, (byte)0xF3
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP512r1_a = {
|
||||
(byte)0x78, (byte)0x30, (byte)0xA3, (byte)0x31,
|
||||
(byte)0x8B, (byte)0x60, (byte)0x3B, (byte)0x89,
|
||||
(byte)0xE2, (byte)0x32, (byte)0x71, (byte)0x45,
|
||||
(byte)0xAC, (byte)0x23, (byte)0x4C, (byte)0xC5,
|
||||
(byte)0x94, (byte)0xCB, (byte)0xDD, (byte)0x8D,
|
||||
(byte)0x3D, (byte)0xF9, (byte)0x16, (byte)0x10,
|
||||
(byte)0xA8, (byte)0x34, (byte)0x41, (byte)0xCA,
|
||||
(byte)0xEA, (byte)0x98, (byte)0x63, (byte)0xBC,
|
||||
(byte)0x2D, (byte)0xED, (byte)0x5D, (byte)0x5A,
|
||||
(byte)0xA8, (byte)0x25, (byte)0x3A, (byte)0xA1,
|
||||
(byte)0x0A, (byte)0x2E, (byte)0xF1, (byte)0xC9,
|
||||
(byte)0x8B, (byte)0x9A, (byte)0xC8, (byte)0xB5,
|
||||
(byte)0x7F, (byte)0x11, (byte)0x17, (byte)0xA7,
|
||||
(byte)0x2B, (byte)0xF2, (byte)0xC7, (byte)0xB9,
|
||||
(byte)0xE7, (byte)0xC1, (byte)0xAC, (byte)0x4D,
|
||||
(byte)0x77, (byte)0xFC, (byte)0x94, (byte)0xCA
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP512r1_b = {
|
||||
(byte)0x3D, (byte)0xF9, (byte)0x16, (byte)0x10,
|
||||
(byte)0xA8, (byte)0x34, (byte)0x41, (byte)0xCA,
|
||||
(byte)0xEA, (byte)0x98, (byte)0x63, (byte)0xBC,
|
||||
(byte)0x2D, (byte)0xED, (byte)0x5D, (byte)0x5A,
|
||||
(byte)0xA8, (byte)0x25, (byte)0x3A, (byte)0xA1,
|
||||
(byte)0x0A, (byte)0x2E, (byte)0xF1, (byte)0xC9,
|
||||
(byte)0x8B, (byte)0x9A, (byte)0xC8, (byte)0xB5,
|
||||
(byte)0x7F, (byte)0x11, (byte)0x17, (byte)0xA7,
|
||||
(byte)0x2B, (byte)0xF2, (byte)0xC7, (byte)0xB9,
|
||||
(byte)0xE7, (byte)0xC1, (byte)0xAC, (byte)0x4D,
|
||||
(byte)0x77, (byte)0xFC, (byte)0x94, (byte)0xCA,
|
||||
(byte)0xDC, (byte)0x08, (byte)0x3E, (byte)0x67,
|
||||
(byte)0x98, (byte)0x40, (byte)0x50, (byte)0xB7,
|
||||
(byte)0x5E, (byte)0xBA, (byte)0xE5, (byte)0xDD,
|
||||
(byte)0x28, (byte)0x09, (byte)0xBD, (byte)0x63,
|
||||
(byte)0x80, (byte)0x16, (byte)0xF7, (byte)0x23
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP512r1_g = {
|
||||
(byte)0x04,
|
||||
(byte)0x81, (byte)0xAE, (byte)0xE4, (byte)0xBD,
|
||||
(byte)0xD8, (byte)0x2E, (byte)0xD9, (byte)0x64,
|
||||
(byte)0x5A, (byte)0x21, (byte)0x32, (byte)0x2E,
|
||||
(byte)0x9C, (byte)0x4C, (byte)0x6A, (byte)0x93,
|
||||
(byte)0x85, (byte)0xED, (byte)0x9F, (byte)0x70,
|
||||
(byte)0xB5, (byte)0xD9, (byte)0x16, (byte)0xC1,
|
||||
(byte)0xB4, (byte)0x3B, (byte)0x62, (byte)0xEE,
|
||||
(byte)0xF4, (byte)0xD0, (byte)0x09, (byte)0x8E,
|
||||
(byte)0xFF, (byte)0x3B, (byte)0x1F, (byte)0x78,
|
||||
(byte)0xE2, (byte)0xD0, (byte)0xD4, (byte)0x8D,
|
||||
(byte)0x50, (byte)0xD1, (byte)0x68, (byte)0x7B,
|
||||
(byte)0x93, (byte)0xB9, (byte)0x7D, (byte)0x5F,
|
||||
(byte)0x7C, (byte)0x6D, (byte)0x50, (byte)0x47,
|
||||
(byte)0x40, (byte)0x6A, (byte)0x5E, (byte)0x68,
|
||||
(byte)0x8B, (byte)0x35, (byte)0x22, (byte)0x09,
|
||||
(byte)0xBC, (byte)0xB9, (byte)0xF8, (byte)0x22,
|
||||
(byte)0x7D, (byte)0xDE, (byte)0x38, (byte)0x5D,
|
||||
(byte)0x56, (byte)0x63, (byte)0x32, (byte)0xEC,
|
||||
(byte)0xC0, (byte)0xEA, (byte)0xBF, (byte)0xA9,
|
||||
(byte)0xCF, (byte)0x78, (byte)0x22, (byte)0xFD,
|
||||
(byte)0xF2, (byte)0x09, (byte)0xF7, (byte)0x00,
|
||||
(byte)0x24, (byte)0xA5, (byte)0x7B, (byte)0x1A,
|
||||
(byte)0xA0, (byte)0x00, (byte)0xC5, (byte)0x5B,
|
||||
(byte)0x88, (byte)0x1F, (byte)0x81, (byte)0x11,
|
||||
(byte)0xB2, (byte)0xDC, (byte)0xDE, (byte)0x49,
|
||||
(byte)0x4A, (byte)0x5F, (byte)0x48, (byte)0x5E,
|
||||
(byte)0x5B, (byte)0xCA, (byte)0x4B, (byte)0xD8,
|
||||
(byte)0x8A, (byte)0x27, (byte)0x63, (byte)0xAE,
|
||||
(byte)0xD1, (byte)0xCA, (byte)0x2B, (byte)0x2F,
|
||||
(byte)0xA8, (byte)0xF0, (byte)0x54, (byte)0x06,
|
||||
(byte)0x78, (byte)0xCD, (byte)0x1E, (byte)0x0F,
|
||||
(byte)0x3A, (byte)0xD8, (byte)0x08, (byte)0x92
|
||||
};
|
||||
|
||||
protected static final byte[] brainpoolP512r1_r = {
|
||||
(byte)0xAA, (byte)0xDD, (byte)0x9D, (byte)0xB8,
|
||||
(byte)0xDB, (byte)0xE9, (byte)0xC4, (byte)0x8B,
|
||||
(byte)0x3F, (byte)0xD4, (byte)0xE6, (byte)0xAE,
|
||||
(byte)0x33, (byte)0xC9, (byte)0xFC, (byte)0x07,
|
||||
(byte)0xCB, (byte)0x30, (byte)0x8D, (byte)0xB3,
|
||||
(byte)0xB3, (byte)0xC9, (byte)0xD2, (byte)0x0E,
|
||||
(byte)0xD6, (byte)0x63, (byte)0x9C, (byte)0xCA,
|
||||
(byte)0x70, (byte)0x33, (byte)0x08, (byte)0x70,
|
||||
(byte)0x55, (byte)0x3E, (byte)0x5C, (byte)0x41,
|
||||
(byte)0x4C, (byte)0xA9, (byte)0x26, (byte)0x19,
|
||||
(byte)0x41, (byte)0x86, (byte)0x61, (byte)0x19,
|
||||
(byte)0x7F, (byte)0xAC, (byte)0x10, (byte)0x47,
|
||||
(byte)0x1D, (byte)0xB1, (byte)0xD3, (byte)0x81,
|
||||
(byte)0x08, (byte)0x5D, (byte)0xDA, (byte)0xDD,
|
||||
(byte)0xB5, (byte)0x87, (byte)0x96, (byte)0x82,
|
||||
(byte)0x9C, (byte)0xA9, (byte)0x00, (byte)0x69
|
||||
};
|
||||
|
||||
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/SmartPGP
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
import javacard.framework.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.apdu.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public final class ECCurves {
|
||||
|
||||
protected final ECParams[] curves;
|
||||
|
||||
protected ECCurves() {
|
||||
final ECParams ansix9p256r1 =
|
||||
new ECParams((short)256,
|
||||
ECConstants.ansix9p256r1_oid,
|
||||
ECConstants.ansix9p256r1_field,
|
||||
ECConstants.ansix9p256r1_a,
|
||||
ECConstants.ansix9p256r1_b,
|
||||
ECConstants.ansix9p256r1_g,
|
||||
ECConstants.ansix9p256r1_r,
|
||||
(short)1);
|
||||
|
||||
final ECParams ansix9p384r1 =
|
||||
new ECParams((short)384,
|
||||
ECConstants.ansix9p384r1_oid,
|
||||
ECConstants.ansix9p384r1_field,
|
||||
ECConstants.ansix9p384r1_a,
|
||||
ECConstants.ansix9p384r1_b,
|
||||
ECConstants.ansix9p384r1_g,
|
||||
ECConstants.ansix9p384r1_r,
|
||||
(short)1);
|
||||
|
||||
final ECParams ansix9p521r1 =
|
||||
new ECParams((short)521,
|
||||
ECConstants.ansix9p521r1_oid,
|
||||
ECConstants.ansix9p521r1_field,
|
||||
ECConstants.ansix9p521r1_a,
|
||||
ECConstants.ansix9p521r1_b,
|
||||
ECConstants.ansix9p521r1_g,
|
||||
ECConstants.ansix9p521r1_r,
|
||||
(short)1);
|
||||
|
||||
final ECParams brainpoolP256r1 =
|
||||
new ECParams((short)256,
|
||||
ECConstants.brainpoolP256r1_oid,
|
||||
ECConstants.brainpoolP256r1_field,
|
||||
ECConstants.brainpoolP256r1_a,
|
||||
ECConstants.brainpoolP256r1_b,
|
||||
ECConstants.brainpoolP256r1_g,
|
||||
ECConstants.brainpoolP256r1_r,
|
||||
(short)1);
|
||||
|
||||
final ECParams brainpoolP384r1 =
|
||||
new ECParams((short)384,
|
||||
ECConstants.brainpoolP384r1_oid,
|
||||
ECConstants.brainpoolP384r1_field,
|
||||
ECConstants.brainpoolP384r1_a,
|
||||
ECConstants.brainpoolP384r1_b,
|
||||
ECConstants.brainpoolP384r1_g,
|
||||
ECConstants.brainpoolP384r1_r,
|
||||
(short)1);
|
||||
|
||||
final ECParams brainpoolP512r1 =
|
||||
new ECParams((short)512,
|
||||
ECConstants.brainpoolP512r1_oid,
|
||||
ECConstants.brainpoolP512r1_field,
|
||||
ECConstants.brainpoolP512r1_a,
|
||||
ECConstants.brainpoolP512r1_b,
|
||||
ECConstants.brainpoolP512r1_g,
|
||||
ECConstants.brainpoolP512r1_r,
|
||||
(short)1);
|
||||
|
||||
curves = new ECParams[]{
|
||||
ansix9p256r1,
|
||||
ansix9p384r1,
|
||||
ansix9p521r1,
|
||||
brainpoolP256r1,
|
||||
brainpoolP384r1,
|
||||
brainpoolP512r1
|
||||
};
|
||||
}
|
||||
|
||||
protected final ECParams findByOid(final byte[] buf,
|
||||
final short off,
|
||||
final byte len) {
|
||||
byte i = 0;
|
||||
while(i < curves.length) {
|
||||
if(curves[i].matchOid(buf, off, len)) {
|
||||
return curves[i];
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/SmartPGP
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
import javacard.framework.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.apdu.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
|
||||
public final class ECParams {
|
||||
|
||||
protected final short nb_bits;
|
||||
protected final byte[] oid;
|
||||
protected final byte[] field, a, b, g, r;
|
||||
protected final short k;
|
||||
|
||||
protected ECParams(final short nb_bits,
|
||||
final byte[] oid,
|
||||
final byte[] field, /* p */
|
||||
final byte[] a,
|
||||
final byte[] b,
|
||||
final byte[] g,
|
||||
final byte[] r, /* n */
|
||||
final short k) /* h */ {
|
||||
this.nb_bits = nb_bits;
|
||||
this.oid = oid;
|
||||
this.field = field;
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.g = g;
|
||||
this.r = r;
|
||||
this.k = k;
|
||||
}
|
||||
|
||||
|
||||
protected final boolean matchOid(final byte[] buf, final short off, final short len) {
|
||||
return (len == (short)oid.length) && (Util.arrayCompare(buf, off, oid, (short)0, len) == 0);
|
||||
}
|
||||
|
||||
protected final void setParams(final ECKey key) {
|
||||
key.setFieldFP(field, (short)0, (short)field.length);
|
||||
key.setA(a, (short)0, (short)a.length);
|
||||
key.setB(b, (short)0, (short)b.length);
|
||||
key.setG(g, (short)0, (short)g.length);
|
||||
key.setR(r, (short)0, (short)r.length);
|
||||
key.setK(k);
|
||||
}
|
||||
}
|
@ -37,22 +37,13 @@ public final class PGPKey {
|
||||
protected final byte[] attributes;
|
||||
protected byte attributes_length;
|
||||
|
||||
protected final boolean is_secure_messaging_key;
|
||||
|
||||
private KeyPair keys;
|
||||
|
||||
|
||||
protected PGPKey(final boolean for_secure_messaging) {
|
||||
protected PGPKey() {
|
||||
|
||||
is_secure_messaging_key = for_secure_messaging;
|
||||
|
||||
if(is_secure_messaging_key) {
|
||||
fingerprint = null;
|
||||
generation_date = null;
|
||||
} else {
|
||||
fingerprint = new Fingerprint();
|
||||
generation_date = new byte[Constants.GENERATION_DATE_SIZE];
|
||||
}
|
||||
fingerprint = new Fingerprint();
|
||||
generation_date = new byte[Constants.GENERATION_DATE_SIZE];
|
||||
|
||||
certificate = new byte[Constants.cardholderCertificateMaxLength()];
|
||||
certificate_length = 0;
|
||||
@ -75,11 +66,9 @@ public final class PGPKey {
|
||||
Util.arrayFillNonAtomic(certificate, (short)0, certificate_length, (byte)0);
|
||||
}
|
||||
|
||||
if(!is_secure_messaging_key) {
|
||||
fingerprint.reset();
|
||||
fingerprint.reset();
|
||||
|
||||
Util.arrayFillNonAtomic(generation_date, (short)0, Constants.GENERATION_DATE_SIZE, (byte)0);
|
||||
}
|
||||
Util.arrayFillNonAtomic(generation_date, (short)0, Constants.GENERATION_DATE_SIZE, (byte)0);
|
||||
}
|
||||
|
||||
protected final void reset() {
|
||||
@ -91,17 +80,10 @@ public final class PGPKey {
|
||||
attributes_length = (byte)0;
|
||||
}
|
||||
|
||||
if(is_secure_messaging_key) {
|
||||
Util.arrayCopyNonAtomic(Constants.ALGORITHM_ATTRIBUTES_DEFAULT_SECURE_MESSAGING, (short)0,
|
||||
attributes, (short)0,
|
||||
(short)Constants.ALGORITHM_ATTRIBUTES_DEFAULT_SECURE_MESSAGING.length);
|
||||
attributes_length = (byte)Constants.ALGORITHM_ATTRIBUTES_DEFAULT_SECURE_MESSAGING.length;
|
||||
} else {
|
||||
Util.arrayCopyNonAtomic(Constants.ALGORITHM_ATTRIBUTES_DEFAULT, (short)0,
|
||||
attributes, (short)0,
|
||||
(short)Constants.ALGORITHM_ATTRIBUTES_DEFAULT.length);
|
||||
attributes_length = (byte)Constants.ALGORITHM_ATTRIBUTES_DEFAULT.length;
|
||||
}
|
||||
Util.arrayCopyNonAtomic(Constants.ALGORITHM_ATTRIBUTES_DEFAULT, (short)0,
|
||||
attributes, (short)0,
|
||||
(short)Constants.ALGORITHM_ATTRIBUTES_DEFAULT.length);
|
||||
attributes_length = (byte)Constants.ALGORITHM_ATTRIBUTES_DEFAULT.length;
|
||||
JCSystem.commitTransaction();
|
||||
}
|
||||
|
||||
@ -133,8 +115,7 @@ public final class PGPKey {
|
||||
Util.arrayCopy(buf, off, generation_date, (short)0, len);
|
||||
}
|
||||
|
||||
protected final void setAttributes(final ECCurves ec,
|
||||
final byte[] buf, final short off, final short len) {
|
||||
protected final void setAttributes(final byte[] buf, final short off, final short len) {
|
||||
if((len < Constants.ALGORITHM_ATTRIBUTES_MIN_LENGTH) ||
|
||||
(len > Constants.ALGORITHM_ATTRIBUTES_MAX_LENGTH)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
@ -143,7 +124,7 @@ public final class PGPKey {
|
||||
|
||||
switch(buf[0]) {
|
||||
case 0x01:
|
||||
if((len != 6) || is_secure_messaging_key) {
|
||||
if(len != 6) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return;
|
||||
}
|
||||
@ -155,24 +136,6 @@ public final class PGPKey {
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
if(len < 2) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return;
|
||||
}
|
||||
final byte delta = (buf[(short)(len - 1)] == (byte)0xff) ? (byte)1 : (byte)0;
|
||||
final ECParams params = ec.findByOid(buf, (short)(off + 1), (byte)(len - 1 - delta));
|
||||
if(params == null) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return;
|
||||
}
|
||||
if((buf[0] != 0x12) && is_secure_messaging_key) {
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return;
|
||||
@ -202,17 +165,6 @@ public final class PGPKey {
|
||||
return Util.getShort(attributes, (short)3);
|
||||
}
|
||||
|
||||
protected final boolean isEc() {
|
||||
return ((attributes[0] == (byte)0x12) ||
|
||||
(attributes[0] == (byte)0x13));
|
||||
}
|
||||
|
||||
protected final ECParams ecParams(final ECCurves ec) {
|
||||
final byte delta = (attributes[(short)(attributes_length - 1)] == (byte)0xff) ? (byte)1 : (byte)0;
|
||||
return ec.findByOid(attributes, (short)1, (byte)(attributes_length - 1 - delta));
|
||||
}
|
||||
|
||||
|
||||
private final KeyPair generateRSA() {
|
||||
final PrivateKey priv = (PrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, rsaModulusBitSize(), false);
|
||||
final RSAPublicKey pub = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, rsaModulusBitSize(), false);
|
||||
@ -227,32 +179,12 @@ public final class PGPKey {
|
||||
}
|
||||
|
||||
|
||||
private final KeyPair generateEC(final ECCurves ec) {
|
||||
|
||||
final ECParams params = ecParams(ec);
|
||||
|
||||
final ECPrivateKey priv = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, params.nb_bits, false);
|
||||
final ECPublicKey pub = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, params.nb_bits, false);
|
||||
|
||||
if((priv == null) || (pub == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
params.setParams(priv);
|
||||
params.setParams(pub);
|
||||
|
||||
return new KeyPair(pub, priv);
|
||||
}
|
||||
|
||||
|
||||
protected final void generate(final ECCurves ec) {
|
||||
protected final void generate() {
|
||||
|
||||
KeyPair nkeys = null;
|
||||
|
||||
if(isRsa()) {
|
||||
nkeys = generateRSA();
|
||||
} else if(isEc()) {
|
||||
nkeys = generateEC(ec);
|
||||
}
|
||||
|
||||
if(nkeys == null) {
|
||||
@ -361,70 +293,8 @@ public final class PGPKey {
|
||||
return new KeyPair(pub, priv);
|
||||
}
|
||||
|
||||
private final KeyPair importECKey(final ECCurves ec,
|
||||
final byte[] buf,
|
||||
final short boff, final short len,
|
||||
final byte tag_count, final byte[] tag_val, final short[] tag_len) {
|
||||
final ECParams params = ecParams(ec);
|
||||
|
||||
final ECPrivateKey priv = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,
|
||||
params.nb_bits,
|
||||
false);
|
||||
final ECPublicKey pub = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,
|
||||
params.nb_bits,
|
||||
false);
|
||||
|
||||
if((priv == null) || (pub == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
params.setParams(priv);
|
||||
params.setParams(pub);
|
||||
|
||||
short off = boff;
|
||||
byte i = 0;
|
||||
while(i < tag_count) {
|
||||
|
||||
if((short)((short)(off - boff) + tag_len[i]) > len) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return null;
|
||||
}
|
||||
|
||||
switch(tag_val[i]) {
|
||||
case (byte)0x92:
|
||||
if(tag_len[i] > Common.bitsToBytes(params.nb_bits)) {
|
||||
return null;
|
||||
}
|
||||
priv.setS(buf, off, tag_len[i]);
|
||||
break;
|
||||
|
||||
case (byte)0x99:
|
||||
if(tag_len[i] > (short)(2 * Common.bitsToBytes(params.nb_bits) + 1)) {
|
||||
return null;
|
||||
}
|
||||
if(((byte)(tag_len[i] - 1) & (byte)0x1) != 0) {
|
||||
return null;
|
||||
}
|
||||
pub.setW(buf, off, tag_len[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
off += tag_len[i];
|
||||
++i;
|
||||
}
|
||||
|
||||
if(!priv.isInitialized() || !pub.isInitialized()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new KeyPair(pub, priv);
|
||||
}
|
||||
|
||||
protected final void importKey(final ECCurves ec,
|
||||
final byte[] buf, final short boff, final short len) {
|
||||
protected final void importKey(final byte[] buf, final short boff, final short len) {
|
||||
|
||||
short off = boff;
|
||||
|
||||
@ -499,8 +369,6 @@ public final class PGPKey {
|
||||
|
||||
if(isRsa()) {
|
||||
nkeys = importRSAKey(buf, data_off, data_len, data_tag_count, data_tag_val, data_tag_len);
|
||||
} else if(isEc()) {
|
||||
nkeys = importECKey(ec, buf, data_off, data_len, data_tag_count, data_tag_val, data_tag_len);
|
||||
}
|
||||
|
||||
if(nkeys == null) {
|
||||
@ -552,28 +420,6 @@ public final class PGPKey {
|
||||
|
||||
return off;
|
||||
|
||||
} else if(isEc()) {
|
||||
|
||||
final ECPublicKey ecpub = (ECPublicKey)pub;
|
||||
final short qsize = (short)(1 + 2 * (short)((ecpub.getSize() / 8) + (((ecpub.getSize() % 8) == 0) ? 0 : 1)));
|
||||
short rsize = (short)(1 + qsize);
|
||||
|
||||
if(qsize > 0x7f) {
|
||||
rsize = (short)(rsize + 2);
|
||||
} else {
|
||||
rsize = (short)(rsize + 1);
|
||||
}
|
||||
|
||||
off = Common.writeLength(buf, off, rsize);
|
||||
|
||||
buf[off++] = (byte)0x86;
|
||||
|
||||
off = Common.writeLength(buf, off, qsize);
|
||||
|
||||
off += ecpub.getW(buf, off);
|
||||
|
||||
return off;
|
||||
|
||||
}
|
||||
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
@ -634,88 +480,6 @@ public final class PGPKey {
|
||||
buf, (short)0,
|
||||
off);
|
||||
|
||||
} else if(isEc()) {
|
||||
|
||||
byte alg;
|
||||
|
||||
if(lc == MessageDigest.LENGTH_SHA) {
|
||||
alg = Signature.ALG_ECDSA_SHA;
|
||||
} else if(lc == MessageDigest.LENGTH_SHA_224) {
|
||||
alg = Signature.ALG_ECDSA_SHA_224;
|
||||
} else if(lc == MessageDigest.LENGTH_SHA_256) {
|
||||
alg = Signature.ALG_ECDSA_SHA_256;
|
||||
} else if(lc == MessageDigest.LENGTH_SHA_384) {
|
||||
alg = Signature.ALG_ECDSA_SHA_384;
|
||||
} else if(lc == MessageDigest.LENGTH_SHA_512) {
|
||||
alg = Signature.ALG_ECDSA_SHA_512;
|
||||
} else {
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
final Signature sig = Signature.getInstance(alg, false);
|
||||
sig.init(priv, Signature.MODE_SIGN);
|
||||
|
||||
final short sig_size = sig.signPreComputedHash(buf, (short)0, lc,
|
||||
buf, lc);
|
||||
|
||||
off = (short)(lc + 1);
|
||||
if((buf[off] & (byte)0x80) != (byte)0) {
|
||||
++off;
|
||||
}
|
||||
++off;
|
||||
|
||||
if((buf[off++] != (byte)0x02)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((buf[off] & (byte)0x80) != (byte)0) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
final short r_size = Util.makeShort((byte)0, buf[off++]);
|
||||
final short r_off = off;
|
||||
|
||||
off += r_size;
|
||||
|
||||
if((buf[off++] != (byte)0x02)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((buf[off] & (byte)0x80) != (byte)0) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
final short s_size = Util.makeShort((byte)0, buf[off++]);
|
||||
final short s_off = off;
|
||||
|
||||
off = (short)(lc + sig_size);
|
||||
|
||||
if(r_size < s_size) {
|
||||
off = Util.arrayFillNonAtomic(buf, off, (short)(s_size - r_size), (byte)0);
|
||||
}
|
||||
|
||||
off = Util.arrayCopyNonAtomic(buf, r_off,
|
||||
buf, off, r_size);
|
||||
|
||||
if(s_size < r_size) {
|
||||
off = Util.arrayFillNonAtomic(buf, off, (short)(r_size - s_size), (byte)0);
|
||||
}
|
||||
|
||||
off = Util.arrayCopyNonAtomic(buf, s_off,
|
||||
buf, off, s_size);
|
||||
|
||||
off = Util.arrayCopyNonAtomic(buf, (short)(lc + sig_size),
|
||||
buf, (short)0,
|
||||
(short)(off - lc - sig_size));
|
||||
|
||||
Util.arrayFillNonAtomic(buf, off, (short)(lc + sig_size - off), (byte)0);
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
@ -723,7 +487,7 @@ public final class PGPKey {
|
||||
}
|
||||
|
||||
|
||||
protected final short decipher(final ECCurves ec, final byte[] buf, final short lc) {
|
||||
protected final short decipher(final byte[] buf, final short lc) {
|
||||
|
||||
if(!isInitialized()) {
|
||||
ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND);
|
||||
@ -761,64 +525,6 @@ public final class PGPKey {
|
||||
|
||||
return off;
|
||||
|
||||
} else if(isEc()) {
|
||||
|
||||
final ECParams params = ecParams(ec);
|
||||
|
||||
if((lc <= 7) || (lc > (short)(7 + 1 + (short)(2 * Common.bitsToBytes(params.nb_bits))))) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(buf[off] != (byte)0xA6) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
++off;
|
||||
|
||||
if(buf[off] != (byte)(lc - off - 1)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
++off;
|
||||
|
||||
if(Util.getShort(buf, off) != (short)(0x7f49)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
off += 2;
|
||||
|
||||
if(buf[off] != (byte)(lc - off - 1)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
++off;
|
||||
|
||||
if(buf[off] != (byte)0x86) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
++off;
|
||||
|
||||
if(buf[off] != (byte)(lc - off - 1)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
++off;
|
||||
|
||||
final KeyAgreement ka = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH_PLAIN, false);
|
||||
ka.init(priv);
|
||||
|
||||
final short len = ka.generateSecret(buf, off, (short)(lc - off),
|
||||
buf, lc);
|
||||
|
||||
off = Util.arrayCopyNonAtomic(buf, lc,
|
||||
buf, (short)0,
|
||||
len);
|
||||
|
||||
Util.arrayFillNonAtomic(buf, lc, len, (byte)0);
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
|
@ -129,7 +129,7 @@ public final class Persistent {
|
||||
|
||||
pgp_keys = new PGPKey[PGP_KEYS_LENGTH];
|
||||
for(byte i = 0; i < pgp_keys.length; ++i) {
|
||||
pgp_keys[i] = new PGPKey(false);
|
||||
pgp_keys[i] = new PGPKey();
|
||||
}
|
||||
|
||||
key_derivation_function = new byte[Constants.specialDoMaxLength()];
|
||||
|
@ -1,468 +0,0 @@
|
||||
/*
|
||||
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
|
||||
https://github.com/ANSSI-FR/SmartPGP
|
||||
Copyright (C) 2016 ANSSI
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package fr.anssi.smartpgp;
|
||||
|
||||
import javacard.framework.*;
|
||||
import javacard.security.*;
|
||||
import javacardx.apdu.*;
|
||||
import javacardx.crypto.*;
|
||||
|
||||
public final class SecureMessaging {
|
||||
|
||||
public static final short MAC_LENGTH = (short)(Constants.AES_BLOCK_SIZE / (short)2);
|
||||
|
||||
protected static final byte[] PADDING_BLOCK = {
|
||||
(byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
|
||||
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
|
||||
};
|
||||
|
||||
private static final byte[] CRT_PREFIX = {
|
||||
(byte)0xA6, (byte)0x0D,
|
||||
(byte)0x90, (byte)0x02, (byte)0x11, (byte)0x00,
|
||||
(byte)0x95, (byte)0x01, (byte)0x3C,
|
||||
(byte)0x80, (byte)0x01, (byte)0x88,
|
||||
(byte)0x81, (byte)0x01
|
||||
};
|
||||
|
||||
private final MessageDigest digest;
|
||||
private final KeyAgreement key_agreement;
|
||||
|
||||
protected final PGPKey static_key;
|
||||
|
||||
private final Cipher cipher;
|
||||
private AESKey senc;
|
||||
private final byte[] iv;
|
||||
|
||||
private final CmacSignature macer;
|
||||
private final byte[] mac_chaining;
|
||||
private CmacKey sreceiptmac;
|
||||
private CmacKey smac;
|
||||
private CmacKey srmac;
|
||||
|
||||
|
||||
protected SecureMessaging(final Transients transients) {
|
||||
digest = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
|
||||
key_agreement = KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH_PLAIN, false);
|
||||
|
||||
static_key = new PGPKey(true);
|
||||
|
||||
cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
|
||||
senc = null;
|
||||
iv = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE,
|
||||
JCSystem.CLEAR_ON_DESELECT);
|
||||
|
||||
macer = new CmacSignature();
|
||||
mac_chaining = JCSystem.makeTransientByteArray(Constants.AES_BLOCK_SIZE,
|
||||
JCSystem.CLEAR_ON_DESELECT);
|
||||
sreceiptmac = null;
|
||||
smac = null;
|
||||
srmac = null;
|
||||
|
||||
reset(transients);
|
||||
}
|
||||
|
||||
|
||||
protected final void clearSession(final Transients transients) {
|
||||
if((senc != null) && senc.isInitialized()) {
|
||||
senc.clearKey();
|
||||
}
|
||||
Util.arrayFillNonAtomic(iv, (short)0, (short)iv.length, (byte)0);
|
||||
|
||||
macer.clear();
|
||||
Util.arrayFillNonAtomic(mac_chaining, (short)0, (short)mac_chaining.length, (byte)0);
|
||||
if((sreceiptmac != null) && senc.isInitialized()) {
|
||||
sreceiptmac.clearKey();
|
||||
}
|
||||
if((smac != null) && smac.isInitialized()) {
|
||||
smac.clearKey();
|
||||
}
|
||||
if((srmac != null) && srmac.isInitialized()) {
|
||||
srmac.clearKey();
|
||||
}
|
||||
|
||||
transients.setSecureMessagingEncryptionCounter((short)0);
|
||||
}
|
||||
|
||||
protected final void reset(final Transients transients) {
|
||||
clearSession(transients);
|
||||
sreceiptmac = null;
|
||||
senc = null;
|
||||
smac = null;
|
||||
srmac = null;
|
||||
static_key.reset();
|
||||
}
|
||||
|
||||
private final void initSession(final short keyLength,
|
||||
final byte[] buf, final short off) {
|
||||
if((sreceiptmac == null) ||
|
||||
(sreceiptmac.getSize() != (short)(keyLength * 8))) {
|
||||
senc = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES_TRANSIENT_DESELECT,
|
||||
(short)(keyLength * 8),
|
||||
false);
|
||||
|
||||
sreceiptmac = new CmacKey(keyLength);
|
||||
smac = new CmacKey(keyLength);
|
||||
srmac = new CmacKey(keyLength);
|
||||
}
|
||||
|
||||
sreceiptmac.setKey(buf, off);
|
||||
senc.setKey(buf, (short)(off + keyLength));
|
||||
smac.setKey(buf, (short)(off + (short)(2 * keyLength)));
|
||||
srmac.setKey(buf, (short)(off + (short)(3 * keyLength)));
|
||||
}
|
||||
|
||||
protected final boolean isInitialized() {
|
||||
return static_key.isInitialized();
|
||||
}
|
||||
|
||||
protected final boolean isSessionAvailable() {
|
||||
return isInitialized()
|
||||
&& (senc != null) && senc.isInitialized()
|
||||
&& (smac != null) && smac.isInitialized()
|
||||
&& (srmac != null) && srmac.isInitialized();
|
||||
}
|
||||
|
||||
|
||||
private final short scp11b(final ECCurves curves,
|
||||
final byte[] buf, final short len) {
|
||||
|
||||
final ECParams params = static_key.ecParams(curves);
|
||||
|
||||
if(len <= (short)((short)CRT_PREFIX.length + 4)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Util.arrayCompare(CRT_PREFIX, (short)0,
|
||||
buf, (short)0,
|
||||
(short)CRT_PREFIX.length) != (byte)0) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
short off = (short)CRT_PREFIX.length;
|
||||
|
||||
if(buf[off] != Common.aesKeyLength(params)) {
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
++off;
|
||||
|
||||
if(Util.getShort(buf, off) != (short)0x5F49) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
}
|
||||
off += 2;
|
||||
|
||||
short keylen = Common.readLength(buf, off, len);
|
||||
|
||||
off = Common.skipLength(buf, off, len);
|
||||
|
||||
if((short)(off + keylen) > len) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(keylen != (short)(2 * Common.bitsToBytes(params.nb_bits) + 1)) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ECPrivateKey eskcard = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,
|
||||
params.nb_bits,
|
||||
false);
|
||||
ECPublicKey epkcard = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,
|
||||
params.nb_bits,
|
||||
false);
|
||||
|
||||
params.setParams(eskcard);
|
||||
params.setParams(epkcard);
|
||||
|
||||
KeyPair ekcard = new KeyPair(epkcard, eskcard);
|
||||
|
||||
ekcard.genKeyPair();
|
||||
|
||||
if(!eskcard.isInitialized() ||
|
||||
!epkcard.isInitialized()) {
|
||||
ISOException.throwIt(Constants.SW_MEMORY_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
key_agreement.init(eskcard);
|
||||
|
||||
short msglen = 0;
|
||||
|
||||
msglen += key_agreement.generateSecret(buf, off, keylen, buf, len);
|
||||
eskcard.clearKey();
|
||||
eskcard = null;
|
||||
|
||||
static_key.initKeyAgreement(key_agreement);
|
||||
msglen += key_agreement.generateSecret(buf, off, keylen, buf, (short)(len + msglen));
|
||||
|
||||
Util.setShort(buf, (short)(len + msglen), (short)0);
|
||||
msglen += 2;
|
||||
|
||||
short counter = 1;
|
||||
off = (short)(len + msglen);
|
||||
msglen += 2;
|
||||
|
||||
buf[(short)(len + msglen)] = CRT_PREFIX[(short)8];
|
||||
++msglen;
|
||||
buf[(short)(len + msglen)] = CRT_PREFIX[(short)11];
|
||||
++msglen;
|
||||
buf[(short)(len + msglen)] = buf[CRT_PREFIX.length];
|
||||
++msglen;
|
||||
|
||||
keylen = 0;
|
||||
|
||||
while(keylen < (short)(4 * buf[CRT_PREFIX.length])) {
|
||||
Util.setShort(buf, off, counter);
|
||||
++counter;
|
||||
|
||||
keylen += digest.doFinal(buf, len, msglen,
|
||||
buf, (short)(len + msglen + keylen));
|
||||
}
|
||||
|
||||
initSession(Common.aesKeyLength(params), buf, (short)(len + msglen));
|
||||
|
||||
Util.arrayFillNonAtomic(buf, len, (short)(msglen + keylen), (byte)0);
|
||||
|
||||
off = len;
|
||||
Util.setShort(buf, off, (short)0x5F49);
|
||||
off += 2;
|
||||
off = Common.writeLength(buf, off, (short)(2 * Common.bitsToBytes(params.nb_bits) + 1));
|
||||
off += epkcard.getW(buf, off);
|
||||
msglen = off;
|
||||
|
||||
epkcard.clearKey();
|
||||
epkcard = null;
|
||||
|
||||
ekcard = null;
|
||||
|
||||
buf[off++] = (byte)0x86;
|
||||
buf[off++] = (byte)Constants.AES_BLOCK_SIZE;
|
||||
|
||||
macer.init(sreceiptmac);
|
||||
macer.sign(buf, (short)0, msglen,
|
||||
buf, off, Constants.AES_BLOCK_SIZE);
|
||||
macer.clear();
|
||||
|
||||
Util.arrayCopy(buf, off, mac_chaining, (short)0, Constants.AES_BLOCK_SIZE);
|
||||
|
||||
off += Constants.AES_BLOCK_SIZE;
|
||||
|
||||
msglen = (short)(off - len);
|
||||
|
||||
Util.arrayCopy(buf, len, buf, (short)0, msglen);
|
||||
|
||||
return msglen;
|
||||
}
|
||||
|
||||
|
||||
protected final short establish(final Transients transients,
|
||||
final ECCurves ec,
|
||||
final byte[] buf, final short len) {
|
||||
|
||||
clearSession(transients);
|
||||
|
||||
if(isInitialized() && static_key.isEc()) {
|
||||
return scp11b(ec, buf, len);
|
||||
}
|
||||
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final void incrementEncryptionCounter(final Transients transients) {
|
||||
final short pval = transients.secureMessagingEncryptionCounter();
|
||||
final short nval = (short)(pval + 1);
|
||||
|
||||
if(nval <= pval) {
|
||||
clearSession(transients);
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return;
|
||||
}
|
||||
|
||||
transients.setSecureMessagingEncryptionCounter(nval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected final short verifyAndDecryptCommand(final Transients transients,
|
||||
short dataLen, short dataWithHeaderLen) {
|
||||
|
||||
if(!isSessionAvailable()) {
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
incrementEncryptionCounter(transients);
|
||||
|
||||
if(dataLen < MAC_LENGTH) {
|
||||
clearSession(transients);
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
final byte[] buf = transients.buffer;
|
||||
|
||||
macer.init(smac);
|
||||
macer.update(mac_chaining, (short)0, Constants.AES_BLOCK_SIZE);
|
||||
macer.update(buf, dataLen, (short)(dataWithHeaderLen - dataLen));
|
||||
macer.sign(buf, (short)0, (short)(dataLen - MAC_LENGTH),
|
||||
buf, dataLen, Constants.AES_BLOCK_SIZE);
|
||||
|
||||
if(Util.arrayCompare(buf, (short)(dataLen - MAC_LENGTH),
|
||||
buf, dataLen,
|
||||
MAC_LENGTH) != (byte)0) {
|
||||
clearSession(transients);
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Util.arrayCopyNonAtomic(buf, dataLen,
|
||||
mac_chaining, (short)0,
|
||||
Constants.AES_BLOCK_SIZE);
|
||||
|
||||
dataLen -= MAC_LENGTH;
|
||||
|
||||
if(dataLen > 0) {
|
||||
Util.arrayFillNonAtomic(buf, dataLen, Constants.AES_BLOCK_SIZE, (byte)0);
|
||||
Util.setShort(buf, (short)(dataLen + Constants.AES_BLOCK_SIZE - 2),
|
||||
transients.secureMessagingEncryptionCounter());
|
||||
|
||||
cipher.init(senc, Cipher.MODE_ENCRYPT);
|
||||
cipher.doFinal(buf, dataLen, Constants.AES_BLOCK_SIZE,
|
||||
iv, (short)0);
|
||||
|
||||
cipher.init(senc, Cipher.MODE_DECRYPT,
|
||||
iv, (short)0, Constants.AES_BLOCK_SIZE);
|
||||
|
||||
|
||||
short tmp = (short)(Constants.INTERNAL_BUFFER_MAX_LENGTH - dataLen);
|
||||
if(tmp < Constants.AES_BLOCK_SIZE) {
|
||||
ISOException.throwIt(Constants.SW_MEMORY_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Util.arrayCopyNonAtomic(buf, (short)0,
|
||||
buf, tmp,
|
||||
dataLen);
|
||||
dataLen = 0;
|
||||
while(tmp < Constants.INTERNAL_BUFFER_MAX_LENGTH) {
|
||||
if((short)(Constants.INTERNAL_BUFFER_MAX_LENGTH - tmp) <= Constants.AES_BLOCK_SIZE) {
|
||||
dataLen += cipher.doFinal(buf, tmp, (short)(Constants.INTERNAL_BUFFER_MAX_LENGTH - tmp),
|
||||
buf, dataLen);
|
||||
tmp = Constants.INTERNAL_BUFFER_MAX_LENGTH;
|
||||
} else {
|
||||
dataLen += cipher.update(buf, tmp, Constants.AES_BLOCK_SIZE,
|
||||
buf, dataLen);
|
||||
tmp += Constants.AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
Util.arrayFillNonAtomic(iv, (short)0, (short)iv.length, (byte)0);
|
||||
|
||||
--dataLen;
|
||||
while((dataLen > 0) && buf[dataLen] == (byte)0)
|
||||
--dataLen;
|
||||
|
||||
if((dataLen <= 0) || (buf[dataLen] != (byte)0x80)) {
|
||||
clearSession(transients);
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return dataLen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected final short encryptAndSign(final Transients transients,
|
||||
short dataLen,
|
||||
final short sw) {
|
||||
|
||||
if(!isSessionAvailable()) {
|
||||
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
final byte[] buf = transients.buffer;
|
||||
|
||||
if(dataLen > 0) {
|
||||
Util.arrayFillNonAtomic(buf, dataLen, Constants.AES_BLOCK_SIZE, (byte)0);
|
||||
buf[dataLen] = (byte)0x80;
|
||||
Util.setShort(buf, (short)(dataLen + Constants.AES_BLOCK_SIZE - 2),
|
||||
transients.secureMessagingEncryptionCounter());
|
||||
|
||||
cipher.init(senc, Cipher.MODE_ENCRYPT);
|
||||
|
||||
cipher.doFinal(buf, dataLen, Constants.AES_BLOCK_SIZE,
|
||||
iv, (short)0);
|
||||
|
||||
cipher.init(senc, Cipher.MODE_ENCRYPT,
|
||||
iv, (short)0, Constants.AES_BLOCK_SIZE);
|
||||
|
||||
short tmp = (short)(Constants.INTERNAL_BUFFER_MAX_LENGTH - dataLen);
|
||||
if(tmp < Constants.AES_BLOCK_SIZE) {
|
||||
ISOException.throwIt(Constants.SW_MEMORY_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Util.arrayCopyNonAtomic(buf, (short)0,
|
||||
buf, tmp,
|
||||
dataLen);
|
||||
dataLen = 0;
|
||||
while(tmp < Constants.INTERNAL_BUFFER_MAX_LENGTH) {
|
||||
if((short)(Constants.INTERNAL_BUFFER_MAX_LENGTH - tmp) <= Constants.AES_BLOCK_SIZE) {
|
||||
dataLen += cipher.doFinal(buf, tmp, (short)(Constants.INTERNAL_BUFFER_MAX_LENGTH - tmp),
|
||||
buf, dataLen);
|
||||
tmp = Constants.INTERNAL_BUFFER_MAX_LENGTH;
|
||||
} else {
|
||||
dataLen += cipher.update(buf, tmp, Constants.AES_BLOCK_SIZE,
|
||||
buf, dataLen);
|
||||
tmp += Constants.AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
Util.arrayFillNonAtomic(iv, (short)0, (short)iv.length, (byte)0);
|
||||
}
|
||||
|
||||
macer.init(srmac);
|
||||
|
||||
macer.update(mac_chaining, (short)0, Constants.AES_BLOCK_SIZE);
|
||||
if(dataLen > 0) {
|
||||
macer.update(buf, (short)0, dataLen);
|
||||
}
|
||||
macer.updateShort(sw);
|
||||
dataLen += macer.sign(null, (short)0, (short)0,
|
||||
buf, dataLen, MAC_LENGTH);
|
||||
|
||||
return dataLen;
|
||||
}
|
||||
|
||||
}
|
@ -27,18 +27,14 @@ import javacardx.crypto.*;
|
||||
|
||||
public final class SmartPGPApplet extends Applet {
|
||||
|
||||
private final ECCurves ec;
|
||||
private final Persistent data;
|
||||
private final SecureMessaging sm;
|
||||
|
||||
private final Transients transients;
|
||||
|
||||
|
||||
public SmartPGPApplet() {
|
||||
ec = new ECCurves();
|
||||
data = new Persistent();
|
||||
transients = new Transients();
|
||||
sm = new SecureMessaging(transients);
|
||||
}
|
||||
|
||||
public static final void install(byte[] buf, short off, byte len) {
|
||||
@ -53,8 +49,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC];
|
||||
case 2:
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG];
|
||||
case 3:
|
||||
return sm.static_key;
|
||||
default:
|
||||
ISOException.throwIt(Constants.SW_REFERENCE_DATA_NOT_FOUND);
|
||||
return null;
|
||||
@ -128,15 +122,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
}
|
||||
|
||||
private final void sensitiveData() {
|
||||
final byte proto = APDU.getProtocol();
|
||||
|
||||
if(((proto & APDU.PROTOCOL_MEDIA_MASK) == APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_A) ||
|
||||
((proto & APDU.PROTOCOL_MEDIA_MASK) == APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_B)) {
|
||||
if(sm.isInitialized() && !transients.secureMessagingOk()) {
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void assertAdmin() {
|
||||
@ -358,15 +343,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
k.attributes_length);
|
||||
break;
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_SM:
|
||||
buf[off++] = (byte)0xd4;
|
||||
k = sm.static_key;
|
||||
off = Common.writeLength(buf, off, k.attributes_length);
|
||||
off = Util.arrayCopyNonAtomic(k.attributes, (short)0,
|
||||
buf, off,
|
||||
k.attributes_length);
|
||||
break;
|
||||
|
||||
case Constants.TAG_APPLICATION_RELATED_DATA:
|
||||
tlen = (short)(1 + 1 + Constants.EXTENDED_CAPABILITIES.length +
|
||||
1 + 1 + data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG].attributes_length +
|
||||
@ -840,16 +816,12 @@ public final class SmartPGPApplet extends Applet {
|
||||
k = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT];
|
||||
break;
|
||||
|
||||
case Constants.CRT_SECURE_MESSAGING_KEY:
|
||||
k = sm.static_key;
|
||||
break;
|
||||
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
k.importKey(ec, buf, (short)(off + 2), (short)(lc - off - 2));
|
||||
k.importKey(buf, (short)(off + 2), (short)(lc - off - 2));
|
||||
|
||||
} else {
|
||||
final short tag = Util.makeShort(p1, p2);
|
||||
@ -1034,7 +1006,7 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_SIG:
|
||||
assertAdmin();
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG].setAttributes(ec, buf, (short)0, lc);
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_SIG].setAttributes(buf, (short)0, lc);
|
||||
JCSystem.beginTransaction();
|
||||
Util.arrayFillNonAtomic(data.digital_signature_counter, (short)0,
|
||||
(byte)data.digital_signature_counter.length, (byte)0);
|
||||
@ -1043,17 +1015,12 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_DEC:
|
||||
assertAdmin();
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].setAttributes(ec, buf, (short)0, lc);
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].setAttributes(buf, (short)0, lc);
|
||||
break;
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_AUT:
|
||||
assertAdmin();
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT].setAttributes(ec, buf, (short)0, lc);
|
||||
break;
|
||||
|
||||
case Constants.TAG_ALGORITHM_ATTRIBUTES_SM:
|
||||
assertAdmin();
|
||||
sm.static_key.setAttributes(ec, buf, (short)0, lc);
|
||||
data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT].setAttributes(buf, (short)0, lc);
|
||||
break;
|
||||
|
||||
case Constants.TAG_PW_STATUS:
|
||||
@ -1191,10 +1158,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
pkey = data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT];
|
||||
break;
|
||||
|
||||
case Constants.CRT_SECURE_MESSAGING_KEY:
|
||||
pkey = sm.static_key;
|
||||
break;
|
||||
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
return 0;
|
||||
@ -1204,7 +1167,7 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
assertAdmin();
|
||||
|
||||
pkey.generate(ec);
|
||||
pkey.generate();
|
||||
|
||||
if(do_reset) {
|
||||
JCSystem.beginTransaction();
|
||||
@ -1286,7 +1249,7 @@ public final class SmartPGPApplet extends Applet {
|
||||
return res;
|
||||
}
|
||||
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].decipher(ec, transients.buffer, lc);
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_DEC].decipher(transients.buffer, lc);
|
||||
}
|
||||
|
||||
/* PSO : ENCIPHER */
|
||||
@ -1332,9 +1295,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
sensitiveData();
|
||||
assertUserMode82();
|
||||
return data.pgp_keys[Persistent.PGP_KEYS_OFFSET_AUT].sign(transients.buffer, lc, true);
|
||||
|
||||
case (byte)0x01:
|
||||
return sm.establish(transients, ec, transients.buffer, lc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1390,10 +1350,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
if(data.isTerminated) {
|
||||
switch(p2) {
|
||||
case (byte)1:
|
||||
sm.reset(transients);
|
||||
//missing break is intentional
|
||||
|
||||
case (byte)0:
|
||||
transients.clear();
|
||||
data.reset();
|
||||
@ -1411,7 +1367,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
data.user_puk.reset();
|
||||
data.admin_pin.reset();
|
||||
transients.clear();
|
||||
sm.clearSession(transients);
|
||||
}
|
||||
|
||||
public final void process(final APDU apdu) {
|
||||
@ -1429,8 +1384,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
return;
|
||||
}
|
||||
|
||||
transients.setSecureMessagingOk(false);
|
||||
|
||||
if(data.isTerminated) {
|
||||
if(apdubuf[ISO7816.OFFSET_CLA] != 0) {
|
||||
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
|
||||
@ -1480,34 +1433,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
|
||||
short lc = transients.chainingInputLength();
|
||||
|
||||
if((apdubuf[ISO7816.OFFSET_CLA] & Constants.CLA_MASK_SECURE_MESSAGING) == Constants.CLA_MASK_SECURE_MESSAGING) {
|
||||
short off = lc;
|
||||
|
||||
if((short)(off + 1 + 1 + 1 + 1 + 3) > Constants.INTERNAL_BUFFER_MAX_LENGTH) {
|
||||
ISOException.throwIt(Constants.SW_MEMORY_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
transients.buffer[off++] = apdubuf[ISO7816.OFFSET_CLA];
|
||||
transients.buffer[off++] = apdubuf[ISO7816.OFFSET_INS];
|
||||
transients.buffer[off++] = p1;
|
||||
transients.buffer[off++] = p2;
|
||||
if(lc > (short)0xff) {
|
||||
transients.buffer[off++] = (byte)0;
|
||||
transients.buffer[off++] = (byte)((lc >> 8) & (byte)0xff);
|
||||
}
|
||||
transients.buffer[off++] = (byte)(lc & (byte)0xff);
|
||||
|
||||
transients.setChainingInputLength((short)0);
|
||||
|
||||
lc = sm.verifyAndDecryptCommand(transients, lc, off);
|
||||
|
||||
transients.setSecureMessagingOk(true);
|
||||
|
||||
} else if(sm.isSessionAvailable()) {
|
||||
clearConnection();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
switch(apdubuf[ISO7816.OFFSET_INS]) {
|
||||
@ -1576,23 +1501,6 @@ public final class SmartPGPApplet extends Applet {
|
||||
sw = e.getReason();
|
||||
}
|
||||
|
||||
if(transients.secureMessagingOk()) {
|
||||
|
||||
if(available_le > 0) {
|
||||
short tmp = (short)(Constants.AES_BLOCK_SIZE - (available_le % Constants.AES_BLOCK_SIZE));
|
||||
available_le = Util.arrayCopyNonAtomic(SecureMessaging.PADDING_BLOCK, (short)0,
|
||||
transients.buffer, available_le,
|
||||
tmp);
|
||||
}
|
||||
|
||||
if((available_le != 0) ||
|
||||
(sw == (short)0x9000) ||
|
||||
((short)(sw & (short)0x6200) == (short)0x6200) ||
|
||||
((short)(sw & (short)0x6300) == (short)0x6300)) {
|
||||
available_le = sm.encryptAndSign(transients, available_le, sw);
|
||||
}
|
||||
}
|
||||
|
||||
transients.setOutputLength(available_le);
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,7 @@ public final class Transients {
|
||||
private static final byte SHORT_OFFSET_OUTPUT_START = SHORT_OFFSET_CURRENT_TAG + 1;
|
||||
private static final byte SHORT_OFFSET_OUTPUT_LENGTH = SHORT_OFFSET_OUTPUT_START + 1;
|
||||
private static final byte SHORT_OFFSET_CHAINING_INPUT_LENGTH = SHORT_OFFSET_OUTPUT_LENGTH + 1;
|
||||
private static final byte SHORT_OFFSET_SECURE_MESSAGING_ENCRYPTION_COUNTER = SHORT_OFFSET_CHAINING_INPUT_LENGTH + 1;
|
||||
private static final byte SHORTS_SIZE = SHORT_OFFSET_SECURE_MESSAGING_ENCRYPTION_COUNTER + 1;
|
||||
private static final byte SHORTS_SIZE = SHORT_OFFSET_CHAINING_INPUT_LENGTH + 1;
|
||||
|
||||
private final byte[] bytes;
|
||||
private static final byte BYTE_OFFSET_CHAINING_INPUT_INS = 0;
|
||||
@ -46,8 +45,7 @@ public final class Transients {
|
||||
private static final byte BOOLEAN_OFFSET_CHAINING_INPUT = BOOLEAN_OFFSET_CHAINING_OUTPUT + 1;
|
||||
private static final byte BOOLEAN_OFFSET_USER_PIN_MODE_81 = BOOLEAN_OFFSET_CHAINING_INPUT + 1;
|
||||
private static final byte BOOLEAN_OFFSET_USER_PIN_MODE_82 = BOOLEAN_OFFSET_USER_PIN_MODE_81 + 1;
|
||||
private static final byte BOOLEAN_OFFSET_SECURE_MESSAGING_OK = BOOLEAN_OFFSET_USER_PIN_MODE_82 + 1;
|
||||
private static final byte BOOLEANS_SIZE = BOOLEAN_OFFSET_SECURE_MESSAGING_OK + 1;
|
||||
private static final byte BOOLEANS_SIZE = BOOLEAN_OFFSET_USER_PIN_MODE_82 + 1;
|
||||
|
||||
|
||||
protected Transients() {
|
||||
@ -89,14 +87,6 @@ public final class Transients {
|
||||
return shorts[SHORT_OFFSET_CHAINING_INPUT_LENGTH];
|
||||
}
|
||||
|
||||
protected final void setSecureMessagingEncryptionCounter(final short val) {
|
||||
shorts[SHORT_OFFSET_SECURE_MESSAGING_ENCRYPTION_COUNTER] = val;
|
||||
}
|
||||
|
||||
protected final short secureMessagingEncryptionCounter() {
|
||||
return shorts[SHORT_OFFSET_SECURE_MESSAGING_ENCRYPTION_COUNTER];
|
||||
}
|
||||
|
||||
protected final void setOutputStart(final short off) {
|
||||
shorts[SHORT_OFFSET_OUTPUT_START] = off;
|
||||
}
|
||||
@ -177,12 +167,4 @@ public final class Transients {
|
||||
return booleans[BOOLEAN_OFFSET_USER_PIN_MODE_82];
|
||||
}
|
||||
|
||||
protected final void setSecureMessagingOk(final boolean ok) {
|
||||
booleans[BOOLEAN_OFFSET_SECURE_MESSAGING_OK] = ok;
|
||||
}
|
||||
|
||||
protected final boolean secureMessagingOk() {
|
||||
return booleans[BOOLEAN_OFFSET_SECURE_MESSAGING_OK];
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user