From 6ab06673d808041dd8c164f2fcc10db505a4e6bb Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Fri, 5 Feb 2021 18:32:45 +0530 Subject: [PATCH 1/6] store secrets as keyobjects instead as byte arrays. --- .../android/javacard/keymaster/KMAESKey.java | 46 +++++ .../keymaster/KMAndroidSEProvider.java | 181 +++++++++++++++--- .../keymaster/KMAttestationCertImpl.java | 32 ++-- .../javacard/keymaster/KMECPrivateKey.java | 68 +++++++ .../android/javacard/keymaster/KMHmacKey.java | 59 ++++++ .../javacard/keymaster/KMRsaOAEPEncoding.java | 2 - .../android/javacard/keymaster/KMAESKey.java | 58 ++++++ .../keymaster/KMAttestationCertImpl.java | 26 +-- .../javacard/keymaster/KMECPrivateKey.java | 38 ++++ .../android/javacard/keymaster/KMHmacKey.java | 38 ++++ .../javacard/keymaster/KMJCardSimulator.java | 117 +++++++++-- .../javacard/keymaster/KMAttestationCert.java | 14 +- .../javacard/keymaster/KMAttestationKey.java | 28 +++ .../javacard/keymaster/KMKeymasterApplet.java | 31 ++- .../javacard/keymaster/KMMasterKey.java | 28 +++ .../javacard/keymaster/KMPreSharedKey.java | 28 +++ .../javacard/keymaster/KMRepository.java | 62 ++---- .../javacard/keymaster/KMSEProvider.java | 114 +++++++++-- 18 files changed, 809 insertions(+), 161 deletions(-) create mode 100644 Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java create mode 100644 Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java create mode 100644 Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMHmacKey.java create mode 100644 Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java create mode 100644 Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java create mode 100644 Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMHmacKey.java create mode 100644 Applet/src/com/android/javacard/keymaster/KMAttestationKey.java create mode 100644 Applet/src/com/android/javacard/keymaster/KMMasterKey.java create mode 100644 Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java new file mode 100644 index 00000000..95896b13 --- /dev/null +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java @@ -0,0 +1,46 @@ +package com.android.javacard.keymaster; + +import org.globalplatform.upgrade.Element; + +import com.android.javacard.keymaster.KMMasterKey; + +import javacard.security.AESKey; + +public class KMAESKey implements KMMasterKey { + private 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); + } + + public static KMAESKey onRestore(Element element) { + AESKey aesKey = (AESKey) element.readObject(); + KMAESKey kmKey = new KMAESKey(aesKey); + return kmKey; + } + + public static short getBackupPrimitiveByteCount() { + return (short) 0; + } + + public static short getBackupObjectCount() { + return (short) 1; + } + +} diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index 20417d0f..d182ca02 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -37,6 +37,13 @@ import javacardx.crypto.AEADCipher; import javacardx.crypto.Cipher; +import com.android.javacard.keymaster.KMAESKey; +import com.android.javacard.keymaster.KMAttestationKey; +import com.android.javacard.keymaster.KMECPrivateKey; +import com.android.javacard.keymaster.KMHmacKey; +import com.android.javacard.keymaster.KMMasterKey; +import com.android.javacard.keymaster.KMPreSharedKey; + public class KMAndroidSEProvider implements KMSEProvider { // static final variables // -------------------------------------------------------------- @@ -158,6 +165,9 @@ public class KMAndroidSEProvider implements KMSEProvider { private RandomData rng; //For storing root certificate and intermediate certificates. private byte[] certificateChain; + private KMAESKey masterKey; + private KMECPrivateKey attestationKey; + private KMHmacKey preSharedKey; private static KMAndroidSEProvider androidSEProvider = null; @@ -177,7 +187,8 @@ public KMAndroidSEProvider() { hmacKey = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, (short) 512, false); rsaKeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048); - initECKey(); + ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); + initECKey(ecKeyPair); // Re-usable cipher and signature instances cipherPool = new Object[(short) (CIPHER_ALGS.length * 4)]; @@ -210,8 +221,7 @@ public void clean() { Util.arrayFillNonAtomic(tmpArray, (short) 0, (short) 256, (byte) 0); } - private void initECKey() { - ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); + private void initECKey(KeyPair ecKeyPair) { ECPrivateKey privKey = (ECPrivateKey) ecKeyPair.getPrivate(); ECPublicKey pubkey = (ECPublicKey) ecKeyPair.getPublic(); pubkey.setFieldFP(secp256r1_P, (short) 0, (short) secp256r1_P.length); @@ -600,13 +610,11 @@ public void addRngEntropy(byte[] num, short offset, short length) { rng.setSeed(num, offset, length); } - @Override - public short aesGCMEncrypt(byte[] aesKey, short aesKeyStart, short aesKeyLen, - byte[] secret, short secretStart, short secretLen, byte[] encSecret, - short encSecretStart, byte[] nonce, short nonceStart, short nonceLen, - byte[] authData, short authDataStart, short authDataLen, byte[] authTag, - short authTagStart, short authTagLen) { - + public short aesGCMEncrypt(AESKey key, + byte[] secret, short secretStart, short secretLen, byte[] encSecret, + short encSecretStart, byte[] nonce, short nonceStart, short nonceLen, + byte[] authData, short authDataStart, short authDataLen, byte[] authTag, + short authTagStart, short authTagLen) { if (authTagLen != AES_GCM_TAG_LENGTH) { CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } @@ -617,7 +625,6 @@ public short aesGCMEncrypt(byte[] aesKey, short aesKeyStart, short aesKeyLen, aesGcmCipher = (AEADCipher) Cipher.getInstance(AEADCipher.ALG_AES_GCM, false); } - AESKey key = createAESKey(aesKey, aesKeyStart, aesKeyLen); aesGcmCipher.init(key, Cipher.MODE_ENCRYPT, nonce, nonceStart, nonceLen); aesGcmCipher.updateAAD(authData, authDataStart, authDataLen); short ciphLen = aesGcmCipher.doFinal(secret, secretStart, secretLen, @@ -626,6 +633,32 @@ public short aesGCMEncrypt(byte[] aesKey, short aesKeyStart, short aesKeyLen, return ciphLen; } + @Override + public short aesGCMEncrypt(byte[] aesKey, short aesKeyStart, short aesKeyLen, + byte[] secret, short secretStart, short secretLen, byte[] encSecret, + short encSecretStart, byte[] nonce, short nonceStart, short nonceLen, + byte[] authData, short authDataStart, short authDataLen, byte[] authTag, + short authTagStart, short authTagLen) { + + AESKey key = createAESKey(aesKey, aesKeyStart, aesKeyLen); + return aesGCMEncrypt( + key, + secret, + secretStart, + secretLen, + encSecret, + encSecretStart, + nonce, + nonceStart, + nonceLen, + authData, + authDataStart, + authDataLen, + authTag, + authTagStart, + authTagLen); + } + @Override public boolean aesGCMDecrypt(byte[] aesKey, short aesKeyStart, short aesKeyLen, byte[] encSecret, short encSecretStart, @@ -648,8 +681,7 @@ public boolean aesGCMDecrypt(byte[] aesKey, short aesKeyStart, return verification; } - public HMACKey cmacKdf(byte[] keyMaterial, short keyMaterialStart, - short keyMaterialLen, byte[] label, short labelStart, short labelLen, + public HMACKey cmacKdf(KMPreSharedKey preSharedKey, byte[] label, short labelStart, short labelLen, byte[] context, short contextStart, short contextLength) { try { // This is hardcoded to requirement - 32 byte output with two concatenated @@ -667,10 +699,18 @@ public HMACKey cmacKdf(byte[] keyMaterial, short keyMaterialStart, // [i] counter - 32 bits 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); + aesKeys[KEYSIZE_256_OFFSET].setKey(tmpArray, (short) 0); + //Initialize the key derivation function. + kdf.init(aesKeys[KEYSIZE_256_OFFSET], Signature.MODE_SIGN); + //Clear the tmpArray buffer. + Util.arrayFillNonAtomic(tmpArray, (short) 0, (short) 256, (byte) 0); + Util.arrayFillNonAtomic(tmpArray, (short) 0, iBufLen, (byte) 0); Util.arrayFillNonAtomic(tmpArray, (short) iBufLen, keyOutLen, (byte) 0); - aesKeys[KEYSIZE_256_OFFSET].setKey(keyMaterial, (short) keyMaterialStart); - kdf.init(aesKeys[KEYSIZE_256_OFFSET], Signature.MODE_SIGN); + byte i = 1; short pos = 0; while (i <= n) { @@ -733,17 +773,15 @@ public short rsaDecipherOAEP256(byte[] secret, short secretStart, outputDataBuf, (short) outputDataStart); } - public short ecSign256(byte[] secret, short secretStart, short secretLength, + public short ecSign256(KMAttestationKey attestationKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { Signature.OneShot signer = null; try { - ECPrivateKey key = (ECPrivateKey) ecKeyPair.getPrivate(); - key.setS(secret, secretStart, secretLength); signer = Signature.OneShot.open(MessageDigest.ALG_SHA_256, Signature.SIG_CIPHER_ECDSA, Cipher.PAD_NULL); - signer.init(key, Signature.MODE_SIGN); + signer.init(((KMECPrivateKey)attestationKey).getPrivateKey(), Signature.MODE_SIGN); return signer.sign(inputDataBuf, inputDataStart, inputDataLength, outputDataBuf, outputDataStart); } finally { @@ -975,7 +1013,7 @@ public Cipher createRsaCipher(short padding, short digest, byte[] modBuffer, short modOff, short modLength) { try { byte cipherAlg = mapCipherAlg(KMType.RSA, (byte) padding, (byte) 0, (byte)digest); - // TODO Java Card does not support MGF1-SHA1 and digest as SHA256. + // Java Card does not support MGF1-SHA1 and digest as SHA256. // Both digest should be SHA256 as per Java Card, but as per Keymaster // MGF should use SHA1 and message digest should be SHA256. if (cipherAlg == Cipher.ALG_RSA_PKCS1_OAEP) { @@ -1116,12 +1154,11 @@ public KMAttestationCert getAttestationCert(boolean rsaCert) { } @Override - public short cmacKdf(byte[] keyMaterial, short keyMaterialStart, - short keyMaterialLen, byte[] label, short labelStart, short labelLen, - byte[] context, short contextStart, short contextLength, byte[] keyBuf, - short keyStart) { - HMACKey key = cmacKdf(keyMaterial, keyMaterialStart, keyMaterialLen, label, - labelStart, labelLen, context, contextStart, contextLength); + public short cmacKdf(KMPreSharedKey pSharedKey, byte[] label, + short labelStart, short labelLen, byte[] context, short contextStart, + short contextLength, byte[] keyBuf, short keyStart) { + HMACKey key = cmacKdf(pSharedKey, label, labelStart, labelLen, context, + contextStart, contextLength); return key.getKey(keyBuf, keyStart); } @@ -1187,25 +1224,113 @@ public void clearDeviceBooted(boolean resetBootFlag) { @Override public void onSave(Element element) { element.write(certificateChain); + KMAESKey.onSave(element, masterKey); + KMECPrivateKey.onSave(element, attestationKey); + KMHmacKey.onSave(element, preSharedKey); } @Override public void onRestore(Element element) { certificateChain = (byte[]) element.readObject(); + masterKey = KMAESKey.onRestore(element); + attestationKey = KMECPrivateKey.onRestore(element); + preSharedKey = KMHmacKey.onRestore(element); } @Override public short getBackupPrimitiveByteCount() { - return (short) 0; + short count = + (short) (KMAESKey.getBackupPrimitiveByteCount() + + KMECPrivateKey.getBackupPrimitiveByteCount() + + KMHmacKey.getBackupPrimitiveByteCount()); + return count; } @Override public short getBackupObjectCount() { - return (short) 1; + short count = + (short) (1 /*Certificate chain */ + + KMAESKey.getBackupObjectCount() + + KMECPrivateKey.getBackupObjectCount() + + KMHmacKey.getBackupObjectCount()); + return count; } @Override public boolean isUpgrading() { return UpgradeManager.isUpgrading(); } + + @Override + public KMMasterKey createMasterKey(short keySizeBits) { + try { + if (masterKey == null) { + AESKey key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, + keySizeBits, false); + masterKey = new KMAESKey(key); + short keyLen = (short) (keySizeBits / 8); + getTrueRandomNumber(tmpArray, (short) 0, keyLen); + masterKey.setKey(tmpArray, (short) 0); + } + return (KMMasterKey) masterKey; + } finally { + clean(); + } + } + + @Override + public KMAttestationKey createAttestationKey(byte[] keyData, short offset, + short length) { + if (attestationKey == null) { + // Strongbox supports only P-256 curve for EC key. + KeyPair ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); + initECKey(ecKeyPair); + attestationKey = new KMECPrivateKey(ecKeyPair); + } + attestationKey.setS(keyData, offset, length); + return (KMAttestationKey) attestationKey; + } + + @Override + public KMPreSharedKey createPresharedKey(byte[] keyData, short offset, short length) { + short lengthInBits = (short)(length * 8); + if ((lengthInBits % 8 != 0) || !(lengthInBits >= 64 && lengthInBits <= 512)) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + if (preSharedKey == null) { + HMACKey key = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, lengthInBits, + false); + preSharedKey = new KMHmacKey(key); + } + preSharedKey.setKey(keyData, offset, length); + return (KMPreSharedKey) preSharedKey; + } + + @Override + public KMMasterKey getMasterKey() { + return (KMMasterKey) masterKey; + } + + @Override + public KMAttestationKey getAttestationKey() { + return (KMAttestationKey) attestationKey; + } + + @Override + public KMPreSharedKey getPresharedKey() { + return (KMPreSharedKey) preSharedKey; + } + + @Override + public short aesGCMEncrypt(KMMasterKey key, byte[] secret, short secretStart, + short secretLen, byte[] encSecret, short encSecretStart, + byte[] nonce, short nonceStart, short nonceLen, byte[] authData, + short authDataStart, short authDataLen, byte[] authTag, + short authTagStart, short authTagLen) { + + return aesGCMEncrypt(((KMAESKey) key).getKey(), secret, secretStart, + secretLen, encSecret, encSecretStart, nonce, nonceStart, nonceLen, + authData, authDataStart, authDataLen, authTag, authTagStart, + authTagLen); + } } diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 5a36e3c3..bf6ae9b7 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -1,7 +1,13 @@ package com.android.javacard.keymaster; +import com.android.javacard.keymaster.KMAESKey; +import com.android.javacard.keymaster.KMByteBlob; +import com.android.javacard.keymaster.KMECPrivateKey; +import com.android.javacard.keymaster.KMMasterKey; + import javacard.framework.JCSystem; import javacard.framework.Util; +import javacard.security.AESKey; // The class encodes strongbox generated amd signed attestation certificate. This only encodes // required fields of the certificates. It is not meant to be generic X509 cert encoder. @@ -774,12 +780,6 @@ public KMAttestationCert buffer(byte[] buf, short bufStart, short maxLen) { return this; } - @Override - public KMAttestationCert signingKey(short privKey) { - signPriv = privKey; - return this; - } - @Override public short getCertStart() { return certStart; @@ -808,11 +808,10 @@ public void build() { tbsLength = (short) (tbsLength - tbsOffset); pushSequenceHeader((short) (last - stackPtr)); certStart = stackPtr; - short sigLen = KMAndroidSEProvider.getInstance() + KMAndroidSEProvider androidSeProvider = KMAndroidSEProvider.getInstance(); + short sigLen = androidSeProvider .ecSign256( - KMByteBlob.cast(signPriv).getBuffer(), - KMByteBlob.cast(signPriv).getStartOff(), - KMByteBlob.cast(signPriv).length(), + androidSeProvider.getAttestationKey(), stack, tbsOffset, tbsLength, @@ -833,7 +832,7 @@ public void build() { public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff, byte[] creationTime, short timeOffset, short creationTimeLen, byte[] attestAppId, short appIdOff, short attestAppIdLen, - byte resetSinceIdRotation, byte[] key, short keyOff, short keyLen) { + byte resetSinceIdRotation, KMMasterKey masterKey) { // Concatenate T||C||R // temporal count T short temp = KMUtils.countTemporalCount(creationTime, timeOffset, @@ -852,7 +851,16 @@ public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff, scratchPadOff++; timeOffset = KMByteBlob.instance((short) 32); - appIdOff = KMAndroidSEProvider.getInstance().hmacSign(key, keyOff, keyLen, + //Get the key data from the master key and use it for HMAC Sign. + AESKey aesKey = ((KMAESKey) masterKey).getKey(); + short mKeyData = KMByteBlob.instance((short) (aesKey.getSize() / 8)); + aesKey.getKey( + KMByteBlob.cast(mKeyData).getBuffer(), + KMByteBlob.cast(mKeyData).getStartOff()); + appIdOff = KMAndroidSEProvider.getInstance().hmacSign( + KMByteBlob.cast(mKeyData).getBuffer(), /* Key */ + KMByteBlob.cast(mKeyData).getStartOff(), /* Key start*/ + KMByteBlob.cast(mKeyData).length(), /* Key length*/ scratchPad, /* data */ temp, /* data start */ scratchPadOff, /* data length */ diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java new file mode 100644 index 00000000..fe6a636f --- /dev/null +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java @@ -0,0 +1,68 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +import org.globalplatform.upgrade.Element; + +import com.android.javacard.keymaster.KMAESKey; +import com.android.javacard.keymaster.KMAttestationCert; +import com.android.javacard.keymaster.KMAttestationKey; + +import javacard.security.AESKey; +import javacard.security.ECPrivateKey; +import javacard.security.KeyPair; + +public class KMECPrivateKey implements KMAttestationKey { + + private 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(); + } + + public static void onSave(Element element, KMECPrivateKey kmKey) { + element.write(kmKey.ecKeyPair); + } + + public static KMECPrivateKey onRestore(Element element) { + KeyPair ecKey = (KeyPair) element.readObject(); + KMECPrivateKey kmKey = new KMECPrivateKey(ecKey); + return kmKey; + } + + public static short getBackupPrimitiveByteCount() { + return (short) 0; + } + + public static short getBackupObjectCount() { + return (short) 1; + } + +} diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMHmacKey.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMHmacKey.java new file mode 100644 index 00000000..b4ca3af4 --- /dev/null +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMHmacKey.java @@ -0,0 +1,59 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +import org.globalplatform.upgrade.Element; + +import com.android.javacard.keymaster.KMPreSharedKey; + +import javacard.security.HMACKey; + +public class KMHmacKey implements KMPreSharedKey { + private HMACKey hmacKey; + + public KMHmacKey(HMACKey key) { + hmacKey = key; + } + + public void setKey(byte[] keyData, short kOff, short length) { + hmacKey.setKey(keyData, kOff, length); + } + + public byte getKey(byte[] keyData, short kOff) { + return hmacKey.getKey(keyData, kOff); + } + + public short getKeySizeBits() { + return hmacKey.getSize(); + } + public static void onSave(Element element, KMHmacKey kmKey) { + element.write(kmKey.hmacKey); + } + + public static KMHmacKey onRestore(Element element) { + HMACKey hmacKey = (HMACKey) element.readObject(); + KMHmacKey kmKey = new KMHmacKey(hmacKey); + return kmKey; + } + + public static short getBackupPrimitiveByteCount() { + return (short) 0; + } + + public static short getBackupObjectCount() { + return (short) 1; + } +} diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java index d4f4cb83..b8c7b30e 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java @@ -80,13 +80,11 @@ public byte getAlgorithm() { @Override public byte getCipherAlgorithm() { - // TODO return 0; } @Override public byte getPaddingAlgorithm() { - // TODO return 0; } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java new file mode 100644 index 00000000..c16a8188 --- /dev/null +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java @@ -0,0 +1,58 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +import org.globalplatform.upgrade.Element; + +import javacard.security.AESKey; + +public class KMAESKey implements KMMasterKey { + private AESKey aesKey; + + public KMAESKey(AESKey key) { + aesKey = key; + } + + public void setKey(byte[] keyData, short kOff) { + aesKey.setKey(keyData, kOff); + } + + public byte getKey(byte[] keyData, short kOff) { + return aesKey.getKey(keyData, kOff); + } + + public short getKeySizeBits() { + return aesKey.getSize(); + } + + public static void onSave(Element element, KMAESKey kmKey) { + element.write(kmKey.aesKey); + } + + public static KMAESKey onRestore(Element element) { + AESKey aesKey = (AESKey) element.readObject(); + KMAESKey kmKey = new KMAESKey(aesKey); + return kmKey; + } + + public static short getBackupPrimitiveByteCount() { + return (short) 0; + } + + public static short getBackupObjectCount() { + return (short) 1; + } +} diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index cd9567d3..b89b50ca 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -774,12 +774,6 @@ public KMAttestationCert buffer(byte[] buf, short bufStart, short maxLen) { return this; } - @Override - public KMAttestationCert signingKey(short privKey) { - signPriv = privKey; - return this; - } - @Override public short getCertStart() { return certStart; @@ -808,11 +802,10 @@ public void build() { tbsLength = (short) (tbsLength - tbsOffset); pushSequenceHeader((short) (last - stackPtr)); certStart = stackPtr; - short sigLen = KMJCardSimulator.getInstance() + KMJCardSimulator provider = KMJCardSimulator.getInstance(); + short sigLen = provider .ecSign256( - KMByteBlob.cast(signPriv).getBuffer(), - KMByteBlob.cast(signPriv).getStartOff(), - KMByteBlob.cast(signPriv).length(), + provider.getAttestationKey(), stack, tbsOffset, tbsLength, @@ -833,7 +826,7 @@ public void build() { public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff, byte[] creationTime, short timeOffset, short creationTimeLen, byte[] attestAppId, short appIdOff, short attestAppIdLen, - byte resetSinceIdRotation, byte[] key, short keyOff, short keyLen) { + byte resetSinceIdRotation, KMMasterKey masterKey) { // Concatenate T||C||R // temporal count T short temp = KMUtils.countTemporalCount(creationTime, timeOffset, @@ -851,8 +844,17 @@ public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff, scratchPad[scratchPadOff] = resetSinceIdRotation; scratchPadOff++; + //Get the key data from the master key + KMAESKey aesKey = (KMAESKey) masterKey; + short mKeyData = KMByteBlob.instance((short) (aesKey.getKeySizeBits() / 8)); + aesKey.getKey( + KMByteBlob.cast(mKeyData).getBuffer(), /* Key */ + KMByteBlob.cast(mKeyData).getStartOff()); /* Key start*/ timeOffset = KMByteBlob.instance((short) 32); - appIdOff = KMJCardSimulator.getInstance().hmacSign(key, keyOff, keyLen, + appIdOff = KMJCardSimulator.getInstance().hmacSign( + KMByteBlob.cast(mKeyData).getBuffer(), /* Key */ + KMByteBlob.cast(mKeyData).getStartOff(), /* Key start*/ + KMByteBlob.cast(mKeyData).length(), /* Key length*/ scratchPad, /* data */ temp, /* data start */ scratchPadOff, /* data length */ diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java new file mode 100644 index 00000000..65c069d1 --- /dev/null +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java @@ -0,0 +1,38 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +import javacard.security.ECPrivateKey; +import javacard.security.KeyPair; + +public class KMECPrivateKey implements KMAttestationKey { + + private 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 ECPrivateKey getPrivateKey() { + return (ECPrivateKey) ecKeyPair.getPrivate(); + } + +} diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMHmacKey.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMHmacKey.java new file mode 100644 index 00000000..8b75827a --- /dev/null +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMHmacKey.java @@ -0,0 +1,38 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +import javacard.security.HMACKey; + +public class KMHmacKey implements KMPreSharedKey { + private HMACKey hmacKey; + + public KMHmacKey(HMACKey key) { + hmacKey = key; + } + + public void setKey(byte[] keyData, short kOff, short length) { + hmacKey.setKey(keyData, kOff, length); + } + + public byte getKey(byte[] keyData, short kOff) { + return hmacKey.getKey(keyData, kOff); + } + + public short getKeySizeBits() { + return hmacKey.getSize(); + } +} diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 08c3d0ea..2c7001b2 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -84,6 +84,9 @@ public class KMJCardSimulator implements KMSEProvider { private static byte[] entropyPool; private static byte[] rndNum; private byte[] certificateChain; + private KMAESKey masterKey; + private KMECPrivateKey attestationKey; + private KMHmacKey preSharedKey; private static KMJCardSimulator jCardSimulator = null; @@ -320,6 +323,7 @@ public short aesGCMEncrypt( key.getKey(keyMaterial,(short)0); */ + //print("KeyMaterial Enc", keyMaterial); //print("Authdata Enc", authData, authDataStart, authDataLen); java.security.Key aesKey = new SecretKeySpec(keyBuf,keyStart,keyLen, "AES"); @@ -511,10 +515,16 @@ public HMACKey cmacKdf(byte[] keyMaterial, short keyMaterialStart, short keyMate } @Override - public short cmacKdf(byte[] keyMaterial, short keyMaterialStart, short keyMaterialLen, byte[] label, + public short cmacKdf(KMPreSharedKey pSharedKey, byte[] label, short labelStart, short labelLen, byte[] context, short contextStart, short contextLength, byte[] keyBuf, short keyStart) { - HMACKey key = cmacKdf(keyMaterial,keyMaterialStart, keyMaterialLen, label, labelStart, labelLen,context,contextStart,contextLength); - return key.getKey(keyBuf,keyStart); + KMHmacKey key = (KMHmacKey) pSharedKey; + short keyMaterialLen = key.getKeySizeBits(); + keyMaterialLen = (short) (keyMaterialLen / 8); + short keyMaterialStart = 0; + byte[] keyMaterial = new byte[keyMaterialLen]; + key.getKey(keyMaterial, keyMaterialStart); + HMACKey hmacKey = cmacKdf(keyMaterial,keyMaterialStart, keyMaterialLen, label, labelStart, labelLen,context,contextStart,contextLength); + return hmacKey.getKey(keyBuf,keyStart); } @@ -1213,13 +1223,11 @@ public short getCertificateChainLength() { } @Override - public short ecSign256(byte[] secret, short secretStart, short secretLength, + public short ecSign256(KMAttestationKey attestationKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, byte[] outputDataBuf, short outputDataStart) { - ECPrivateKey key = (ECPrivateKey) KeyBuilder.buildKey( - KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false); - key.setS(secret, secretStart, secretLength); + ECPrivateKey key = ((KMECPrivateKey)attestationKey).getPrivateKey(); Signature signer = Signature .getInstance(Signature.ALG_ECDSA_SHA_256, false); @@ -1272,36 +1280,115 @@ public boolean isDeviceRebooted() { @Override public void clearDeviceBooted(boolean resetBootFlag) { - // To be filled } @Override public void onSave(Element ele) { - // TODO Auto-generated method stub - } @Override public void onRestore(Element ele) { - // TODO Auto-generated method stub - } @Override public short getBackupPrimitiveByteCount() { - // TODO Auto-generated method stub return 0; } @Override public short getBackupObjectCount() { - // TODO Auto-generated method stub return 0; } @Override public boolean isUpgrading() { - // TODO Auto-generated method stub return false; } + + @Override + public KMMasterKey createMasterKey(short keySizeBits) { + if (masterKey == null) { + AESKey key = (AESKey) KeyBuilder.buildKey( + KeyBuilder.TYPE_AES, keySizeBits, false); + masterKey = new KMAESKey(key); + short keyLen = (short) (keySizeBits / 8); + byte[] keyData = new byte[keyLen]; + getTrueRandomNumber(keyData, (short) 0, keyLen); + masterKey.setKey(keyData, (short) 0); + } + return (KMMasterKey) masterKey; + } + + @Override + public KMAttestationKey createAttestationKey(byte[] keyData, short offset, + short length) { + if (attestationKey == null) { + // Strongbox supports only P-256 curve for EC key. + KeyPair ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); + attestationKey = new KMECPrivateKey(ecKeyPair); + } + attestationKey.setS(keyData, offset, length); + return (KMAttestationKey) attestationKey; + } + + @Override + public KMPreSharedKey createPresharedKey(byte[] keyData, short offset, short length) { + short lengthInBits = (short)(length * 8); + if ((lengthInBits % 8 != 0) || !(lengthInBits >= 64 && lengthInBits <= 512)) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + if (preSharedKey == null) { + HMACKey key = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, lengthInBits, + false); + preSharedKey = new KMHmacKey(key); + } + preSharedKey.setKey(keyData, offset, length); + return (KMPreSharedKey) preSharedKey; + } + + @Override + public KMMasterKey getMasterKey() { + return (KMMasterKey) masterKey; + } + + @Override + public KMAttestationKey getAttestationKey() { + return (KMAttestationKey) attestationKey; + } + + @Override + public KMPreSharedKey getPresharedKey() { + return (KMPreSharedKey) preSharedKey; + } + + @Override + public short aesGCMEncrypt(KMMasterKey masterKey, byte[] secret, short secretStart, + short secretLen, byte[] encSecret, short encSecretStart, byte[] nonce, + short nonceStart, short nonceLen, byte[] authData, + short authDataStart, short authDataLen, byte[] authTag, + short authTagStart, short authTagLen) { + KMAESKey aesKey = (KMAESKey) masterKey; + short keyLen = aesKey.getKeySizeBits(); + keyLen = (short) (keyLen / 8); + byte[] keyBuf = new byte[keyLen]; + aesKey.getKey(keyBuf, (short)0); + return aesGCMEncrypt( + keyBuf, + (short) 0, + keyLen, + secret, + secretStart, + secretLen, + encSecret, + encSecretStart, + nonce, + nonceStart, + nonceLen, + authData, + authDataStart, + authDataLen, + authTag, + authTagStart, + authTagLen); + } } diff --git a/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java index d27f015a..f3d36663 100644 --- a/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java +++ b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java @@ -44,15 +44,13 @@ public interface KMAttestationCert { * @param attestAppIdOff Start offset of the attestAppId buffer. * @param attestAppIdLen Length of the attestAppId buffer. * @param resetSinceIdRotation This holds the information of RESET_SINCE_ID_ROTATION. - * @param key This buffer contains the master secret. - * @param keyOff Start offset of the master key. - * @param keyLen Length of the master key. + * @param instance of the master key. * @return instance of KMAttestationCert. */ KMAttestationCert makeUniqueId(byte[] scratchpad, short scratchPadOff, byte[] creationTime, short creationTimeOff, short creationTimeLen, byte[] attestAppId, short attestAppIdOff, short attestAppIdLen, byte resetSinceIdRotation, - byte[] key, short keyOff, short keyLen); + KMMasterKey masterKey); /** * Set start time received from creation/activation time tag. Used for certificate's valid period. @@ -130,14 +128,6 @@ KMAttestationCert notAfter(short usageExpiryTimeObj, */ KMAttestationCert buffer(byte[] buf, short bufStart, short maxLen); - /** - * Set signing key to be used to sign the cert. - * - * @param privateKey This is ECPrivateKey with curve P-256. - * @return instance of KMAttestationCert - */ - KMAttestationCert signingKey(short privateKey); - /** * Get the start of the certificate * diff --git a/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java b/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java new file mode 100644 index 00000000..4b6213ee --- /dev/null +++ b/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java @@ -0,0 +1,28 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +/** + * KMAttestationKey is a marker interface and the SE Provider has to implement + * this interface. KMAttestationKey is stored as a Javacard KeyPair object instead + * of byte array. When the attestation key is stored as a KeyPair object, + * the Javacard OS internally provides appropriate security measures + * to protect the key. The attestation key is maintained by the + * SEProvider. + */ +public interface KMAttestationKey { + +} diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 1b156d53..4cf028e5 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -190,8 +190,7 @@ protected KMKeymasterApplet(KMSEProvider seImpl) { JCSystem.makeTransientShortArray((short) TMP_VARIABLE_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); if(!isUpgrading) { keymasterState = KMKeymasterApplet.INIT_STATE; - seProvider.getTrueRandomNumber(buf, (short) 0, KMRepository.MASTER_KEY_SIZE); - repository.initMasterKey(buf, (short)0, KMRepository.MASTER_KEY_SIZE); + seProvider.createMasterKey((short) (KMRepository.MASTER_KEY_SIZE * 8)); } KMType.initialize(); encoder = new KMEncoder(); @@ -752,7 +751,10 @@ private void processProvisionAttestationKey(APDU apdu) { importECKeys(scratchPad); // persist key - repository.persistAttestationKey(data[SECRET]); + seProvider.createAttestationKey( + KMByteBlob.cast(data[SECRET]).getBuffer(), + KMByteBlob.cast(data[SECRET]).getStartOff(), + KMByteBlob.cast(data[SECRET]).length()); } private void processProvisionAttestIdsCmd(APDU apdu) { @@ -795,7 +797,7 @@ private void processProvisionSharedSecretCmd(APDU apdu) { KMException.throwIt(KMError.INVALID_ARGUMENT); } // Persist shared Hmac. - repository.initHmacSharedSecretKey( + seProvider.createPresharedKey( KMByteBlob.cast(tmpVariables[0]).getBuffer(), KMByteBlob.cast(tmpVariables[0]).getStartOff(), KMByteBlob.cast(tmpVariables[0]).length()); @@ -1033,12 +1035,9 @@ private void processComputeSharedHmacCmd(APDU apdu) { } // generate the key and store it in scratch pad - 32 bytes - tmpVariables[8] = repository.getSharedKey(); tmpVariables[6] = seProvider.cmacKdf( - KMByteBlob.cast(tmpVariables[8]).getBuffer(), - KMByteBlob.cast(tmpVariables[8]).getStartOff(), - KMByteBlob.cast(tmpVariables[8]).length(), + seProvider.getPresharedKey(), ckdfLable, (short) 0, (short) ckdfLable.length, @@ -1397,7 +1396,7 @@ private void processAttestKeyCmd(APDU apdu) { // validity period // active time or creation time - byte blob - // TODO current assumption is that if active and creation time are missing from characteristics + // current assumption is that if active and creation time are missing from characteristics // then // then it is an error. tmpVariables[1] = @@ -1425,7 +1424,6 @@ private void processAttestKeyCmd(APDU apdu) { cert.deviceLocked(repository.getDeviceLock()); cert.issuer(repository.getIssuer()); cert.publicKey(data[PUB_KEY]); - cert.signingKey(repository.getAttKey()); cert.verifiedBootHash(repository.getVerifiedBootHash()); cert.verifiedBootKey(repository.getVerifiedBootKey()); @@ -1529,8 +1527,6 @@ private void setUniqueId(KMAttestationCert cert, byte[] scratchPad) { resetAfterRotation = 0x01; } - //master key. - tmpVariables[2] = repository.getMasterKeySecret(); cert.makeUniqueId( scratchPad, (short) 0, @@ -1540,9 +1536,7 @@ private void setUniqueId(KMAttestationCert cert, byte[] scratchPad) { KMByteBlob.cast(tmpVariables[1]).getBuffer(), KMByteBlob.cast(tmpVariables[1]).getStartOff(), KMByteBlob.cast(tmpVariables[1]).length(), resetAfterRotation, - KMByteBlob.cast(tmpVariables[2]).getBuffer(), - KMByteBlob.cast(tmpVariables[2]).getStartOff(), - KMByteBlob.cast(tmpVariables[2]).length()); + seProvider.getMasterKey()); } private void processDestroyAttIdsCmd(APDU apdu) { @@ -3893,7 +3887,7 @@ private static short deriveKey(byte[] scratchPad) { // 1. AesGCM Encryption, with below input parameters. // authData - HIDDEN_PARAMTERS // Key - Master Key - // InputData - AUTH_DATA + // InputData - KeyCharacteristics // IV - NONCE // 2. After encryption it generates two outputs // a. Encrypted output @@ -3903,13 +3897,10 @@ private static short deriveKey(byte[] scratchPad) { // Input data - Encrypted output (Generated in step 2). // 4. HMAC Sign generates an output of 32 bytes length. // Consume only first 16 bytes as derived key. - tmpVariables[4] = repository.getMasterKeySecret(); tmpVariables[5] = repository.alloc(AES_GCM_AUTH_TAG_LENGTH); tmpVariables[3] = seProvider.aesGCMEncrypt( - KMByteBlob.cast(tmpVariables[4]).getBuffer(), - KMByteBlob.cast(tmpVariables[4]).getStartOff(), - KMByteBlob.cast(tmpVariables[4]).length(), + seProvider.getMasterKey(), repository.getHeap(), data[AUTH_DATA], data[AUTH_DATA_LENGTH], diff --git a/Applet/src/com/android/javacard/keymaster/KMMasterKey.java b/Applet/src/com/android/javacard/keymaster/KMMasterKey.java new file mode 100644 index 00000000..0b7b1a6a --- /dev/null +++ b/Applet/src/com/android/javacard/keymaster/KMMasterKey.java @@ -0,0 +1,28 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +/** + * KMMasterKey is a marker interface and the SE Provider has to implement + * this interface. Masterkey is stored as a Javacard Key object instead + * of byte array. When master key is stored as a Key object, + * the Javacard OS internally provides appropriate security measures + * to protect the key. The master key is maintained by the + * SEProvider. + */ +public interface KMMasterKey { + +} diff --git a/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java b/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java new file mode 100644 index 00000000..7d02db4e --- /dev/null +++ b/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java @@ -0,0 +1,28 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.javacard.keymaster; + +/** + * KMPreSharedKey is a marker interface and the SE Provider has to implement + * this interface. KMPreSharedKey is stored as a Javacard Key object instead + * of byte array. When the shared key is stored as a Key object, + * the Javacard OS internally provides appropriate security measures + * to protect the key. The pre shared key is maintained by the + * SEProvider. + */ +public interface KMPreSharedKey { + +} diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 4c30a613..7785c5b6 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -29,7 +29,7 @@ */ public class KMRepository implements KMUpgradable { // Data table configuration - public static final short DATA_INDEX_SIZE = 24; + public static final short DATA_INDEX_SIZE = 21; public static final short DATA_INDEX_ENTRY_SIZE = 4; public static final short DATA_MEM_SIZE = 2048; public static final short HEAP_SIZE = 10000; @@ -42,10 +42,8 @@ public class KMRepository implements KMUpgradable { private static final short OPERATION_HANDLE_ENTRY_SIZE = OPERATION_HANDLE_SIZE + OPERATION_HANDLE_STATUS_SIZE; // Data table offsets - public static final byte MASTER_KEY = 8; - public static final byte SHARED_KEY = 9; - public static final byte COMPUTED_HMAC_KEY = 10; - public static final byte HMAC_NONCE = 11; + public static final byte COMPUTED_HMAC_KEY = 8; + public static final byte HMAC_NONCE = 9; public static final byte ATT_ID_BRAND = 0; public static final byte ATT_ID_DEVICE = 1; public static final byte ATT_ID_PRODUCT = 2; @@ -54,18 +52,17 @@ public class KMRepository implements KMUpgradable { public static final byte ATT_ID_MEID = 5; public static final byte ATT_ID_MANUFACTURER = 6; public static final byte ATT_ID_MODEL = 7; - public static final byte ATT_EC_KEY = 12; - public static final byte CERT_ISSUER = 13; - public static final byte CERT_EXPIRY_TIME = 14; - public static final byte BOOT_OS_VERSION = 15; - public static final byte BOOT_OS_PATCH = 16; - public static final byte VENDOR_PATCH_LEVEL = 17; - public static final byte BOOT_PATCH_LEVEL = 18; - public static final byte BOOT_VERIFIED_BOOT_KEY = 19; - public static final byte BOOT_VERIFIED_BOOT_HASH = 20; - public static final byte BOOT_VERIFIED_BOOT_STATE = 21; - public static final byte BOOT_DEVICE_LOCKED_STATUS = 22; - public static final byte BOOT_DEVICE_LOCKED_TIME = 23; + public static final byte CERT_ISSUER = 10; + public static final byte CERT_EXPIRY_TIME = 11; + public static final byte BOOT_OS_VERSION = 12; + public static final byte BOOT_OS_PATCH = 13; + public static final byte VENDOR_PATCH_LEVEL = 14; + public static final byte BOOT_PATCH_LEVEL = 15; + public static final byte BOOT_VERIFIED_BOOT_KEY = 16; + public static final byte BOOT_VERIFIED_BOOT_HASH = 17; + public static final byte BOOT_VERIFIED_BOOT_STATE = 18; + public static final byte BOOT_DEVICE_LOCKED_STATUS = 19; + public static final byte BOOT_DEVICE_LOCKED_TIME = 20; // Data Item sizes public static final short MASTER_KEY_SIZE = 16; @@ -249,16 +246,6 @@ public void releaseOperation(KMOperationState op) { } } - public void initMasterKey(byte[] key, short start, short len) { - if(len != MASTER_KEY_SIZE) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); - writeDataEntry(MASTER_KEY,key, start, len); - } - - public void initHmacSharedSecretKey(byte[] key, short start, short len) { - if(len != SHARED_SECRET_KEY_SIZE) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); - writeDataEntry(SHARED_KEY,key,start,len); - } - public void initComputedHmac(byte[] key, short start, short len) { if(len != COMPUTED_HMAC_KEY_SIZE) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); writeDataEntry(COMPUTED_HMAC_KEY,key,start,len); @@ -296,14 +283,9 @@ public void onSelect() { // If write through caching is implemented then this method will restore the data into cache } - public short getMasterKeySecret() { - return readData(MASTER_KEY); - } - // This function uses memory from the back of the heap(transient memory). Call // reclaimMemory function immediately after the use. public short allocReclaimableMemory(short length) { - // TODO Verify the below condition (HEAP_SIZE/2) if ((((short) (reclaimIndex - length)) <= heapIndex) || (length >= HEAP_SIZE / 2)) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); @@ -376,7 +358,6 @@ private void clearDataEntry(short id){ if (dataLen != 0) { short dataPtr = Util.getShort(dataTable,(short)(id+DATA_INDEX_ENTRY_OFFSET)); Util.arrayFillNonAtomic(dataTable, dataPtr,dataLen,(byte)0); - //Util.arrayFillNonAtomic(dataTable, id,DATA_INDEX_ENTRY_SIZE,(byte)0); } JCSystem.commitTransaction(); } @@ -422,10 +403,6 @@ public byte[] getHeap() { return heap; } - public short getSharedKey() { - return readData(SHARED_KEY); - } - public short getHmacNonce() { return readData(HMAC_NONCE); } @@ -434,17 +411,6 @@ public short getComputedHmacKey() { return readData(COMPUTED_HMAC_KEY); } - public void persistAttestationKey(short secret) { - writeDataEntry(ATT_EC_KEY, - KMByteBlob.cast(secret).getBuffer(), - KMByteBlob.cast(secret).getStartOff(), - KMByteBlob.cast(secret).length()); - } - - public short getAttKey() { - return readData(ATT_EC_KEY); - } - public void persistAttId(byte id, byte[] buf, short start, short len){ writeDataEntry(id, buf,start,len); } diff --git a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java index 3e981c9a..3b7edcf4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java +++ b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java @@ -159,6 +159,46 @@ short aesGCMEncrypt( short authTagStart, short authTagLen); + /** + * This function is used to derive a partial secret, which is used to encrypt the keyBlobs. + * This is a oneshot operation that performs encryption operation using AES GCM algorithm. It throws + * CryptoException if algorithm is not supported or if tag length is not equal to 16 or + * nonce length is not equal to 12. + * + * @param aesKey instance of KMMasterKey. + * @param data is the buffer that contains data to encrypt. + * @param dataStart is the start of the data buffer. + * @param dataLen is the length of the data buffer. + * @param encData is the buffer of the output encrypted data. + * @param encDataStart is the start of the encrypted data buffer. + * @param nonce is the buffer of nonce. + * @param nonceStart is the start of the nonce buffer. + * @param nonceLen is the length of the nonce buffer. + * @param authData is the authentication data buffer. + * @param authDataStart is the start of the authentication buffer. + * @param authDataLen is the length of the authentication buffer. + * @param authTag is the buffer to output authentication tag. + * @param authTagStart is the start of the buffer. + * @param authTagLen is the length of the buffer. + * @return length of the encrypted data. + */ + short aesGCMEncrypt( + KMMasterKey aesKey, + byte[] data, + short dataStart, + short dataLen, + byte[] encData, + short encDataStart, + byte[] nonce, + short nonceStart, + short nonceLen, + byte[] authData, + short authDataStart, + short authDataLen, + byte[] authTag, + short authTagStart, + short authTagLen); + /** * This is a oneshot operation that performs decryption operation using AES GCM algorithm. It throws * CryptoException if algorithm is not supported. @@ -205,9 +245,7 @@ boolean aesGCMDecrypt( * This is a oneshot operation that performs key derivation function using cmac kdf (CKDF) as * defined in android keymaster hal definition. * - * @param aesKey is the key to use for ckdf. - * @param aesKeyStart is the start of the aes key buffer. - * @param aesKeyLen is the length of the aes key buffer. + * @param instance of pre-shared key. * @param label is the label to be used for ckdf. * @param labelStart is the start of label. * @param labelLen is the length of the label. @@ -219,9 +257,7 @@ boolean aesGCMDecrypt( * @return length of the derived key buffer in bytes. */ short cmacKdf( - byte[] aesKey, - short aesKeyStart, - short aesKeyLen, + KMPreSharedKey hmacKey, byte[] label, short labelStart, short labelLen, @@ -313,9 +349,7 @@ short rsaDecipherOAEP256( /** * This is a oneshot operation that signs the data using EC private key. * - * @param secret is the private key of P-256 curve. - * @param secretStart is the start of the private key buffer. - * @param secretLength is the length of the private buffer in bytes. + * @param instance of KMAttestationKey. * @param inputDataBuf is the buffer of the input data. * @param inputDataStart is the start of the input data buffer. * @param inputDataLength is the length of the inpur data buffer in bytes. @@ -324,9 +358,7 @@ short rsaDecipherOAEP256( * @return length of the decrypted data. */ short ecSign256( - byte[] secret, - short secretStart, - short secretLength, + KMAttestationKey ecPrivKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, @@ -472,4 +504,62 @@ KMOperation initAsymmetricOperation( * @return true if upgrading, otherwise false. */ boolean isUpgrading(); + + /** + * This function generates an AES Key of keySizeBits, which is used as + * an master key. This generated key is maintained by the SEProvider. + * This function should be called only once at the time of installation. + * + * @param keySizeBits key size in bits. + * @return An instance of KMMasterKey. + */ + KMMasterKey createMasterKey(short keySizeBits); + + /** + * This function creates an ECKey and initializes the ECPrivateKey with + * the provided input key data. The initialized Key is maintained by the + * SEProvider. This function should be called only while provisioning the + * attestation key. + * + * @param keyData buffer containing the ec private key. + * @param offset start of the buffer. + * @param length length of the buffer. + * @return An instance of KMAttestationKey. + */ + KMAttestationKey createAttestationKey(byte[] keyData, short offset, short length); + + /** + * This function creates an HMACKey and initializes the key with the + * provided input key data. This created key is maintained by the + * SEProvider. This function should be called only while provisioing the + * pre-shared secret. + * + * @param keyData buffer containing the key data. + * @param offset start of the buffer. + * @param length length of the buffer. + * @return An instance of KMPreSharedKey. + */ + KMPreSharedKey createPresharedKey(byte[] keyData, short offset, short length); + + /** + * Returns the master key. + * + * @return Instance of the KMMasterKey + */ + KMMasterKey getMasterKey(); + + /** + * Returns the attestation key. + * + * @return Instance of the KMAttestationKey. + */ + KMAttestationKey getAttestationKey(); + + /** + * Returns the preshared key. + * + * @return Instance of the KMPreSharedKey. + */ + KMPreSharedKey getPresharedKey(); + } From 64e37fad5408f7cd7006133407f8b6c6a2bb775c Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sat, 6 Feb 2021 20:35:12 +0530 Subject: [PATCH 2/6] Updated the documentation comments --- .../com/android/javacard/keymaster/KMAttestationKey.java | 8 +++----- .../src/com/android/javacard/keymaster/KMMasterKey.java | 6 ++---- .../com/android/javacard/keymaster/KMPreSharedKey.java | 6 ++---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java b/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java index 4b6213ee..8582d2b2 100644 --- a/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java +++ b/Applet/src/com/android/javacard/keymaster/KMAttestationKey.java @@ -17,11 +17,9 @@ /** * KMAttestationKey is a marker interface and the SE Provider has to implement - * this interface. KMAttestationKey is stored as a Javacard KeyPair object instead - * of byte array. When the attestation key is stored as a KeyPair object, - * the Javacard OS internally provides appropriate security measures - * to protect the key. The attestation key is maintained by the - * SEProvider. + * this interface. Internally attestation key is stored as a Javacard EC + * key pair object, which will provide additional security. + * The attestation key is maintained by the SEProvider. */ public interface KMAttestationKey { diff --git a/Applet/src/com/android/javacard/keymaster/KMMasterKey.java b/Applet/src/com/android/javacard/keymaster/KMMasterKey.java index 0b7b1a6a..0ceb6291 100644 --- a/Applet/src/com/android/javacard/keymaster/KMMasterKey.java +++ b/Applet/src/com/android/javacard/keymaster/KMMasterKey.java @@ -17,10 +17,8 @@ /** * KMMasterKey is a marker interface and the SE Provider has to implement - * this interface. Masterkey is stored as a Javacard Key object instead - * of byte array. When master key is stored as a Key object, - * the Javacard OS internally provides appropriate security measures - * to protect the key. The master key is maintained by the + * this interface. Internally Masterkey is stored as a Javacard AES key object, + * which will provide additional security. The master key is maintained by the * SEProvider. */ public interface KMMasterKey { diff --git a/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java b/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java index 7d02db4e..71dfcae6 100644 --- a/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java +++ b/Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java @@ -17,10 +17,8 @@ /** * KMPreSharedKey is a marker interface and the SE Provider has to implement - * this interface. KMPreSharedKey is stored as a Javacard Key object instead - * of byte array. When the shared key is stored as a Key object, - * the Javacard OS internally provides appropriate security measures - * to protect the key. The pre shared key is maintained by the + * this interface. Internally Preshared key is stored as a Javacard HMac key object, + * which will provide additional security. The pre-shared key is maintained by the * SEProvider. */ public interface KMPreSharedKey { From 2699c29d3dd45425fa968cd1a9429b1a6f3ec618 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sat, 6 Feb 2021 20:44:06 +0530 Subject: [PATCH 3/6] Changed the key derivation alogorithm to hmac sign Root of trust now contains VerifiedBootKey, VerifiedBootKeyHash, bootState, deviceLocked state. --- .../keymaster/KMAndroidSEProvider.java | 28 +-- .../javacard/keymaster/KMJCardSimulator.java | 42 +--- .../javacard/keymaster/KMKeymasterApplet.java | 210 +++--------------- .../javacard/keymaster/KMRepository.java | 70 +++++- .../javacard/keymaster/KMSEProvider.java | 60 ++--- 5 files changed, 131 insertions(+), 279 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index d182ca02..b04cb362 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -751,6 +751,21 @@ public short hmacSign(byte[] keyBuf, short keyStart, short keyLength, return hmacSign(key, data, dataStart, dataLength, mac, macStart); } + @Override + public short hmacSign(KMMasterKey masterkey, byte[] data, short dataStart, + short dataLength, byte[] signature, short signatureStart) { + try { + AESKey aesKey = ((KMAESKey) masterkey).getKey(); + aesKey.getKey(tmpArray, (short) 0); + HMACKey key = createHMACKey(tmpArray, (short) 0, + (short) (aesKey.getSize() / 8)); + return hmacSign(key, data, dataStart, dataLength, signature, + signatureStart); + } finally { + clean(); + } + } + @Override public boolean hmacVerify(byte[] keyBuf, short keyStart, short keyLength, byte[] data, short dataStart, short dataLength, byte[] mac, @@ -1320,17 +1335,4 @@ public KMAttestationKey getAttestationKey() { public KMPreSharedKey getPresharedKey() { return (KMPreSharedKey) preSharedKey; } - - @Override - public short aesGCMEncrypt(KMMasterKey key, byte[] secret, short secretStart, - short secretLen, byte[] encSecret, short encSecretStart, - byte[] nonce, short nonceStart, short nonceLen, byte[] authData, - short authDataStart, short authDataLen, byte[] authTag, - short authTagStart, short authTagLen) { - - return aesGCMEncrypt(((KMAESKey) key).getKey(), secret, secretStart, - secretLen, encSecret, encSecretStart, nonce, nonceStart, nonceLen, - authData, authDataStart, authDataLen, authTag, authTagStart, - authTagLen); - } } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 2c7001b2..2ef4f873 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -539,6 +539,17 @@ public boolean hmacVerify(HMACKey key, byte[] data, short dataStart, short dataL return hmacSignature.verify(data, dataStart, dataLength, mac, macStart, macLength); } + @Override + public short hmacSignkdf(KMMasterKey masterkey, byte[] data, short dataStart, + short dataLength, byte[] signature, short signatureStart) { + KMAESKey aesKey = (KMAESKey) masterkey; + short keyLen = (short) (aesKey.getKeySizeBits() / 8); + byte[] keyData = new byte[keyLen]; + aesKey.getKey(keyData, (short) 0); + return hmacSign(keyData, (short) 0, keyLen, data, dataStart, dataLength, + signature, signatureStart); + } + @Override public short hmacSign(byte[] keyBuf, short keyStart, short keyLength, byte[] data, short dataStart, short dataLength, byte[] mac, short macStart) { HMACKey key = createHMACKey(keyBuf,keyStart,keyLength); @@ -1360,35 +1371,4 @@ public KMAttestationKey getAttestationKey() { public KMPreSharedKey getPresharedKey() { return (KMPreSharedKey) preSharedKey; } - - @Override - public short aesGCMEncrypt(KMMasterKey masterKey, byte[] secret, short secretStart, - short secretLen, byte[] encSecret, short encSecretStart, byte[] nonce, - short nonceStart, short nonceLen, byte[] authData, - short authDataStart, short authDataLen, byte[] authTag, - short authTagStart, short authTagLen) { - KMAESKey aesKey = (KMAESKey) masterKey; - short keyLen = aesKey.getKeySizeBits(); - keyLen = (short) (keyLen / 8); - byte[] keyBuf = new byte[keyLen]; - aesKey.getKey(keyBuf, (short)0); - return aesGCMEncrypt( - keyBuf, - (short) 0, - keyLen, - secret, - secretStart, - secretLen, - encSecret, - encSecretStart, - nonce, - nonceStart, - nonceLen, - authData, - authDataStart, - authDataLen, - authTag, - authTagStart, - authTagLen); - } } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index 4cf028e5..f7b34db5 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -39,6 +39,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private static final byte CLA_ISO7816_NO_SM_NO_CHAN = (byte) 0x80; private static final short KM_HAL_VERSION = (short) 0x4000; private static final short MAX_AUTH_DATA_SIZE = (short) 512; + private static final short DERIVE_KEY_INPUT_SIZE = (short) 256; // "Keymaster HMAC Verification" - used for HMAC key verification. public static final byte[] sharingCheck = { @@ -524,11 +525,8 @@ private void processDeviceLockedCmd(APDU apdu) { if (KMInteger.compare(verTime, lastDeviceLockedTime) > 0) { Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 8, (byte) 0); KMInteger.cast(verTime).getValue(scratchPad, (short) 0, (short) 8); - // repository.deviceLockedFlag = true; repository.setDeviceLock(true); - // repository.deviceUnlockPasswordOnly = (tmpVariables[1] == 0x01); repository.setDeviceLockPasswordOnly(tmpVariables[1] == 0x01); - // Util.arrayCopy(scratchPad,(short)0,repository.deviceLockedTimestamp,(short)0,(short)repository.deviceLockedTimestamp.length); repository.setDeviceLockTimestamp(scratchPad, (short) 0, (short) 8); } sendError(apdu, KMError.OK); @@ -549,7 +547,6 @@ public static void sendOutgoing(APDU apdu) { } // Send data apdu.setOutgoing(); - // short currentBlockSize = apdu.getOutBlockSize(); apdu.setOutgoingLength(bufferLength); apdu.sendBytesLong(buffer, bufferStartOffset, bufferLength); } @@ -917,7 +914,6 @@ private void processDeleteKeyCmd(APDU apdu) { // Receive the incoming request fully from the master. receiveIncoming(apdu); - // Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) apdu.getBuffer().length, (byte) 0); // Arguments short argsProto = KMArray.instance((short) 1); KMArray.cast(argsProto).add((short) 0, KMByteBlob.exp()); @@ -1421,7 +1417,7 @@ private void processAttestKeyCmd(APDU apdu) { addTags( KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getSoftwareEnforced(), false, cert); - cert.deviceLocked(repository.getDeviceLock()); + cert.deviceLocked(repository.getBootLoaderLock()); cert.issuer(repository.getIssuer()); cert.publicKey(data[PUB_KEY]); cert.verifiedBootHash(repository.getVerifiedBootHash()); @@ -1429,7 +1425,7 @@ private void processAttestKeyCmd(APDU apdu) { cert.verifiedBootKey(repository.getVerifiedBootKey()); cert.verifiedBootState(repository.getBootState()); // buffer for cert - we allocate 2KBytes buffer - // TODO make this buffer size configurable + // make this buffer size configurable tmpVariables[3] = KMByteBlob.instance(MAX_CERT_SIZE); buffer = KMByteBlob.cast(tmpVariables[3]).getBuffer(); bufferStartOffset = KMByteBlob.cast(tmpVariables[3]).getStartOff(); @@ -1465,24 +1461,6 @@ private void addAttestationIds(KMAttestationCert cert) { } index++; } - /* - if(repository.isAttIdSupported()){ - short attTag; - short blob; - byte index = 0; - while (index < repository.ATT_ID_TABLE_SIZE) { - if (repository.getAttIdLen(index) != 0) { - blob = KMByteBlob.instance( - repository.getAttIdBuffer(index), - repository.getAttIdOffset(index), - repository.getAttIdLen(index)); - attTag = KMByteTag.instance(repository.getAttIdTag(index), blob); - cert.extensionTag(attTag,true); - index++; - } - } - } - */ } private void addTags(short params, boolean hwEnforced, KMAttestationCert cert) { @@ -1631,10 +1609,6 @@ private void processFinishOperationCmd(APDU apdu) { private void finishEncryptOperation(KMOperationState op, byte[] scratchPad) { short len = KMByteBlob.cast(data[INPUT_DATA]).length(); switch (op.getAlgorithm()) { - // - // RSA Encryption is only supported for testing purpose - // TODO remove this later on if not required - // case KMType.RSA: // Output size is always 256 bytes data[OUTPUT_DATA] = KMByteBlob.instance((short) 256); @@ -1693,8 +1667,6 @@ private void finishEncryptOperation(KMOperationState op, byte[] scratchPad) { private void finishDecryptOperation(KMOperationState op, byte[] scratchPad) { short len = KMByteBlob.cast(data[INPUT_DATA]).length(); switch (op.getAlgorithm()) { - // Only supported for testing purpose - // TODO remove this later on case KMType.RSA: // Fill the scratch pad with zero Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); @@ -1907,7 +1879,6 @@ private void authorizeUpdateFinishOperation(KMOperationState op, byte[] scratchP if (KMInteger.compare(tmpVariables[0], tmpVariables[2]) < 0) { KMException.throwIt(KMError.KEY_USER_NOT_AUTHENTICATED); } - // TODO this is not needed op.setAuthTimeoutValidated(true); } else if (op.isAuthPerOperationReqd()) { // If Auth per operation is required tmpVariables[0] = KMHardwareAuthToken.cast(data[HW_TOKEN]).getChallenge(); @@ -1930,11 +1901,6 @@ private void authorizeDeviceUnlock(short hwToken) { ptr = KMHardwareAuthToken.cast(hwToken).getTimestamp(); // Check if the current auth time stamp is greater then device locked time stamp short ts = repository.getDeviceTimeStamp(); - /*if (KMInteger.compare(ptr, KMInteger.uint_64(repository.deviceLockedTimestamp, (short) 0)) - <= 0) { - KMException.throwIt(KMError.DEVICE_LOCKED); - } - */ if (KMInteger.compare(ptr, ts) <= 0) { KMException.throwIt(KMError.DEVICE_LOCKED); } @@ -1951,7 +1917,6 @@ private void authorizeDeviceUnlock(short hwToken) { // repository.deviceLockedFlag = false; repository.setDeviceLock(false); repository.clearDeviceLockTimeStamp(); - // Util.arrayFillNonAtomic(repository.deviceLockedTimestamp, (short) 0, (short) 8, (byte) 0); } } @@ -2006,16 +1971,6 @@ private void validateVerificationToken(short verToken, byte[] scratchPad) { // hmac the data ptr = KMVerificationToken.cast(verToken).getMac(); short key = repository.getComputedHmacKey(); - /*boolean verified = - seProvider.hmacVerify(repository.getComputedHmacKey(), - (short) 0, - (short) repository.getComputedHmacKey().length, - scratchPad, (short) 0, len, - KMByteBlob.cast(ptr).getBuffer(), - KMByteBlob.cast(ptr).getStartOff(), - KMByteBlob.cast(ptr).length()); - - */ boolean verified = seProvider.hmacVerify( KMByteBlob.cast(key).getBuffer(), @@ -2509,8 +2464,6 @@ private void authorizeAndBeginOperation(KMOperationState op, byte[] scratchPad) private void beginCipherOperation(KMOperationState op) { switch (op.getAlgorithm()) { - // Not required to be supported - supported for testing purpose - // TODO remove this later case KMType.RSA: try { if (op.getPurpose() == KMType.DECRYPT) { @@ -2550,7 +2503,6 @@ private void beginCipherOperation(KMOperationState op) { op.setAesGcmUpdateStart(); } try { - // if (data[IV] != KMType.INVALID_VALUE) { op.setOperation( seProvider.initSymmetricOperation( (byte) op.getPurpose(), @@ -2769,15 +2721,6 @@ private boolean validateHwToken(short hwToken, byte[] scratchPad) { // hmac the data ptr = KMHardwareAuthToken.cast(hwToken).getMac(); short key = repository.getComputedHmacKey(); - /*return seProvider.hmacVerify( - repository.getComputedHmacKey(), - (short) 0, - (short) repository.getComputedHmacKey().length, - scratchPad, (short) 0, len, - KMByteBlob.cast(ptr).getBuffer(), - KMByteBlob.cast(ptr).getStartOff(), - KMByteBlob.cast(ptr).length()); - */ return seProvider.hmacVerify( KMByteBlob.cast(key).getBuffer(), KMByteBlob.cast(key).getStartOff(), @@ -3219,7 +3162,6 @@ private void processSetBootParamsCmd(APDU apdu) { KMArray.cast(argsProto).add((short) 6, tmpVariables[6]); KMArray.cast(argsProto).add((short) 7, tmpVariables[7]); // Decode the arguments - // System.out.println("Process boot params buffer: "+byteArrayToHexString(buffer)); short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); //reclaim memory repository.reclaimMemory(bufferLength); @@ -3280,7 +3222,7 @@ private void processSetBootParamsCmd(APDU apdu) { repository.setBootState(enumVal); enumVal = KMEnum.cast(tmpVariables[7]).getVal(); - repository.setDeviceLock(enumVal == KMType.DEVICE_LOCKED_TRUE); + repository.setBootloaderLocked(enumVal == KMType.DEVICE_LOCKED_TRUE); // Clear the Computed SharedHmac and Hmac nonce from persistent memory. repository.clearComputedHmac(); @@ -3422,7 +3364,6 @@ private static void generateRSAKey(byte[] scratchPad) { // Validate RSA Key validateRSAKey(scratchPad); // Now generate 2048 bit RSA keypair for the given exponent - // KeyPair rsaKey = seProvider.createRsaKeyPair(); short[] lengths = tmpVariables; data[PUB_KEY] = KMByteBlob.instance((short) 256); data[SECRET] = KMByteBlob.instance((short) 256); @@ -3480,8 +3421,6 @@ private static void generateAESKey(byte[] scratchPad) { validateAESKey(); tmpVariables[0] = KMIntegerTag.getShortValue(KMType.UINT_TAG, KMType.KEYSIZE, data[KEY_PARAMETERS]); - // AESKey aesKey = seProvider.createAESKey(tmpVariables[0]); - // tmpVariables[0] = aesKey.getKey(scratchPad, (short) 0); tmpVariables[0] = seProvider.createSymmetricKey(KMType.AES, tmpVariables[0], scratchPad, (short) 0); data[SECRET] = KMByteBlob.instance(scratchPad, (short) 0, tmpVariables[0]); @@ -3504,7 +3443,6 @@ private static void validateECKeys() { private static void generateECKeys(byte[] scratchPad) { validateECKeys(); - // KeyPair ecKey = seProvider.createECKeyPair(); short[] lengths = tmpVariables; seProvider.createAsymmetricKey( KMType.EC, @@ -3515,9 +3453,7 @@ private static void generateECKeys(byte[] scratchPad) { (short) 128, (short) 128, lengths); - // tmpVariables[5] = ((ECPublicKey) ecKey.getPublic()).getW(scratchPad, (short) 0); data[PUB_KEY] = KMByteBlob.instance(scratchPad, (short) 128, lengths[1]); - // tmpVariables[5] = ((ECPrivateKey) ecKey.getPrivate()).getS(scratchPad, (short) 0); data[SECRET] = KMByteBlob.instance(scratchPad, (short) 0, lengths[0]); data[KEY_BLOB] = KMArray.instance((short) 5); KMArray.cast(data[KEY_BLOB]).add(KEY_BLOB_PUB_KEY, data[PUB_KEY]); @@ -3543,8 +3479,6 @@ private static void validateTDESKey() { private static void generateTDESKey(byte[] scratchPad) { validateTDESKey(); - // DESKey desKey = seProvider.createTDESKey(); - // tmpVariables[0] = desKey.getKey(scratchPad, (short) 0); tmpVariables[0] = seProvider.createSymmetricKey(KMType.DES, (short) 168, scratchPad, (short) 0); data[SECRET] = KMByteBlob.instance(scratchPad, (short) 0, tmpVariables[0]); data[KEY_BLOB] = KMArray.instance((short) 4); @@ -3590,8 +3524,6 @@ private static void generateHmacKey(byte[] scratchPad) { tmpVariables[0] = KMIntegerTag.getShortValue(KMType.UINT_TAG, KMType.KEYSIZE, data[KEY_PARAMETERS]); // generate HMAC Key - // HMACKey hmacKey = seProvider.createHMACKey(tmpVariables[1]); - // tmpVariables[0] = hmacKey.getKey(scratchPad, (short) 0); tmpVariables[0] = seProvider.createSymmetricKey(KMType.HMAC, tmpVariables[0], scratchPad, (short) 0); data[SECRET] = KMByteBlob.instance(scratchPad, (short) 0, tmpVariables[0]); @@ -3618,20 +3550,6 @@ private void checkVersionAndPatchLevel(byte[] scratchPad) { KMException.throwIt(KMError.KEY_REQUIRES_UPGRADE); } } - /* - if ((tmpVariables[0] != KMType.INVALID_VALUE) - && (Util.arrayCompare( - repository.osVersion, (short) 0, scratchPad, (short) 0, tmpVariables[0]) - != 0)) { - if (Util.arrayCompare(repository.osVersion, (short) 0, scratchPad, (short) 0, tmpVariables[0]) - == -1) { - // If the key characteristics has os version > current os version - KMException.throwIt(KMError.INVALID_KEY_BLOB); - } else { - KMException.throwIt(KMError.KEY_REQUIRES_UPGRADE); - } - } - */ tmpVariables[0] = KMIntegerTag.getValue( scratchPad, (short) 0, KMType.UINT_TAG, KMType.OS_PATCH_LEVEL, data[HW_PARAMETERS]); @@ -3650,18 +3568,6 @@ private void checkVersionAndPatchLevel(byte[] scratchPad) { KMException.throwIt(KMError.KEY_REQUIRES_UPGRADE); } } - /*if ((tmpVariables[0] != KMType.INVALID_VALUE) - && (Util.arrayCompare(repository.osPatch, (short) 0, scratchPad, (short) 0, tmpVariables[0]) - != 0)) { - if (Util.arrayCompare(repository.osPatch, (short) 0, scratchPad, (short) 0, tmpVariables[0]) - == -1) { - // If the key characteristics has os patch level > current os patch - KMException.throwIt(KMError.INVALID_KEY_BLOB); - } else { - KMException.throwIt(KMError.KEY_REQUIRES_UPGRADE); - } - } - */ } private static void makeKeyCharacteristics(byte[] scratchPad) { @@ -3688,7 +3594,7 @@ private static void createEncryptedKeyBlob(byte[] scratchPad) { // make key characteristics - returns key characteristics in data[KEY_CHARACTERISTICS] makeKeyCharacteristics(scratchPad); // make root of trust blob - data[ROT] = repository.getVerifiedBootKey(); + data[ROT] = repository.readROT(); // make hidden key params list data[HIDDEN_PARAMETERS] = @@ -3747,11 +3653,7 @@ private static void parseEncryptedKeyBlob(byte[] scratchPad) { KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getHardwareEnforced(); data[SW_PARAMETERS] = KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getSoftwareEnforced(); - // make root of trust blob - // data[ROT] = - // KMByteBlob.instance( - // repository.verifiedBootKey, (short) 0, (short) repository.verifiedBootKey.length); - data[ROT] = repository.getVerifiedBootKey(); + data[ROT] = repository.readROT(); data[HIDDEN_PARAMETERS] = KMKeyParameters.makeHidden(data[APP_ID], data[APP_DATA], data[ROT], scratchPad); @@ -3880,59 +3782,37 @@ private static short addPtrToAAD(short dataArrPtr, byte[] aadBuf, short offset) private static short deriveKey(byte[] scratchPad) { tmpVariables[0] = KMKeyParameters.cast(data[HIDDEN_PARAMETERS]).getVals(); - tmpVariables[1] = repository.alloc((short) 256); + tmpVariables[1] = repository.alloc(DERIVE_KEY_INPUT_SIZE); // generate derivation material from hidden parameters tmpVariables[2] = encoder.encode(tmpVariables[0], repository.getHeap(), tmpVariables[1]); + if (DERIVE_KEY_INPUT_SIZE > tmpVariables[2]) { + // Copy KeyCharacteristics in the remaining space of DERIVE_KEY_INPUT_SIZE + Util.arrayCopyNonAtomic(repository.getHeap(), (short) (data[AUTH_DATA]), + repository.getHeap(), + (short) (tmpVariables[1] + tmpVariables[2]), + (short) (DERIVE_KEY_INPUT_SIZE - tmpVariables[2])); + } // KeyDerivation: - // 1. AesGCM Encryption, with below input parameters. - // authData - HIDDEN_PARAMTERS - // Key - Master Key - // InputData - KeyCharacteristics - // IV - NONCE - // 2. After encryption it generates two outputs - // a. Encrypted output - // b. Auth Tag - // 3. Do HMAC Sign, with below input parameters. - // Key - Auth Tag (Generated in step 2). - // Input data - Encrypted output (Generated in step 2). - // 4. HMAC Sign generates an output of 32 bytes length. + // 1. Do HMAC Sign, with below input parameters. + // Key - 128 bit master key + // Input data - HIDDEN_PARAMETERS + KeyCharacateristics + // - Truncate beyond 256 bytes. + // 2. HMAC Sign generates an output of 32 bytes length. // Consume only first 16 bytes as derived key. - tmpVariables[5] = repository.alloc(AES_GCM_AUTH_TAG_LENGTH); - tmpVariables[3] = - seProvider.aesGCMEncrypt( - seProvider.getMasterKey(), - repository.getHeap(), - data[AUTH_DATA], - data[AUTH_DATA_LENGTH], - scratchPad, - (short) 0, - KMByteBlob.cast(data[NONCE]).getBuffer(), - KMByteBlob.cast(data[NONCE]).getStartOff(), - KMByteBlob.cast(data[NONCE]).length(), - repository.getHeap(), - tmpVariables[1], - tmpVariables[2], - repository.getHeap(), - tmpVariables[5], - AES_GCM_AUTH_TAG_LENGTH); // Hmac sign. - tmpVariables[3] = seProvider.hmacSign( + tmpVariables[3] = seProvider.hmacSignkdf( + seProvider.getMasterKey(), repository.getHeap(), - tmpVariables[5], - AES_GCM_AUTH_TAG_LENGTH, + tmpVariables[1], + DERIVE_KEY_INPUT_SIZE, scratchPad, - (short) 0, - tmpVariables[3], - repository.getHeap(), - tmpVariables[1]); + (short) 0); if (tmpVariables[3] < 16) { KMException.throwIt(KMError.UNKNOWN_ERROR); } tmpVariables[3] = 16; - Util.arrayCopyNonAtomic(repository.getHeap(), tmpVariables[1], scratchPad, - (short) 0, tmpVariables[3]); // store the derived secret in data dictionary - data[DERIVED_KEY] = repository.alloc(tmpVariables[3]); + data[DERIVED_KEY] = tmpVariables[1]; Util.arrayCopyNonAtomic( scratchPad, (short) 0, repository.getHeap(), data[DERIVED_KEY], tmpVariables[3]); return tmpVariables[3]; @@ -3977,44 +3857,4 @@ private void add(byte[] buf, short op1, short op2, short result) { index--; } } -/* - @Override - public void onCleanup() { - } - - @Override - public void onConsolidate() { - } - - @Override - public void onRestore(Element element) { - element.initRead(); - provisionStatus = element.readByte(); - keymasterState = element.readByte(); - repository.onRestore(element); - seProvider.onRestore(element); - } - - @Override - public Element onSave() { - // SEProvider count - short primitiveCount = seProvider.getBackupPrimitiveByteCount(); - short objectCount = seProvider.getBackupObjectCount(); - //Repository count - primitiveCount += repository.getBackupPrimitiveByteCount(); - objectCount += repository.getBackupObjectCount(); - //KMKeymasterApplet count - primitiveCount += computePrimitveDataSize(); - objectCount += computeObjectCount(); - - // Create element. - Element element = UpgradeManager.createElement(Element.TYPE_SIMPLE, - primitiveCount, objectCount); - element.write(provisionStatus); - element.write(keymasterState); - repository.onSave(element); - seProvider.onSave(element); - return element; - } -*/ } diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 7785c5b6..ee7cc6a8 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -29,7 +29,7 @@ */ public class KMRepository implements KMUpgradable { // Data table configuration - public static final short DATA_INDEX_SIZE = 21; + public static final short DATA_INDEX_SIZE = 22; public static final short DATA_INDEX_ENTRY_SIZE = 4; public static final short DATA_MEM_SIZE = 2048; public static final short HEAP_SIZE = 10000; @@ -62,7 +62,8 @@ public class KMRepository implements KMUpgradable { public static final byte BOOT_VERIFIED_BOOT_HASH = 17; public static final byte BOOT_VERIFIED_BOOT_STATE = 18; public static final byte BOOT_DEVICE_LOCKED_STATUS = 19; - public static final byte BOOT_DEVICE_LOCKED_TIME = 20; + public static final byte DEVICE_LOCKED_TIME = 20; + public static final byte DEVICE_LOCKED = 21; // Data Item sizes public static final short MASTER_KEY_SIZE = 16; @@ -111,6 +112,11 @@ public KMRepository(boolean isUpgrading) { new Object[KMOperationState.MAX_REFS]}}; index++; } + //Initialize the device locked status + if (!isUpgrading) { + setDeviceLock(false); + setDeviceLockPasswordOnly(false); + } repository = this; } @@ -165,7 +171,6 @@ public KMOperationState reserveOperation(short opHandle){ return null; } - //TODO refactor following method public void persistOperation(byte[] data, short opHandle, KMOperation op) { short index = 0; byte[] opId; @@ -496,6 +501,39 @@ public short getOsPatch(){ } } + public short readROT() { + short length = dataLength(BOOT_VERIFIED_BOOT_KEY); + length += dataLength(BOOT_VERIFIED_BOOT_HASH); + length += dataLength(BOOT_VERIFIED_BOOT_STATE); + length += dataLength(BOOT_DEVICE_LOCKED_STATUS); + short blob = KMByteBlob.instance(length); + if((length = readDataEntry( + BOOT_VERIFIED_BOOT_KEY, + KMByteBlob.cast(blob).getBuffer(), + KMByteBlob.cast(blob).getStartOff())) == 0){ + return 0; + } + if((length += readDataEntry( + BOOT_VERIFIED_BOOT_HASH, + KMByteBlob.cast(blob).getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length))) == 0){ + return 0; + } + if((length += readDataEntry( + BOOT_VERIFIED_BOOT_STATE, + KMByteBlob.cast(blob).getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length))) == 0){ + return 0; + } + if((length += readDataEntry( + BOOT_DEVICE_LOCKED_STATUS, + KMByteBlob.cast(blob).getBuffer(), + (short) (KMByteBlob.cast(blob).getStartOff() + length))) == 0){ + return 0; + } + return blob; + } + public short getVerifiedBootKey(){ return readData(BOOT_VERIFIED_BOOT_KEY); } @@ -504,7 +542,7 @@ public short getVerifiedBootHash(){ return readData(BOOT_VERIFIED_BOOT_HASH); } - public boolean getDeviceLock(){ + public boolean getBootLoaderLock() { short blob = readData(BOOT_DEVICE_LOCKED_STATUS); return (byte)((getHeap())[KMByteBlob.cast(blob).getStartOff()] & 0xFE) != 0; } @@ -514,13 +552,18 @@ public byte getBootState(){ return (getHeap())[KMByteBlob.cast(blob).getStartOff()]; } + public boolean getDeviceLock(){ + short blob = readData(DEVICE_LOCKED); + return (byte)((getHeap())[KMByteBlob.cast(blob).getStartOff()] & 0xFE) != 0; + } + public boolean getDeviceLockPasswordOnly(){ - short blob = readData(BOOT_DEVICE_LOCKED_STATUS); + short blob = readData(DEVICE_LOCKED); return (byte)((getHeap())[KMByteBlob.cast(blob).getStartOff()] & 0xFD) != 0; } public short getDeviceTimeStamp(){ - short blob = readData(BOOT_DEVICE_LOCKED_TIME); + short blob = readData(DEVICE_LOCKED_TIME); if(blob != 0){ return KMInteger.uint_64(KMByteBlob.cast(blob).getBuffer(), KMByteBlob.cast(blob).getStartOff()); @@ -546,27 +589,34 @@ public void setBootPatchLevel(byte[] buf, short start, short len) { writeDataEntry(BOOT_PATCH_LEVEL, buf, start, len); } - public void setDeviceLock(boolean flag){ + public void setBootloaderLocked(boolean flag) { short start = alloc(DEVICE_LOCK_FLAG_SIZE); if(flag) (getHeap())[start] = (byte)((getHeap())[start] | 0x01); else (getHeap())[start] = (byte)((getHeap())[start] & 0xFE); writeDataEntry(BOOT_DEVICE_LOCKED_STATUS,getHeap(),start,DEVICE_LOCK_FLAG_SIZE); } + public void setDeviceLock(boolean flag){ + short start = alloc(DEVICE_LOCK_FLAG_SIZE); + if(flag) (getHeap())[start] = (byte)((getHeap())[start] | 0x01); + else (getHeap())[start] = (byte)((getHeap())[start] & 0xFE); + writeDataEntry(DEVICE_LOCKED,getHeap(),start,DEVICE_LOCK_FLAG_SIZE); + } + public void setDeviceLockPasswordOnly(boolean flag){ short start = alloc(DEVICE_LOCK_FLAG_SIZE); if(flag) (getHeap())[start] = (byte)((getHeap())[start] | 0x02); else (getHeap())[start] = (byte)((getHeap())[start] & 0xFD); - writeDataEntry(BOOT_DEVICE_LOCKED_STATUS,getHeap(),start,DEVICE_LOCK_FLAG_SIZE); + writeDataEntry(DEVICE_LOCKED,getHeap(),start,DEVICE_LOCK_FLAG_SIZE); } public void setDeviceLockTimestamp(byte[] buf, short start, short len){ if(len != DEVICE_LOCK_TS_SIZE) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); - writeDataEntry(BOOT_DEVICE_LOCKED_TIME, buf, start,len); + writeDataEntry(DEVICE_LOCKED_TIME, buf, start,len); } public void clearDeviceLockTimeStamp(){ - clearDataEntry(BOOT_DEVICE_LOCKED_TIME); + clearDataEntry(DEVICE_LOCKED_TIME); } public void setOsPatch(byte[] buf, short start, short len){ diff --git a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java index 3b7edcf4..022eb6cd 100644 --- a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java +++ b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java @@ -159,46 +159,6 @@ short aesGCMEncrypt( short authTagStart, short authTagLen); - /** - * This function is used to derive a partial secret, which is used to encrypt the keyBlobs. - * This is a oneshot operation that performs encryption operation using AES GCM algorithm. It throws - * CryptoException if algorithm is not supported or if tag length is not equal to 16 or - * nonce length is not equal to 12. - * - * @param aesKey instance of KMMasterKey. - * @param data is the buffer that contains data to encrypt. - * @param dataStart is the start of the data buffer. - * @param dataLen is the length of the data buffer. - * @param encData is the buffer of the output encrypted data. - * @param encDataStart is the start of the encrypted data buffer. - * @param nonce is the buffer of nonce. - * @param nonceStart is the start of the nonce buffer. - * @param nonceLen is the length of the nonce buffer. - * @param authData is the authentication data buffer. - * @param authDataStart is the start of the authentication buffer. - * @param authDataLen is the length of the authentication buffer. - * @param authTag is the buffer to output authentication tag. - * @param authTagStart is the start of the buffer. - * @param authTagLen is the length of the buffer. - * @return length of the encrypted data. - */ - short aesGCMEncrypt( - KMMasterKey aesKey, - byte[] data, - short dataStart, - short dataLen, - byte[] encData, - short encDataStart, - byte[] nonce, - short nonceStart, - short nonceLen, - byte[] authData, - short authDataStart, - short authDataLen, - byte[] authTag, - short authTagStart, - short authTagLen); - /** * This is a oneshot operation that performs decryption operation using AES GCM algorithm. It throws * CryptoException if algorithm is not supported. @@ -290,6 +250,26 @@ short hmacSign( byte[] signature, short signatureStart); + /** + * This is a oneshot operation that signs the data using hmac algorithm. + * This is used to derive the key, which is used to encrypt the keyblob. + * + * @param instance of masterkey. + * @param data is the buffer containing data to be signed. + * @param dataStart is the start of the data. + * @param dataLength is the length of the data. + * @param signature is the output signature buffer + * @param signatureStart is the start of the signature + * @return length of the signature buffer in bytes. + */ + short hmacSignkdf( + KMMasterKey masterkey, + byte[] data, + short dataStart, + short dataLength, + byte[] signature, + short signatureStart); + /** * This is a oneshot operation that verifies the signature using hmac algorithm. * From b27520b051bb17ad47c3a6b1be61c99b06115057 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 7 Feb 2021 16:58:48 +0530 Subject: [PATCH 4/6] 1. Removed unused functions in KMAESKey.java 2. Renamed the KMSEProvider function names of hmacSign and cmacKdf --- .../keymaster/KMAndroidSEProvider.java | 4 ++-- .../android/javacard/keymaster/KMAESKey.java | 20 ------------------- .../javacard/keymaster/KMJCardSimulator.java | 4 ++-- .../javacard/keymaster/KMKeymasterApplet.java | 4 ++-- .../javacard/keymaster/KMSEProvider.java | 19 ++++++++++++++++-- 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index b04cb362..6a5a0671 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -752,7 +752,7 @@ public short hmacSign(byte[] keyBuf, short keyStart, short keyLength, } @Override - public short hmacSign(KMMasterKey masterkey, byte[] data, short dataStart, + public short hmacKDF(KMMasterKey masterkey, byte[] data, short dataStart, short dataLength, byte[] signature, short signatureStart) { try { AESKey aesKey = ((KMAESKey) masterkey).getKey(); @@ -1169,7 +1169,7 @@ public KMAttestationCert getAttestationCert(boolean rsaCert) { } @Override - public short cmacKdf(KMPreSharedKey pSharedKey, byte[] label, + public short cmacKDF(KMPreSharedKey pSharedKey, byte[] label, short labelStart, short labelLen, byte[] context, short contextStart, short contextLength, byte[] keyBuf, short keyStart) { HMACKey key = cmacKdf(pSharedKey, label, labelStart, labelLen, context, diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java index c16a8188..489d4f77 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java @@ -15,8 +15,6 @@ */ package com.android.javacard.keymaster; -import org.globalplatform.upgrade.Element; - import javacard.security.AESKey; public class KMAESKey implements KMMasterKey { @@ -37,22 +35,4 @@ public byte getKey(byte[] keyData, short kOff) { public short getKeySizeBits() { return aesKey.getSize(); } - - public static void onSave(Element element, KMAESKey kmKey) { - element.write(kmKey.aesKey); - } - - public static KMAESKey onRestore(Element element) { - AESKey aesKey = (AESKey) element.readObject(); - KMAESKey kmKey = new KMAESKey(aesKey); - return kmKey; - } - - public static short getBackupPrimitiveByteCount() { - return (short) 0; - } - - public static short getBackupObjectCount() { - return (short) 1; - } } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 2ef4f873..6b0596ae 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -515,7 +515,7 @@ public HMACKey cmacKdf(byte[] keyMaterial, short keyMaterialStart, short keyMate } @Override - public short cmacKdf(KMPreSharedKey pSharedKey, byte[] label, + public short cmacKDF(KMPreSharedKey pSharedKey, byte[] label, short labelStart, short labelLen, byte[] context, short contextStart, short contextLength, byte[] keyBuf, short keyStart) { KMHmacKey key = (KMHmacKey) pSharedKey; short keyMaterialLen = key.getKeySizeBits(); @@ -540,7 +540,7 @@ public boolean hmacVerify(HMACKey key, byte[] data, short dataStart, short dataL } @Override - public short hmacSignkdf(KMMasterKey masterkey, byte[] data, short dataStart, + public short hmacKDF(KMMasterKey masterkey, byte[] data, short dataStart, short dataLength, byte[] signature, short signatureStart) { KMAESKey aesKey = (KMAESKey) masterkey; short keyLen = (short) (aesKey.getKeySizeBits() / 8); diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index f7b34db5..b30e63c2 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -1032,7 +1032,7 @@ private void processComputeSharedHmacCmd(APDU apdu) { // generate the key and store it in scratch pad - 32 bytes tmpVariables[6] = - seProvider.cmacKdf( + seProvider.cmacKDF( seProvider.getPresharedKey(), ckdfLable, (short) 0, @@ -3800,7 +3800,7 @@ private static short deriveKey(byte[] scratchPad) { // 2. HMAC Sign generates an output of 32 bytes length. // Consume only first 16 bytes as derived key. // Hmac sign. - tmpVariables[3] = seProvider.hmacSignkdf( + tmpVariables[3] = seProvider.hmacKDF( seProvider.getMasterKey(), repository.getHeap(), tmpVariables[1], diff --git a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java index 022eb6cd..a057eb9e 100644 --- a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java +++ b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import org.globalplatform.upgrade.Element; @@ -216,7 +231,7 @@ boolean aesGCMDecrypt( * @param keyStart is the start of the output buffer. * @return length of the derived key buffer in bytes. */ - short cmacKdf( + short cmacKDF( KMPreSharedKey hmacKey, byte[] label, short labelStart, @@ -262,7 +277,7 @@ short hmacSign( * @param signatureStart is the start of the signature * @return length of the signature buffer in bytes. */ - short hmacSignkdf( + short hmacKDF( KMMasterKey masterkey, byte[] data, short dataStart, From cc53a65798b7bf942865775c2a2f3c4a6d523be1 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 7 Feb 2021 21:24:45 +0530 Subject: [PATCH 5/6] Added Copyright comment --- .../com/android/javacard/keymaster/KMAESKey.java | 15 +++++++++++++++ .../javacard/keymaster/KMAndroidSEApplet.java | 15 +++++++++++++++ .../javacard/keymaster/KMAttestationCertImpl.java | 15 +++++++++++++++ .../keymaster/KMEcdsa256NoDigestSignature.java | 15 +++++++++++++++ .../android/javacard/keymaster/KMInstance.java | 15 +++++++++++++++ .../javacard/keymaster/KMOperationImpl.java | 15 +++++++++++++++ .../keymaster/KMRsa2048NoDigestSignature.java | 15 +++++++++++++++ .../javacard/keymaster/KMRsaOAEPEncoding.java | 15 +++++++++++++++ .../com/android/javacard/keymaster/KMUtils.java | 15 +++++++++++++++ .../javacard/keymaster/KMAttestationCertImpl.java | 15 +++++++++++++++ .../com/android/javacard/keymaster/KMCipher.java | 15 +++++++++++++++ .../android/javacard/keymaster/KMCipherImpl.java | 15 +++++++++++++++ .../keymaster/KMEcdsa256NoDigestSignature.java | 15 +++++++++++++++ .../javacard/keymaster/KMJCardSimApplet.java | 15 +++++++++++++++ .../javacard/keymaster/KMOperationImpl.java | 15 +++++++++++++++ .../keymaster/KMRsa2048NoDigestSignature.java | 15 +++++++++++++++ .../com/android/javacard/keymaster/KMUtils.java | 15 +++++++++++++++ .../javacard/keymaster/KMAttestationCert.java | 15 +++++++++++++++ .../com/android/javacard/keymaster/KMError.java | 15 +++++++++++++++ .../android/javacard/keymaster/KMOperation.java | 15 +++++++++++++++ .../android/javacard/keymaster/KMUpgradable.java | 15 +++++++++++++++ 21 files changed, 315 insertions(+) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java index 95896b13..afdfb08e 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import org.globalplatform.upgrade.Element; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 99dd47ce..bb6a2e86 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import org.globalplatform.upgrade.Element; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index bf6ae9b7..6025feef 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import com.android.javacard.keymaster.KMAESKey; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java index 727641c0..3f11a3b1 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.security.CryptoException; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMInstance.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMInstance.java index 3bf35e97..12655bc4 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMInstance.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMInstance.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; public class KMInstance { diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index 1c7ab32d..a38ee518 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.JCSystem; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java index 71c36a3d..991072e2 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.Util; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java index b8c7b30e..066d828f 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.JCSystem; diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java index cb8df259..7b4352f8 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.Util; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index b89b50ca..5be20599 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.JCSystem; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java index 145fea9d..017a8398 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; public abstract class KMCipher { diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java index 264b74e5..7a1df761 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.Util; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java index 242499ed..42468363 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import java.math.BigInteger; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java index e1ec74f8..fd6dd910 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; public class KMJCardSimApplet extends KMKeymasterApplet { diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index dec071e6..78c01302 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.security.Signature; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java index 3ebf5fe0..855a3104 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.Util; diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java index cb8df259..7b4352f8 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import javacard.framework.Util; diff --git a/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java index f3d36663..a472ff27 100644 --- a/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java +++ b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMError.java b/Applet/src/com/android/javacard/keymaster/KMError.java index 85c71654..8f842236 100644 --- a/Applet/src/com/android/javacard/keymaster/KMError.java +++ b/Applet/src/com/android/javacard/keymaster/KMError.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMOperation.java b/Applet/src/com/android/javacard/keymaster/KMOperation.java index 4011d7f5..8db3312b 100644 --- a/Applet/src/com/android/javacard/keymaster/KMOperation.java +++ b/Applet/src/com/android/javacard/keymaster/KMOperation.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; /** diff --git a/Applet/src/com/android/javacard/keymaster/KMUpgradable.java b/Applet/src/com/android/javacard/keymaster/KMUpgradable.java index e3958a67..6815374e 100644 --- a/Applet/src/com/android/javacard/keymaster/KMUpgradable.java +++ b/Applet/src/com/android/javacard/keymaster/KMUpgradable.java @@ -1,3 +1,18 @@ +/* + * Copyright(C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" (short)0IS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.android.javacard.keymaster; import org.globalplatform.upgrade.Element; From 3fecf13985cfe52be03382add1859a3b3c1f6e21 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Sun, 7 Feb 2021 22:27:26 +0530 Subject: [PATCH 6/6] Removed commented code --- .../src/com/android/javacard/keymaster/KMEncoder.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/Applet/src/com/android/javacard/keymaster/KMEncoder.java index 72f906bf..685ba468 100644 --- a/Applet/src/com/android/javacard/keymaster/KMEncoder.java +++ b/Applet/src/com/android/javacard/keymaster/KMEncoder.java @@ -363,15 +363,4 @@ private void incrementStartOff(short inc){ ISOException.throwIt(ISO7816.SW_DATA_INVALID); } } - /* - private static void print(byte[] buf, short start, short length){ - StringBuilder sb = new StringBuilder(); - for(int i = start; i < (start+length); i++){ - sb.append(String.format("%02X", buf[i])) ; - //if((i-start)%16 == 0 && (i-start) != 0) sb.append(String.format("\n")); - } - System.out.println(sb.toString()); - } - - */ }