diff options
author | subrahmanyaman <subrahmanyaman@google.com> | 2023-03-02 23:12:25 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-03-02 23:12:25 +0000 |
commit | a7f08e34987dc84119e10018a579d6e7e3311054 (patch) | |
tree | b658393f4e900ffa5f76410d6e980327b5153efd | |
parent | 2eddeb4117f77a192365393a2bb0b80e9ea6f2ba (diff) | |
parent | 0ce113724cf47ff0ecde308bd4af9294106f7167 (diff) | |
download | libese-a7f08e34987dc84119e10018a579d6e7e3311054.tar.gz |
km200: Added missing java doc as per the review comments on aosp/2082578 am: 0ce113724c
Original change: https://android-review.googlesource.com/c/platform/external/libese/+/2368029
Change-Id: I5d1cb8f8c32d57e824f67bc3bb7c19363e7c9603
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
37 files changed, 239 insertions, 312 deletions
diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java index 5a8eb76..146b634 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -27,6 +27,11 @@ import org.globalplatform.upgrade.Element; import org.globalplatform.upgrade.OnUpgradeListener; import org.globalplatform.upgrade.UpgradeManager; +/** + * This class extends from KMKeymasterApplet which is main entry point to receive apdu commands. All + * the provision commands are processed here and later the data is handed over to the KMDataStore + * class which stores the data in the flash memory. + */ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeListener { // Magic number version private static final byte KM_MAGIC_NUMBER = (byte) 0x82; @@ -305,8 +310,6 @@ public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeLis } private void processProvisionOEMRootPublicKeyCmd(APDU apdu) { - // Re-purpose the apdu buffer as scratch pad. - byte[] scratchPad = apdu.getBuffer(); // Arguments short keyparams = KMKeyParameters.exp(); short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT); diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 90ec7f2..7245793 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -18,17 +18,17 @@ package com.android.javacard.keymaster; import com.android.javacard.seprovider.KMAESKey; import com.android.javacard.seprovider.KMAttestationCert; import com.android.javacard.seprovider.KMException; -import com.android.javacard.seprovider.KMMasterKey; +import com.android.javacard.seprovider.KMKey; import com.android.javacard.seprovider.KMSEProvider; import javacard.framework.JCSystem; import javacard.framework.Util; -// 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. -// Whatever fields that are fixed are added as byte arrays. The Extensions are encoded as per -// the values. -// The certificate is assembled with leafs first and then the sequences. - +/** + * The class encodes strongbox generated and signed attestation certificates. It only encodes the + * required fields of the certificates. This class is not meant to be a generic X509 cert encoder. + * Any fields that are fixed are added as byte arrays. Extensions are encoded as per the values. The + * certificate is assembled with leafs first and then the sequences. + */ public class KMAttestationCertImpl implements KMAttestationCert { private static final byte MAX_PARAMS = 30; @@ -967,7 +967,7 @@ public class KMAttestationCertImpl implements KMAttestationCert { short appIdOff, short attestAppIdLen, byte resetSinceIdRotation, - KMMasterKey masterKey) { + KMKey masterKey) { // Concatenate T||C||R // temporal count T short temp = diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMConfigurations.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMConfigurations.java index 3fb3653..738326b 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMConfigurations.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMConfigurations.java @@ -15,6 +15,10 @@ */ package com.android.javacard.keymaster; +/** + * This class contains all the configuration values. Vendors can modify these values accordingly + * based on their environment. + */ public class KMConfigurations { // Machine types public static final byte LITTLE_ENDIAN = 0x00; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java index bed3ba7..95ee67f 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -18,6 +18,10 @@ package com.android.javacard.keymaster; import com.android.javacard.seprovider.KMException; import javacard.framework.Util; +/** + * This is a utility class which helps in converting date to UTC format and doing some arithmetic + * Operations. + */ public class KMUtils { // 64 bit unsigned calculations for time diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAESKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAESKey.java index 06f1eaf..41059bb 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAESKey.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAESKey.java @@ -18,7 +18,8 @@ package com.android.javacard.seprovider; import javacard.security.AESKey; import org.globalplatform.upgrade.Element; -public class KMAESKey implements KMMasterKey { +/** This is a wrapper class for AESKey. */ +public class KMAESKey implements KMKey { public AESKey aesKey; @@ -44,4 +45,9 @@ public class KMAESKey implements KMMasterKey { public static short getBackupObjectCount() { return (short) 1; } + + @Override + public short getPublicKey(byte[] buf, short offset) { + return (short) 0; + } } diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java index 3b13b3e..6bfc8c3 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java @@ -8,7 +8,7 @@ * 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, + * 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. @@ -38,6 +38,13 @@ import javacardx.crypto.Cipher; import org.globalplatform.upgrade.Element; import org.globalplatform.upgrade.UpgradeManager; +/** + * This class implements KMSEProvider and provides all the necessary crypto operations required to + * support the KeyMint specification. This class supports AES, 3DES, HMAC, RSA, ECDSA, ECDH + * algorithms additionally it also supports ECDSA_NO_DIGEST, RSA_NO_DIGEST and RSA_OAEP_MGF1_SHA1 + * and RSA_OAEP_MGF1_SHA256 algorithms. This class follows the pattern of Init-Update-Final for the + * crypto operations. + */ public class KMAndroidSEProvider implements KMSEProvider { public static final byte AES_GCM_TAG_LENGTH = 16; @@ -477,7 +484,7 @@ public class KMAndroidSEProvider implements KMSEProvider { } public HMACKey cmacKdf( - KMPreSharedKey preSharedKey, + KMKey preSharedKey, byte[] label, short labelStart, short labelLen, @@ -564,7 +571,7 @@ public class KMAndroidSEProvider implements KMSEProvider { @Override public short hmacKDF( - KMMasterKey masterkey, + KMKey masterkey, byte[] data, short dataStart, short dataLength, @@ -583,7 +590,7 @@ public class KMAndroidSEProvider implements KMSEProvider { @Override public boolean hmacVerify( - KMComputedHmacKey key, + KMKey key, byte[] data, short dataStart, short dataLength, @@ -943,7 +950,7 @@ public class KMAndroidSEProvider implements KMSEProvider { } @Override - public KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey) { + public KMOperation initTrustedConfirmationSymmetricOperation(KMKey computedHmacKey) { KMHmacKey key = (KMHmacKey) computedHmacKey; return createHmacSignerVerifier(KMType.VERIFY, KMType.SHA2_256, key.hmacKey, true); } @@ -1109,7 +1116,7 @@ public class KMAndroidSEProvider implements KMSEProvider { @Override public short cmacKDF( - KMPreSharedKey pSharedKey, + KMKey pSharedKey, byte[] label, short labelStart, short labelLen, @@ -1129,24 +1136,24 @@ public class KMAndroidSEProvider implements KMSEProvider { } @Override - public KMMasterKey createMasterKey(KMMasterKey masterKey, short keySizeBits) { + public KMKey createMasterKey(KMKey masterKey, 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); - ((KMAESKey) masterKey).aesKey.setKey(tmpArray, (short) 0); } - return (KMMasterKey) masterKey; + short keyLen = (short) (keySizeBits / 8); + Util.arrayFillNonAtomic(tmpArray, (short) 0, keyLen, (byte) 0); + getTrueRandomNumber(tmpArray, (short) 0, keyLen); + ((KMAESKey) masterKey).aesKey.setKey(tmpArray, (short) 0); + return (KMKey) masterKey; } finally { clean(); } } @Override - public KMPreSharedKey createPreSharedKey( - KMPreSharedKey preSharedKey, byte[] keyData, short offset, short length) { + public KMKey createPreSharedKey(KMKey preSharedKey, byte[] keyData, short offset, short length) { short lengthInBits = (short) (length * 8); if ((lengthInBits % 8 != 0) || !(lengthInBits >= 64 && lengthInBits <= 512)) { CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); @@ -1156,12 +1163,12 @@ public class KMAndroidSEProvider implements KMSEProvider { preSharedKey = new KMHmacKey(key); } ((KMHmacKey) preSharedKey).hmacKey.setKey(keyData, offset, length); - return (KMPreSharedKey) preSharedKey; + return (KMKey) preSharedKey; } @Override - public KMComputedHmacKey createComputedHmacKey( - KMComputedHmacKey computedHmacKey, byte[] keyData, short offset, short length) { + public KMKey createComputedHmacKey( + KMKey computedHmacKey, byte[] keyData, short offset, short length) { if (length != COMPUTED_HMAC_KEY_SIZE) { CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } @@ -1171,7 +1178,7 @@ public class KMAndroidSEProvider implements KMSEProvider { computedHmacKey = new KMHmacKey(key); } ((KMHmacKey) computedHmacKey).hmacKey.setKey(keyData, offset, length); - return (KMComputedHmacKey) computedHmacKey; + return (KMKey) computedHmacKey; } @Override @@ -1205,30 +1212,6 @@ public class KMAndroidSEProvider implements KMSEProvider { } @Override - public short ecSign256( - KMAttestationKey ecPrivKey, - byte[] inputDataBuf, - short inputDataStart, - short inputDataLength, - byte[] outputDataBuf, - short outputDataStart) { - Signature.OneShot signer = null; - try { - - signer = - Signature.OneShot.open( - MessageDigest.ALG_SHA_256, Signature.SIG_CIPHER_ECDSA, Cipher.PAD_NULL); - signer.init(((KMECPrivateKey) ecPrivKey).ecKeyPair.getPrivate(), Signature.MODE_SIGN); - return signer.sign( - inputDataBuf, inputDataStart, inputDataLength, outputDataBuf, outputDataStart); - } finally { - if (signer != null) { - signer.close(); - } - } - } - - @Override public short rsaSign256Pkcs1( byte[] secret, short secretStart, @@ -1395,8 +1378,8 @@ public class KMAndroidSEProvider implements KMSEProvider { } @Override - public short ecSign256( - KMDeviceUniqueKeyPair ecPrivKey, + public short signWithDeviceUniqueKey( + KMKey ecPrivKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, @@ -1407,7 +1390,8 @@ public class KMAndroidSEProvider implements KMSEProvider { signer = Signature.OneShot.open( MessageDigest.ALG_SHA_256, Signature.SIG_CIPHER_ECDSA, Cipher.PAD_NULL); - signer.init(((KMECDeviceUniqueKey) ecPrivKey).ecKeyPair.getPrivate(), Signature.MODE_SIGN); + signer.init( + ((KMECDeviceUniqueKeyPair) ecPrivKey).ecKeyPair.getPrivate(), Signature.MODE_SIGN); return signer.sign( inputDataBuf, inputDataStart, inputDataLength, outputDataBuf, outputDataStart); } finally { @@ -1418,8 +1402,8 @@ public class KMAndroidSEProvider implements KMSEProvider { } @Override - public KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair( - KMDeviceUniqueKeyPair key, + public KMKey createRkpDeviceUniqueKeyPair( + KMKey key, byte[] pubKey, short pubKeyOff, short pubKeyLen, @@ -1429,18 +1413,17 @@ public class KMAndroidSEProvider implements KMSEProvider { if (key == null) { KeyPair ecKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); poolMgr.initECKey(ecKeyPair); - key = new KMECDeviceUniqueKey(ecKeyPair); + key = new KMECDeviceUniqueKeyPair(ecKeyPair); } - ECPrivateKey ecKeyPair = (ECPrivateKey) ((KMECDeviceUniqueKey) key).ecKeyPair.getPrivate(); - ECPublicKey ecPublicKey = (ECPublicKey) ((KMECDeviceUniqueKey) key).ecKeyPair.getPublic(); + ECPrivateKey ecKeyPair = (ECPrivateKey) ((KMECDeviceUniqueKeyPair) key).ecKeyPair.getPrivate(); + ECPublicKey ecPublicKey = (ECPublicKey) ((KMECDeviceUniqueKeyPair) key).ecKeyPair.getPublic(); ecKeyPair.setS(privKey, privKeyOff, privKeyLen); ecPublicKey.setW(pubKey, pubKeyOff, pubKeyLen); - return (KMDeviceUniqueKeyPair) key; + return (KMKey) key; } @Override - public KMRkpMacKey createRkpMacKey( - KMRkpMacKey rkpMacKey, byte[] keyData, short offset, short length) { + public KMKey createRkpMacKey(KMKey rkpMacKey, byte[] keyData, short offset, short length) { if (rkpMacKey == null) { HMACKey key = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, (short) (length * 8), false); @@ -1494,7 +1477,7 @@ public class KMAndroidSEProvider implements KMSEProvider { KMHmacKey.onSave(element, (KMHmacKey) object); break; case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: - KMECDeviceUniqueKey.onSave(element, (KMECDeviceUniqueKey) object); + KMECDeviceUniqueKeyPair.onSave(element, (KMECDeviceUniqueKeyPair) object); break; case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: KMHmacKey.onSave(element, (KMHmacKey) object); @@ -1518,7 +1501,7 @@ public class KMAndroidSEProvider implements KMSEProvider { case KMDataStoreConstants.INTERFACE_TYPE_PRE_SHARED_KEY: return KMHmacKey.onRestore((HMACKey) element.readObject()); case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: - return KMECDeviceUniqueKey.onRestore((KeyPair) element.readObject()); + return KMECDeviceUniqueKeyPair.onRestore((KeyPair) element.readObject()); case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: return KMHmacKey.onRestore((HMACKey) element.readObject()); default: @@ -1538,7 +1521,7 @@ public class KMAndroidSEProvider implements KMSEProvider { primitiveCount += KMHmacKey.getBackupPrimitiveByteCount(); break; case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: - primitiveCount += KMECDeviceUniqueKey.getBackupPrimitiveByteCount(); + primitiveCount += KMECDeviceUniqueKeyPair.getBackupPrimitiveByteCount(); break; case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: primitiveCount += KMHmacKey.getBackupPrimitiveByteCount(); @@ -1557,7 +1540,7 @@ public class KMAndroidSEProvider implements KMSEProvider { case KMDataStoreConstants.INTERFACE_TYPE_PRE_SHARED_KEY: return KMHmacKey.getBackupObjectCount(); case KMDataStoreConstants.INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR: - return KMECDeviceUniqueKey.getBackupObjectCount(); + return KMECDeviceUniqueKeyPair.getBackupObjectCount(); case KMDataStoreConstants.INTERFACE_TYPE_RKP_MAC_KEY: return KMHmacKey.getBackupObjectCount(); default: diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationCert.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationCert.java index da60794..05801b0 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationCert.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationCert.java @@ -73,7 +73,7 @@ public interface KMAttestationCert { short attestAppIdOff, short attestAppIdLen, byte resetSinceIdRotation, - KMMasterKey masterKey); + KMKey masterKey); /** * Set start time received from creation/activation time tag. Used for certificate's valid period. diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationKey.java deleted file mode 100644 index d941306..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAttestationKey.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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.seprovider; - -/** - * KMAttestationKey is a marker interface and the SE Provider has to implement 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/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java deleted file mode 100644 index 8d406b4..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.android.javacard.seprovider; - -public interface KMComputedHmacKey {} diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java index a1d6454..61ddb36 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDataStoreConstants.java @@ -1,9 +1,15 @@ package com.android.javacard.seprovider; +/** + * This class holds different interface type constants to differentiate between the instances of + * Computed Hmac key, device unique key pair, RKP Mac key, and master key when passed as generic + * objects. These constants are used in upgrade flow to retrieve the size of the object and + * primitive types saved and restored for respective key types. + */ public class KMDataStoreConstants { // INTERFACE Types public static final byte INTERFACE_TYPE_COMPUTED_HMAC_KEY = 0x01; - public static final byte INTERFACE_TYPE_ATTESTATION_KEY = 0x02; + // 0x02 reserved for INTERFACE_TYPE_ATTESTATION_KEY public static final byte INTERFACE_TYPE_DEVICE_UNIQUE_KEY_PAIR = 0x03; public static final byte INTERFACE_TYPE_MASTER_KEY = 0x04; public static final byte INTERFACE_TYPE_PRE_SHARED_KEY = 0x05; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKeyPair.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKeyPair.java deleted file mode 100644 index 9bbccd8..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMDeviceUniqueKeyPair.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright(C) 2021 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.seprovider; - -public interface KMDeviceUniqueKeyPair { - - short getPublicKey(byte[] buf, short offset); -} diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKeyPair.java index 8adb1fb..0e430a3 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKey.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECDeviceUniqueKeyPair.java @@ -19,7 +19,8 @@ import javacard.security.ECPublicKey; import javacard.security.KeyPair; import org.globalplatform.upgrade.Element; -public class KMECDeviceUniqueKey implements KMDeviceUniqueKeyPair { +/** This is a wrapper class for KeyPair. */ +public class KMECDeviceUniqueKeyPair implements KMKey { public KeyPair ecKeyPair; @@ -29,19 +30,19 @@ public class KMECDeviceUniqueKey implements KMDeviceUniqueKeyPair { return publicKey.getW(buf, offset); } - public KMECDeviceUniqueKey(KeyPair ecPair) { + public KMECDeviceUniqueKeyPair(KeyPair ecPair) { ecKeyPair = ecPair; } - public static void onSave(Element element, KMECDeviceUniqueKey kmKey) { + public static void onSave(Element element, KMECDeviceUniqueKeyPair kmKey) { element.write(kmKey.ecKeyPair); } - public static KMECDeviceUniqueKey onRestore(KeyPair ecKey) { + public static KMECDeviceUniqueKeyPair onRestore(KeyPair ecKey) { if (ecKey == null) { return null; } - return new KMECDeviceUniqueKey(ecKey); + return new KMECDeviceUniqueKeyPair(ecKey); } public static short getBackupPrimitiveByteCount() { diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECPrivateKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECPrivateKey.java deleted file mode 100644 index 35c687b..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMECPrivateKey.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.seprovider; - -import javacard.security.KeyPair; -import org.globalplatform.upgrade.Element; - -public class KMECPrivateKey implements KMAttestationKey { - - public KeyPair ecKeyPair; - - public KMECPrivateKey(KeyPair ecPair) { - ecKeyPair = ecPair; - } - - public static void onSave(Element element, KMECPrivateKey kmKey) { - element.write(kmKey.ecKeyPair); - } - - public static KMECPrivateKey onRestore(KeyPair ecKey) { - if (ecKey == null) { - return null; - } - return new KMECPrivateKey(ecKey); - } - - public static short getBackupPrimitiveByteCount() { - return (short) 0; - } - - public static short getBackupObjectCount() { - return (short) 1; - } -} diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMEcdsa256NoDigestSignature.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMEcdsa256NoDigestSignature.java index e9b95ee..83774ab 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMEcdsa256NoDigestSignature.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMEcdsa256NoDigestSignature.java @@ -22,6 +22,10 @@ import javacard.security.MessageDigest; import javacard.security.Signature; import javacardx.crypto.Cipher; +/** + * This class provides support for ECDSA_NO_DIGEST signature algorithm. Added this because javacard + * 3.0.5 does not support this + */ public class KMEcdsa256NoDigestSignature extends Signature { public static final byte ALG_ECDSA_NODIGEST = (byte) 0x67; @@ -31,6 +35,8 @@ public class KMEcdsa256NoDigestSignature extends Signature { public KMEcdsa256NoDigestSignature(byte alg) { algorithm = alg; + // There is no constant for no digest so ALG_ECDSA_SHA_256 is used. However, + // signPreComputedHash is used for signing which is equivalent to no digest sign. inst = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false); } diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java index 3d25143..e938a2b 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java @@ -18,7 +18,8 @@ package com.android.javacard.seprovider; import javacard.security.HMACKey; import org.globalplatform.upgrade.Element; -public class KMHmacKey implements KMPreSharedKey, KMComputedHmacKey, KMRkpMacKey { +/** This is a wrapper class for HMACKey. */ +public class KMHmacKey implements KMKey { public HMACKey hmacKey; @@ -44,4 +45,9 @@ public class KMHmacKey implements KMPreSharedKey, KMComputedHmacKey, KMRkpMacKey public static short getBackupObjectCount() { return (short) 1; } + + @Override + public short getPublicKey(byte[] buf, short offset) { + return (short) 0; + } } diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKey.java new file mode 100644 index 0000000..9894382 --- /dev/null +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKey.java @@ -0,0 +1,10 @@ +package com.android.javacard.seprovider; + +/** + * This interface helps to decouple Javacard internal key objects from the keymaster package. Using + * Javacard key objects provides security by providing protection against side channel attacks. + * KMAESKey, KMECDeviceUniqueKey and KMHmacKey implements this interface. + */ +public interface KMKey { + short getPublicKey(byte[] buf, short offset); +} diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKeyObject.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKeyObject.java index 26edaa2..a37da08 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKeyObject.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMKeyObject.java @@ -1,5 +1,9 @@ package com.android.javacard.seprovider; +/** + * This class holds the KeyObject and its associated algorithm value. Each KMKeyObject is tied to + * one of the crypto operations. + */ public class KMKeyObject { public byte algorithm; public Object keyObjectInst; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMMasterKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMMasterKey.java deleted file mode 100644 index 27afb3d..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMMasterKey.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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.seprovider; - -/** - * KMMasterKey is a marker interface and the SE Provider has to implement 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/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMOperationImpl.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMOperationImpl.java index b2a2421..8059e44 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMOperationImpl.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMOperationImpl.java @@ -25,6 +25,10 @@ import javacard.security.Signature; import javacardx.crypto.AEADCipher; import javacardx.crypto.Cipher; +/** + * This class contains the actual implementation of all the crypto operations. It internally uses + * the Javacard crypto library to perform the operations. + */ public class KMOperationImpl implements KMOperation { private static final byte ALG_TYPE_OFFSET = 0x00; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java index d4d98e3..8ca2664 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java @@ -29,7 +29,15 @@ import javacard.security.Signature; import javacardx.crypto.AEADCipher; import javacardx.crypto.Cipher; -/** This class manages all the pool instances. */ +/** + * This class creates and manages all the cipher, signer, key agreement, operation and trusted + * confirmation pool instances. Each cipher or signer pool can hold a maximum of 4 instances per + * algorithm; however, only one instance of each algorithm is created initially and if required more + * instances are created dynamically. A maximum of four operations can be performed simultaneously. + * Upon reaching the maximum limit of 4, further operations or crypto instances will throw a + * TOO_MANY_OPERATIONS error. TrustedConfirmation pool is to support any operation which has the + * TRUSTED_CONFIRMATION tag in its key parameters. + */ public class KMPoolManager { public static final byte MAX_OPERATION_INSTANCES = 4; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPreSharedKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPreSharedKey.java deleted file mode 100644 index 8f94c82..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPreSharedKey.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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.seprovider; - -/** - * KMPreSharedKey is a marker interface and the SE Provider has to implement 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 {} diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRkpMacKey.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRkpMacKey.java deleted file mode 100644 index fe6ad84..0000000 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRkpMacKey.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.android.javacard.seprovider; - -public interface KMRkpMacKey {} diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsa2048NoDigestSignature.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsa2048NoDigestSignature.java index 287a449..4890ce2 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsa2048NoDigestSignature.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsa2048NoDigestSignature.java @@ -22,6 +22,7 @@ import javacard.security.MessageDigest; import javacard.security.Signature; import javacardx.crypto.Cipher; +/** This class provides support for RSA_NO_DIGEST signature algorithm. */ public class KMRsa2048NoDigestSignature extends Signature { public static final byte ALG_RSA_SIGN_NOPAD = (byte) 0x65; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsaOAEPEncoding.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsaOAEPEncoding.java index 74322bd..bf34ea1 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsaOAEPEncoding.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMRsaOAEPEncoding.java @@ -22,6 +22,7 @@ import javacard.security.Key; import javacard.security.MessageDigest; import javacardx.crypto.Cipher; +/** This class has the implementation for RSA_OAEP decoding algorithm. */ public class KMRsaOAEPEncoding extends Cipher { public static final byte ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA1 = (byte) 0x1E; diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java index 1a564cc..9313c04 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java @@ -92,7 +92,7 @@ public interface KMSEProvider { * @param computedHmacKey Instance of the computed Hmac key. * @return instance of KMOperation. */ - KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey); + KMOperation initTrustedConfirmationSymmetricOperation(KMKey computedHmacKey); /** * Verify that the imported key is valid. If the algorithm and/or keysize are not supported then @@ -263,7 +263,7 @@ public interface KMSEProvider { * @return length of the derived key buffer in bytes. */ short cmacKDF( - KMPreSharedKey hmacKey, + KMKey hmacKey, byte[] label, short labelStart, short labelLen, @@ -328,7 +328,7 @@ public interface KMSEProvider { * @return length of the signature buffer in bytes. */ short hmacKDF( - KMMasterKey masterkey, + KMKey masterkey, byte[] data, short dataStart, short dataLength, @@ -350,7 +350,7 @@ public interface KMSEProvider { * @return true if the signature matches. */ boolean hmacVerify( - KMComputedHmacKey hmacKey, + KMKey hmacKey, byte[] data, short dataStart, short dataLength, @@ -390,25 +390,6 @@ public interface KMSEProvider { short outputDataStart); /** - * This is a oneshot operation that signs the data using EC private key. - * - * @param ecPrivKey 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. - * @param outputDataBuf is the output buffer that contains the signature. - * @param outputDataStart is the start of the output data buffer. - * @return length of the decrypted data. - */ - short ecSign256( - KMAttestationKey ecPrivKey, - byte[] inputDataBuf, - short inputDataStart, - short inputDataLength, - byte[] outputDataBuf, - short outputDataStart); - - /** * Implementation of HKDF as per RFC5869 https://datatracker.ietf.org/doc/html/rfc5869#section-2 * * @param ikm is the buffer containing input key material. @@ -498,8 +479,8 @@ public interface KMSEProvider { * @param outputDataStart is the start of the output data buffer. * @return length of the decrypted data. */ - short ecSign256( - KMDeviceUniqueKeyPair ecPrivKey, + short signWithDeviceUniqueKey( + KMKey deviceUniqueKey, byte[] inputDataBuf, short inputDataStart, short inputDataLength, @@ -688,7 +669,7 @@ public interface KMSEProvider { * @param keySizeBits key size in bits. * @return An instance of KMMasterKey. */ - KMMasterKey createMasterKey(KMMasterKey masterKey, short keySizeBits); + KMKey createMasterKey(KMKey masterKey, short keySizeBits); /** * This function creates an HMACKey and initializes the key with the provided input key data. @@ -698,8 +679,7 @@ public interface KMSEProvider { * @param length length of the buffer. * @return An instance of the KMComputedHmacKey. */ - KMComputedHmacKey createComputedHmacKey( - KMComputedHmacKey computedHmacKey, byte[] keyData, short offset, short length); + KMKey createComputedHmacKey(KMKey computedHmacKey, byte[] keyData, short offset, short length); /** Returns true if factory provisioned attestation key is supported. */ boolean isAttestationKeyProvisioned(); @@ -722,8 +702,8 @@ public interface KMSEProvider { * @param privKeyLen private key buffer length. * @return instance of KMDeviceUniqueKey. */ - KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair( - KMDeviceUniqueKeyPair key, + KMKey createRkpDeviceUniqueKeyPair( + KMKey key, byte[] pubKey, short pubKeyOff, short pubKeyLen, @@ -753,8 +733,7 @@ public interface KMSEProvider { * @param length is the length of the key. * @return instance of KMPresharedKey. */ - KMPreSharedKey createPreSharedKey( - KMPreSharedKey presharedKey, byte[] key, short offset, short length); + KMKey createPreSharedKey(KMKey presharedKey, byte[] key, short offset, short length); /** * This function saves the key objects while upgrade. @@ -799,6 +778,5 @@ public interface KMSEProvider { * @param length length of the buffer. * @return An instance of the KMRkpMacKey. */ - KMRkpMacKey createRkpMacKey( - KMRkpMacKey createComputedHmacKey, byte[] keyData, short offset, short length); + KMKey createRkpMacKey(KMKey createComputedHmacKey, byte[] keyData, short offset, short length); } diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMUpgradable.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMUpgradable.java index 69536ab..420b2c7 100644 --- a/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMUpgradable.java +++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMUpgradable.java @@ -17,6 +17,7 @@ package com.android.javacard.seprovider; import org.globalplatform.upgrade.Element; +/** This interface helps in storing and restoring the applet data during the applet upgrades. */ public interface KMUpgradable { void onSave(Element ele); diff --git a/ready_se/google/keymint/KM200/Applet/README.md b/ready_se/google/keymint/KM200/Applet/README.md index ace6950..c14a369 100644 --- a/ready_se/google/keymint/KM200/Applet/README.md +++ b/ready_se/google/keymint/KM200/Applet/README.md @@ -1,14 +1,15 @@ # JavaCardKeymaster Applet
-This directory contains the implementation of the Keymint 1.0
+This directory contains the implementation of the KeyMint 2.0
interface, in the form of a JavaCard 3.0.5 applet which runs in a secure
-element. It must be deployed in conjuction with the associated HAL,
+element. It must be deployed in conjunction with the associated HAL,
which mediates between Android Keystore and this applet.
# Supported Features!
- - Keymint 1.0 supported functions for required VTS compliance.
+ - KeyMint 2.0 supported functions for required VTS compliance.
- SharedSecret 1.0 supported functions for required VTS compliance.
+ - RemotelyProvisionedComponent 2.0 supported functions for required VTS compliance.
# Not supported features
- Factory provisioned attestation key will not be supported in this applet.
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMAsn1Parser.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMAsn1Parser.java index 8ff1bc3..b3eacd6 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMAsn1Parser.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMAsn1Parser.java @@ -4,6 +4,10 @@ import com.android.javacard.seprovider.KMException; import javacard.framework.JCSystem; import javacard.framework.Util; +/** + * This is a utility class that helps in parsing the PKCS8 encoded RSA and EC keys, certificate + * subject, subjectPublicKey info and ECDSA signatures. + */ public class KMAsn1Parser { public static final byte ASN1_OCTET_STRING = 0x04; diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java index 10c7d29..e7dc21d 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMDecoder.java @@ -22,6 +22,11 @@ import javacard.framework.ISOException; import javacard.framework.JCSystem; import javacard.framework.Util; +/** + * This class decodes the CBOR format data into a KMType structure. It interprets the input CBOR + * format using the input expression provided. Validation of KeyMint tags and tag types happens in + * the process of decoding, while constructing the subtype of a KMType structure. + */ public class KMDecoder { // major types diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java index 7405e06..65394bd 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEncoder.java @@ -22,6 +22,11 @@ import javacard.framework.ISOException; import javacard.framework.JCSystem; import javacard.framework.Util; +/** + * This class encodes KMType structures to a cbor format data recursively. Encoded bytes are written + * on the buffer provided by the caller. An exception will be thrown if the encoded data length is + * greater than the buffer length provided. + */ public class KMEncoder { // major types diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index e196371..adc060f 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -18,8 +18,8 @@ package com.android.javacard.keymaster; import com.android.javacard.seprovider.KMAttestationCert; import com.android.javacard.seprovider.KMDataStoreConstants; -import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMException; +import com.android.javacard.seprovider.KMKey; import com.android.javacard.seprovider.KMOperation; import com.android.javacard.seprovider.KMSEProvider; import javacard.framework.APDU; @@ -33,9 +33,9 @@ import javacard.security.CryptoException; import javacardx.apdu.ExtendedLength; /** - * KMKeymasterApplet implements the javacard applet. It creates repository and other install time - * objects. It also implements the keymaster state machine and handles javacard applet life cycle - * events. + * KMKeymasterApplet implements the javacard applet. It creates an instance of the KMRepository and + * other install time objects. It also implements the keymaster state machine and handles javacard + * applet life cycle events. */ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLength { @@ -264,7 +264,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe // ComputeHMAC constants private static final byte HMAC_SHARED_PARAM_MAX_SIZE = 64; // Instance of RemotelyProvisionedComponentDevice, used to redirect the rkp commands. - protected static RemotelyProvisionedComponentDevice rkp; + protected static KMRemotelyProvisionedComponentDevice rkp; protected static KMEncoder encoder; protected static KMDecoder decoder; protected static KMRepository repository; @@ -303,7 +303,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe // initialize default values initHmacNonceAndSeed(); rkp = - new RemotelyProvisionedComponentDevice( + new KMRemotelyProvisionedComponentDevice( encoder, decoder, repository, seProvider, kmDataStore); } @@ -1069,7 +1069,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe if (!testMode && kmDataStore.isProvisionLocked()) { KMException.throwIt(KMError.STATUS_FAILED); } - KMDeviceUniqueKeyPair deviceUniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(testMode); + KMKey deviceUniqueKey = kmDataStore.getRkpDeviceUniqueKeyPair(testMode); short temp = deviceUniqueKey.getPublicKey(scratchPad, (short) 0); short coseKey = KMCose.constructCoseKey( @@ -1139,7 +1139,8 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe coseSignStructure, scratchPad, (short) 0, KMKeymasterApplet.MAX_COSE_BUF_SIZE); // do sign short len = - seProvider.ecSign256(deviceUniqueKey, scratchPad, (short) 0, temp, scratchPad, temp); + seProvider.signWithDeviceUniqueKey( + deviceUniqueKey, scratchPad, (short) 0, temp, scratchPad, temp); len = KMAsn1Parser.instance() .decodeEcdsa256Signature(KMByteBlob.instance(scratchPad, temp, len), scratchPad, temp); @@ -1817,6 +1818,9 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private void processDeleteAllKeysCmd(APDU apdu) { // No arguments + // This function is triggered when a factory reset event occurs. + // Regenerate the master key to render all keys unusable. + kmDataStore.regenerateMasterKey(); // Send ok sendResponse(apdu, KMError.OK); } diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java index f58debc..28bb810 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java @@ -1,12 +1,8 @@ package com.android.javacard.keymaster; -import com.android.javacard.seprovider.KMComputedHmacKey; import com.android.javacard.seprovider.KMDataStoreConstants; -import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMException; -import com.android.javacard.seprovider.KMMasterKey; -import com.android.javacard.seprovider.KMPreSharedKey; -import com.android.javacard.seprovider.KMRkpMacKey; +import com.android.javacard.seprovider.KMKey; import com.android.javacard.seprovider.KMSEProvider; import com.android.javacard.seprovider.KMUpgradable; import javacard.framework.ISO7816; @@ -15,6 +11,12 @@ import javacard.framework.JCSystem; import javacard.framework.Util; import org.globalplatform.upgrade.Element; +/** + * This is a storage class which helps in storing the provisioned data, ROT, OS version, Boot patch + * level, Vendor Patchlevel, HMAC nonce, computed shared secret, 8 auth tags, device-locked, + * device-locked timestamp and device-locked password only. Only the provisioned data is restored + * back during applet upgrades and the remaining data is flushed. + */ public class KMKeymintDataStore implements KMUpgradable { // Data table configuration @@ -93,12 +95,12 @@ public class KMKeymintDataStore implements KMUpgradable { private KMRepository repository; private byte[] additionalCertChain; private byte[] bcc; - private KMMasterKey masterKey; - private KMDeviceUniqueKeyPair testDeviceUniqueKeyPair; - private KMDeviceUniqueKeyPair deviceUniqueKeyPair; - private KMPreSharedKey preSharedKey; - private KMComputedHmacKey computedHmacKey; - private KMRkpMacKey rkpMacKey; + private KMKey masterKey; + private KMKey testDeviceUniqueKeyPair; + private KMKey deviceUniqueKeyPair; + private KMKey preSharedKey; + private KMKey computedHmacKey; + private KMKey rkpMacKey; private byte[] oemRootPublicKey; private short provisionStatus; @@ -527,14 +529,20 @@ public class KMKeymintDataStore implements KMUpgradable { buf[offset] = state; } - public KMMasterKey createMasterKey(short keySizeBits) { + // The master key should only be generated during applet installation and + // during a device factory reset event. + public KMKey createMasterKey(short keySizeBits) { if (masterKey == null) { masterKey = seProvider.createMasterKey(masterKey, keySizeBits); } - return (KMMasterKey) masterKey; + return (KMKey) masterKey; } - public KMMasterKey getMasterKey() { + public KMKey regenerateMasterKey() { + return seProvider.createMasterKey(masterKey, KMKeymasterApplet.MASTER_KEY_SIZE); + } + + public KMKey getMasterKey() { return masterKey; } @@ -547,7 +555,7 @@ public class KMKeymintDataStore implements KMUpgradable { } } - public KMPreSharedKey getPresharedKey() { + public KMKey getPresharedKey() { if (preSharedKey == null) { KMException.throwIt(KMError.INVALID_DATA); } @@ -565,14 +573,14 @@ public class KMKeymintDataStore implements KMUpgradable { } } - public KMComputedHmacKey getComputedHmacKey() { + public KMKey getComputedHmacKey() { if (computedHmacKey == null) { KMException.throwIt(KMError.INVALID_DATA); } return computedHmacKey; } - public KMDeviceUniqueKeyPair createRkpTestDeviceUniqueKeyPair( + public KMKey createRkpTestDeviceUniqueKeyPair( byte[] pubKey, short pubKeyOff, short pubKeyLen, @@ -596,7 +604,7 @@ public class KMKeymintDataStore implements KMUpgradable { return testDeviceUniqueKeyPair; } - public KMDeviceUniqueKeyPair createRkpDeviceUniqueKeyPair( + public KMKey createRkpDeviceUniqueKeyPair( byte[] pubKey, short pubKeyOff, short pubKeyLen, @@ -614,8 +622,8 @@ public class KMKeymintDataStore implements KMUpgradable { return deviceUniqueKeyPair; } - public KMDeviceUniqueKeyPair getRkpDeviceUniqueKeyPair(boolean testMode) { - return ((KMDeviceUniqueKeyPair) (testMode ? testDeviceUniqueKeyPair : deviceUniqueKeyPair)); + public KMKey getRkpDeviceUniqueKeyPair(boolean testMode) { + return ((KMKey) (testMode ? testDeviceUniqueKeyPair : deviceUniqueKeyPair)); } public void createRkpMacKey(byte[] keydata, short offset, short length) { @@ -626,7 +634,7 @@ public class KMKeymintDataStore implements KMUpgradable { } } - public KMRkpMacKey getRkpMacKey() { + public KMKey getRkpMacKey() { if (rkpMacKey == null) { KMException.throwIt(KMError.INVALID_DATA); } @@ -954,11 +962,11 @@ public class KMKeymintDataStore implements KMUpgradable { bcc = (byte[]) element.readObject(); // Read Key Objects - masterKey = (KMMasterKey) seProvider.onRestore(element); + masterKey = (KMKey) seProvider.onRestore(element); seProvider.onRestore(element); // pop computedHmacKey - preSharedKey = (KMPreSharedKey) seProvider.onRestore(element); - deviceUniqueKeyPair = (KMDeviceUniqueKeyPair) seProvider.onRestore(element); - rkpMacKey = (KMRkpMacKey) seProvider.onRestore(element); + preSharedKey = (KMKey) seProvider.onRestore(element); + deviceUniqueKeyPair = (KMKey) seProvider.onRestore(element); + rkpMacKey = (KMKey) seProvider.onRestore(element); handleProvisionStatusUpgrade(oldDataTable, oldDataIndex); } @@ -981,10 +989,10 @@ public class KMKeymintDataStore implements KMUpgradable { bcc = (byte[]) element.readObject(); oemRootPublicKey = (byte[]) element.readObject(); // Read Key Objects - masterKey = (KMMasterKey) seProvider.onRestore(element); - preSharedKey = (KMPreSharedKey) seProvider.onRestore(element); - deviceUniqueKeyPair = (KMDeviceUniqueKeyPair) seProvider.onRestore(element); - rkpMacKey = (KMRkpMacKey) seProvider.onRestore(element); + masterKey = (KMKey) seProvider.onRestore(element); + preSharedKey = (KMKey) seProvider.onRestore(element); + deviceUniqueKeyPair = (KMKey) seProvider.onRestore(element); + rkpMacKey = (KMKey) seProvider.onRestore(element); } public void getProvisionStatus(byte[] dataTable, byte[] scratchpad, short offset) { diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMMap.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMMap.java index 4583e02..2418204 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMMap.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMMap.java @@ -20,6 +20,13 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.Util; +/** + * KMMap represents an array of a KMType key and a KMType value. Map is the sequence of pairs. Each + * pair is one or more sub-types of KMType. The KMMap instance maps to the CBOR type map. KMMap is a + * KMType and it further extends the value field in TLV_HEADER as MAP_HEADER struct{ short + * subType;short length;} followed by a sequence of pairs. Each pair contains a key and a value as + * short pointers to KMType instances. + */ public class KMMap extends KMType { public static final short ANY_MAP_LENGTH = 0x1000; diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMNInteger.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMNInteger.java index 6246f21..3a6404e 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMNInteger.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMNInteger.java @@ -20,6 +20,10 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.Util; +/** + * Represents 8-bit, 16-bit, 32-bit and 64-bit signed integer. It corresponds to CBOR int type. + * struct{byte NEG_INTEGER_TYPE; short length; 4 or 8 bytes of value} + */ public class KMNInteger extends KMInteger { public static final byte SIGNED_MASK = (byte) 0x80; diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMRemotelyProvisionedComponentDevice.java index e33ecdf..b844ce6 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMRemotelyProvisionedComponentDevice.java @@ -15,8 +15,8 @@ */ package com.android.javacard.keymaster; -import com.android.javacard.seprovider.KMDeviceUniqueKeyPair; import com.android.javacard.seprovider.KMException; +import com.android.javacard.seprovider.KMKey; import com.android.javacard.seprovider.KMOperation; import com.android.javacard.seprovider.KMSEProvider; import javacard.framework.APDU; @@ -25,16 +25,16 @@ import javacard.framework.ISOException; import javacard.framework.JCSystem; import javacard.framework.Util; -/* - * This class handles the remote key provisioning. Generates an RKP key and generates a certificate signing - * request(CSR). The generation of CSR is divided amoung multiple functions to the save the memory inside - * the Applet. The set of functions to be called sequentially in the order to complete the process of - * generating the CSR are processBeginSendData, processUpdateKey, processUpdateEekChain, - * processUpdateChallenge, processFinishSendData and getResponse. ProcessUpdateKey is called N times, where - * N is the number of keys. Similarly getResponse is called is multiple times till the client receives the - * response completely. +/** + * This class handles remote key provisioning. Generates an RKP key and generates a certificate + * signing request(CSR). The generation of CSR is divided among multiple functions to the save the + * memory inside the Applet. The set of functions to be called sequentially in the order to complete + * the process of generating the CSR are processBeginSendData, processUpdateKey, + * processUpdateEekChain, processUpdateChallenge, processFinishSendData, and getResponse. + * ProcessUpdateKey is called Ntimes, where N is the number of keys. Similarly, getResponse is + * called multiple times till the client receives the response completely. */ -public class RemotelyProvisionedComponentDevice { +public class KMRemotelyProvisionedComponentDevice { // Device Info labels public static final byte[] BRAND = {0x62, 0x72, 0x61, 0x6E, 0x64}; @@ -151,7 +151,7 @@ public class RemotelyProvisionedComponentDevice { private Object[] operation; private short[] dataIndex; - public RemotelyProvisionedComponentDevice( + public KMRemotelyProvisionedComponentDevice( KMEncoder encoder, KMDecoder decoder, KMRepository repository, @@ -790,10 +790,7 @@ public class RemotelyProvisionedComponentDevice { } private short createSignedMac( - KMDeviceUniqueKeyPair deviceUniqueKeyPair, - byte[] scratchPad, - short deviceMapPtr, - short pubKeysToSign) { + KMKey deviceUniqueKeyPair, byte[] scratchPad, short deviceMapPtr, short pubKeysToSign) { // Challenge short dataEntryIndex = getEntry(CHALLENGE); short challengePtr = KMByteBlob.instance(data, dataEntryIndex, getEntryLength(CHALLENGE)); @@ -834,7 +831,7 @@ public class RemotelyProvisionedComponentDevice { short maxEcdsaSignLen = 72; short reclaimIndex = repository.allocReclaimableMemory(maxEcdsaSignLen); short len = - seProvider.ecSign256( + seProvider.signWithDeviceUniqueKey( deviceUniqueKeyPair, scratchPad, (short) 0, @@ -858,8 +855,8 @@ public class RemotelyProvisionedComponentDevice { protectedHeaders, unprotectedHeader, ephmeralMacKey, signStructure); } - private KMDeviceUniqueKeyPair createDeviceUniqueKeyPair(boolean testMode, byte[] scratchPad) { - KMDeviceUniqueKeyPair deviceUniqueKeyPair; + private KMKey createDeviceUniqueKeyPair(boolean testMode, byte[] scratchPad) { + KMKey deviceUniqueKeyPair; rkpTmpVariables[0] = 0; rkpTmpVariables[1] = 0; if (testMode) { @@ -1372,7 +1369,7 @@ public class RemotelyProvisionedComponentDevice { private short processSignedMac(byte[] scratchPad, short pubKeysToSignMac, short deviceInfo) { // Construct SignedMac - KMDeviceUniqueKeyPair deviceUniqueKeyPair = + KMKey deviceUniqueKeyPair = createDeviceUniqueKeyPair((TRUE == data[getEntry(TEST_MODE)]) ? true : false, scratchPad); // Create signedMac short signedMac = diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSemanticTag.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSemanticTag.java index 6165c31..07b2675 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSemanticTag.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSemanticTag.java @@ -4,6 +4,11 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.Util; +/** + * KMSemanticTag corresponds to CBOR type of tagged item. The structure is defined as struct{byte + * SEMANTIC_TAG_TYPE; short length; tag, short ptr }. Tag is INTEGER_TYPE and the possible values + * are defined here https://www.rfc-editor.org/rfc/rfc7049#section-2.4 + */ public class KMSemanticTag extends KMType { public static final short COSE_MAC_SEMANTIC_TAG = (short) 0x0011; diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSimpleValue.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSimpleValue.java index 14b7bb8..6dffd73 100644 --- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSimpleValue.java +++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMSimpleValue.java @@ -4,6 +4,10 @@ import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.Util; +/** + * KMSimpleValue corresponds to CBOR type of Simple value. It holds either true, false or NULL + * values. The structure is defined as struct{byte SIMPLE_VALUE_TYPE; short length; simple value } + */ public class KMSimpleValue extends KMType { public static final byte FALSE = (byte) 20; |