Version without elliptic curves and secure messaging compatible with JavaCard 3.0.1

This commit is contained in:
Arnaud Fontaine 2017-07-18 15:03:15 +02:00
parent ab7baa6a55
commit 309dbbad8a
12 changed files with 24 additions and 2020 deletions

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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
};
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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()];

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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];
}
}