Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,12 @@

public class KMAESKey implements KMMasterKey {

private AESKey aesKey;
public AESKey aesKey;

public KMAESKey(AESKey key) {
aesKey = key;
}

public void setKey(byte[] keyData, short kOff) {
aesKey.setKey(keyData, kOff);
}

public AESKey getKey() {
return aesKey;
}

public short getKeySizeBits() {
return aesKey.getSize();
}

public static void onSave(Element element, KMAESKey kmKey) {
element.write(kmKey.aesKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
import javacard.framework.ISOException;

public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeListener {
// provisionStatus - 1 byte
// keymasterState - 1 byte
// MagicNumber - 1 byte
// Applet package version - 2 bytes.
private static final byte PRIMITIVE_DATA_STORAGE_SIZE = 0x05;

KMAndroidSEApplet() {
super(new KMAndroidSEProvider());
Expand Down Expand Up @@ -78,8 +83,8 @@ public Element onSave() {
primitiveCount += repository.getBackupPrimitiveByteCount();
objectCount += repository.getBackupObjectCount();
//KMKeymasterApplet count
primitiveCount += computePrimitveDataSize();
objectCount += computeObjectCount();
primitiveCount += PRIMITIVE_DATA_STORAGE_SIZE;
// No objects to be stored in KMAndroidSEApplet.

// Create element.
Element element = UpgradeManager.createElement(Element.TYPE_SIMPLE,
Expand All @@ -93,15 +98,6 @@ public Element onSave() {
return element;
}

private short computePrimitveDataSize() {
// provisionStatus + keymasterState + magic byte + version
return (short) 5;
}

private short computeObjectCount() {
return (short) 0;
}

public boolean isUpgradeAllowed(short oldVersion) {
boolean upgradeAllowed = false;
short oldMajorVersion = (short) ((oldVersion >> 8) & 0x00FF);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.globalplatform.upgrade.Element;
import org.globalplatform.upgrade.UpgradeManager;
import org.jcp.xml.dsig.internal.dom.Utils;

import javacard.framework.APDU;
import javacard.framework.JCSystem;
Expand Down Expand Up @@ -227,14 +228,18 @@ public KMAndroidSEProvider() {
initECKey(ecKeyPair);

// Re-usable cipher and signature instances
cipherPool = new Object[(short) (CIPHER_ALGS.length * 4)];
cipherPool = new Object[(short) (CIPHER_ALGS.length * MAX_OPERATION_INSTANCES)];
// Extra 4 algorithms are used to support TRUSTED_CONFIRMATION_REQUIRED feature.
sigPool = new Object[(short) ((SIG_ALGS.length * 4) + 4)];
sigPool =
new Object[(short) ((SIG_ALGS.length * MAX_OPERATION_INSTANCES)
+ MAX_OPERATION_INSTANCES)];
operationPool = new Object[MAX_OPERATION_INSTANCES];
hmacSignOperationPool = new Object[MAX_OPERATION_INSTANCES];
// Reserve (KEY_ALGS.length * 4) + 4) size of key pool
// Extra 4 keys for TRUSTED_CONFIRMATION_REQUIRED feature.
keysPool = new Object[(short) ((KEY_ALGS.length * 4) + 4)];
keysPool =
new Object[(short) ((KEY_ALGS.length * MAX_OPERATION_INSTANCES)
+ MAX_OPERATION_INSTANCES)];

// Creates an instance of each cipher algorithm once.
initializeCipherPool();
Expand Down Expand Up @@ -298,55 +303,45 @@ private void initECKey(KeyPair ecKeyPair) {
}

private boolean isCipherAlgorithm(byte alg) {
short index = 0;
while (index < CIPHER_ALGS.length) {
if (CIPHER_ALGS[index++] == alg) {
for (short index = 0; index < CIPHER_ALGS.length; index++) {
if (CIPHER_ALGS[index] == alg) {
return true;
}
}
return false;
}

private boolean isSignerAlgorithm(byte alg) {
short index = 0;
while (index < SIG_ALGS.length) {
if (SIG_ALGS[index++] == alg) {
for (short index = 0; index < SIG_ALGS.length; index++) {
if (SIG_ALGS[index] == alg) {
return true;
}
}
return false;
}

private void initializeOperationPool() {
short index = 0;
while (index < MAX_OPERATION_INSTANCES) {
for (short index = 0; index < MAX_OPERATION_INSTANCES; index++) {
operationPool[index] = new KMOperationImpl();
index++;
}
}

private void initializeHmacSignOperationPool() {
short index = 0;
while (index < MAX_OPERATION_INSTANCES) {
for (short index = 0; index < MAX_OPERATION_INSTANCES; index++) {
hmacSignOperationPool[index] = new KMOperationImpl();
index++;
}
}

// Create a signature instance of each algorithm once.
private void initializeSigPool() {
short index = 0;
while (index < SIG_ALGS.length) {
for (short index = 0; index < SIG_ALGS.length; index++) {
sigPool[index] = getSignatureInstance(SIG_ALGS[index]);
index++;
}
}

private void initializeKeysPool() {
short index = 0;
while (index < KEY_ALGS.length) {
for (short index = 0; index < KEY_ALGS.length; index++) {
keysPool[index] = createKeyObjectInstance(KEY_ALGS[index]);
index++;
}
}

Expand All @@ -371,10 +366,8 @@ private Cipher getCipherInstance(byte alg) {

// Create a cipher instance of each algorithm once.
private void initializeCipherPool() {
short index = 0;
while (index < CIPHER_ALGS.length) {
for (short index = 0; index < CIPHER_ALGS.length; index++) {
cipherPool[index] = getCipherInstance(CIPHER_ALGS[index]);
index++;
}
}

Expand Down Expand Up @@ -477,13 +470,13 @@ public KMKeyObject getKeyObjectFromPool(byte algo, short secretLength) {
if (KMType.HMAC == algo) {
maxOperations = HMAC_MAX_OPERATION_INSTANCES;
}
if(algo == KMType.AES) {
if (algo == KMType.AES) {
if (secretLength == 16) {
algo = AES_128;
} else if (secretLength == 32) {
algo = AES_256;
algo = AES_256;
} else {
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
}
}
short index = 0;
Expand All @@ -500,7 +493,7 @@ public KMKeyObject getKeyObjectFromPool(byte algo, short secretLength) {
break;
}
keyObject = (KMKeyObject) keysPool[index];
if (algo == keyObject.getAlgorithm()) {
if (algo == keyObject.algorithm) {
// Check if the Object instance is not busy and free to use.
if (!isResourceBusy(keyObject, RESOURCE_TYPE_KEY)) {
break;
Expand Down Expand Up @@ -797,8 +790,7 @@ public HMACKey cmacKdf(KMPreSharedKey preSharedKey, byte[] label, short labelSta
short iBufLen = 4;
short keyOutLen = n * 16;
//Convert Hmackey to AES Key as the algorithm is ALG_AES_CMAC_128.
KMHmacKey hmacKey = ((KMHmacKey) preSharedKey);
hmacKey.getKey(tmpArray, (short) 0);
((KMHmacKey) preSharedKey).hmacKey.getKey(tmpArray, (short) 0);
aesKeys[KEYSIZE_256_OFFSET].setKey(tmpArray, (short) 0);
//Initialize the key derivation function.
kdf.init(aesKeys[KEYSIZE_256_OFFSET], Signature.MODE_SIGN);
Expand Down Expand Up @@ -837,8 +829,7 @@ public short hmacSign(HMACKey key, byte[] data, short dataStart,
@Override
public boolean hmacVerify(KMComputedHmacKey key, byte[] data, short dataStart,
short dataLength, byte[] mac, short macStart, short macLength) {
KMHmacKey hmacKey = (KMHmacKey) key;
hmacSignature.init(hmacKey.getKey(), Signature.MODE_VERIFY);
hmacSignature.init(((KMHmacKey) key).hmacKey, Signature.MODE_VERIFY);
return hmacSignature.verify(data, dataStart, dataLength, mac, macStart,
macLength);
}
Expand All @@ -854,10 +845,9 @@ public short hmacSign(byte[] keyBuf, short keyStart, short keyLength,
public short hmacKDF(KMMasterKey masterkey, byte[] data, short dataStart,
short dataLength, byte[] signature, short signatureStart) {
try {
AESKey aesKey = ((KMAESKey) masterkey).getKey();
aesKey.getKey(tmpArray, (short) 0);
((KMAESKey) masterkey).aesKey.getKey(tmpArray, (short) 0);
HMACKey key = createHMACKey(tmpArray, (short) 0,
(short) (aesKey.getSize() / 8));
(short) (((KMAESKey) masterkey).aesKey.getSize() / 8));
return hmacSign(key, data, dataStart, dataLength, signature,
signatureStart);
} finally {
Expand Down Expand Up @@ -983,7 +973,7 @@ private byte mapCipherAlg(byte alg, byte padding, byte blockmode, byte digest) {
public Cipher createSymmetricCipher(short alg, short purpose,
short blockMode, short padding, byte[] secret, short secretStart,
short secretLength, byte[] ivBuffer, short ivStart, short ivLength, KMKeyObject keyObject) {
Key key = (Key) keyObject.getKeyObjectInstance();
Key key = (Key) keyObject.keyObjectInst;
Cipher symmCipher = null;
switch (secretLength) {
case 16:
Expand Down Expand Up @@ -1026,7 +1016,7 @@ public Cipher createSymmetricCipher(short alg, short purpose,

private Signature createHmacSignerVerifier(short purpose, short digest,
byte[] secret, short secretStart, short secretLength, KMKeyObject keyObject) {
HMACKey key = (HMACKey) keyObject.getKeyObjectInstance();
HMACKey key = (HMACKey) keyObject.keyObjectInst;
key.setKey(secret, secretStart, secretLength);
return createHmacSignerVerifier(purpose, digest, key);
}
Expand Down Expand Up @@ -1084,8 +1074,7 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg,
@Override
public KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey) {
KMOperationImpl opr = null;
KMHmacKey key = (KMHmacKey) computedHmacKey;
short len = key.getKey(tmpArray, (short) 0);
short len = ((KMHmacKey) computedHmacKey).hmacKey.getKey(tmpArray, (short) 0);
KMKeyObject keyObject = getKeyObjectFromPool(KMType.HMAC, len);
Signature signerVerifier = createHmacSignerVerifier(KMType.VERIFY, KMType.SHA2_256, tmpArray,
(short) 0, len, keyObject);
Expand All @@ -1108,7 +1097,7 @@ public Signature createRsaSigner(short digest, short padding, byte[] secret,
opMode = Signature.MODE_SIGN;
}
Signature rsaSigner = getSignatureInstanceFromPool(alg);
RSAPrivateKey key = (RSAPrivateKey) ((KeyPair)(keyObject.getKeyObjectInstance())).getPrivate();
RSAPrivateKey key = (RSAPrivateKey) ((KeyPair)(keyObject.keyObjectInst)).getPrivate();
key.setExponent(secret, secretStart, secretLength);
key.setModulus(modBuffer, modOff, modLength);
rsaSigner.init(key, opMode);
Expand All @@ -1120,7 +1109,7 @@ public Cipher createRsaDecipher(short padding, short digest, byte[] secret,
short modLength, KMKeyObject keyObject) {
byte cipherAlg = mapCipherAlg(KMType.RSA, (byte) padding, (byte) 0, (byte) digest);
Cipher rsaCipher = getCipherInstanceFromPool(cipherAlg);
RSAPrivateKey key = (RSAPrivateKey) ((KeyPair)(keyObject.getKeyObjectInstance())).getPrivate();
RSAPrivateKey key = (RSAPrivateKey) ((KeyPair)(keyObject.keyObjectInst)).getPrivate();
key.setExponent(secret, secretStart, secretLength);
key.setModulus(modBuffer, modOff, modLength);
rsaCipher.init(key, Cipher.MODE_DECRYPT);
Expand All @@ -1131,7 +1120,7 @@ public Signature createEcSigner(short digest, byte[] secret,
short secretStart, short secretLength, KMKeyObject keyObject) {
byte alg = mapSignature256Alg(KMType.EC, (byte) 0, (byte) digest);
Signature ecSigner = null;
ECPrivateKey key = (ECPrivateKey) ((KeyPair)(keyObject.getKeyObjectInstance())).getPrivate();
ECPrivateKey key = (ECPrivateKey) ((KeyPair)(keyObject.keyObjectInst)).getPrivate();
key.setS(secret, secretStart, secretLength);
ecSigner = getSignatureInstanceFromPool(alg);
ecSigner.init(key, Signature.MODE_SIGN);
Expand Down Expand Up @@ -1358,7 +1347,7 @@ public KMMasterKey createMasterKey(short keySizeBits) {
masterKey = new KMAESKey(key);
short keyLen = (short) (keySizeBits / 8);
getTrueRandomNumber(tmpArray, (short) 0, keyLen);
masterKey.setKey(tmpArray, (short) 0);
((KMAESKey) masterKey).aesKey.setKey(tmpArray, (short) 0);
}
return (KMMasterKey) masterKey;
} finally {
Expand All @@ -1375,10 +1364,11 @@ public KMAttestationKey createAttestationKey(byte[] keyData, short offset,
initECKey(ecKeyPair);
attestationKey = new KMECPrivateKey(ecKeyPair);
}
attestationKey.setS(keyData, offset, length);
ECPrivateKey ecPriv = (ECPrivateKey) ((KMECPrivateKey) attestationKey).ecKeyPair.getPrivate();
ecPriv.setS(keyData, offset, length);
return (KMAttestationKey) attestationKey;
}

@Override
public KMComputedHmacKey createComputedHmacKey(byte[] keyData, short offset, short length) {
if (length != COMPUTED_HMAC_KEY_SIZE) {
Expand All @@ -1389,7 +1379,7 @@ public KMComputedHmacKey createComputedHmacKey(byte[] keyData, short offset, sho
false);
computedHmacKey = new KMHmacKey(key);
}
computedHmacKey.setKey(keyData, offset, length);
((KMHmacKey) computedHmacKey).hmacKey.setKey(keyData, offset, length);
return (KMComputedHmacKey) computedHmacKey;
}

Expand All @@ -1404,7 +1394,7 @@ public KMPreSharedKey createPresharedKey(byte[] keyData, short offset, short len
false);
preSharedKey = new KMHmacKey(key);
}
preSharedKey.setKey(keyData, offset, length);
((KMHmacKey) preSharedKey).hmacKey.setKey(keyData, offset, length);
return (KMPreSharedKey) preSharedKey;
}

Expand Down Expand Up @@ -1502,7 +1492,10 @@ private KMKeyObject createKeyObjectInstance(byte alg) {
KMException.throwIt(KMError.UNSUPPORTED_ALGORITHM);
}
KMKeyObject ptr = new KMKeyObject();
ptr.setKeyObjectData(alg, keyObject);
JCSystem.beginTransaction();
ptr.algorithm = alg;
ptr.keyObjectInst = keyObject;
JCSystem.commitTransaction();
return ptr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff,

timeOffset = KMByteBlob.instance((short) 32);
//Get the key data from the master key and use it for HMAC Sign.
AESKey aesKey = ((KMAESKey) masterKey).getKey();
AESKey aesKey = ((KMAESKey) masterKey).aesKey;
short mKeyData = KMByteBlob.instance((short) (aesKey.getSize() / 8));
aesKey.getKey(
KMByteBlob.cast(mKeyData).getBuffer(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,12 @@

public class KMECPrivateKey implements KMAttestationKey {

private KeyPair ecKeyPair;
public KeyPair ecKeyPair;

public KMECPrivateKey(KeyPair ecPair) {
ecKeyPair = ecPair;
}

public void setS(byte[] buffer, short offset, short length) {
ECPrivateKey ecPriv = (ECPrivateKey) ecKeyPair.getPrivate();
ecPriv.setS(buffer, offset, length);
}

public short getS(byte[] buffer, short offset) {
ECPrivateKey ecPriv = (ECPrivateKey) ecKeyPair.getPrivate();
return ecPriv.getS(buffer, offset);
}

public ECPrivateKey getPrivateKey() {
return (ECPrivateKey) ecKeyPair.getPrivate();
}
Expand Down
Loading