diff --git a/Applet/JavaCardKeymaster.opt b/Applet/AndroidSEProvider/AndroidSE_3_0_5.opt similarity index 61% rename from Applet/JavaCardKeymaster.opt rename to Applet/AndroidSEProvider/AndroidSE_3_0_5.opt index 77c1931e..ba998254 100644 --- a/Applet/JavaCardKeymaster.opt +++ b/Applet/AndroidSEProvider/AndroidSE_3_0_5.opt @@ -1,5 +1,5 @@ -out EXP JCA CAP --exportpath api_export_files_3.1.0 --applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 com.android.javacard.keymaster.KMKeymasterApplet +-exportpath ../../AndroidSEProvider/api_export_files_3.0.5 +-applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 com.android.javacard.keymaster.KMAndroidSEApplet com.android.javacard.keymaster 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1 1.0 diff --git a/Applet/AndroidSEProvider/AndroidSE_3_1_0.opt b/Applet/AndroidSEProvider/AndroidSE_3_1_0.opt new file mode 100644 index 00000000..3de07eb5 --- /dev/null +++ b/Applet/AndroidSEProvider/AndroidSE_3_1_0.opt @@ -0,0 +1,5 @@ +-out EXP JCA CAP +-exportpath ../../AndroidSEProvider/api_export_files_3.1.0 +-applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 com.android.javacard.keymaster.KMAndroidSEApplet +com.android.javacard.keymaster +0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1 1.0 diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/java/io/javacard/io.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/java/io/javacard/io.exp new file mode 100644 index 00000000..931133af Binary files /dev/null and b/Applet/AndroidSEProvider/api_export_files_3.0.5/java/io/javacard/io.exp differ diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/java/lang/javacard/lang.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/java/lang/javacard/lang.exp new file mode 100644 index 00000000..f3498186 Binary files /dev/null and b/Applet/AndroidSEProvider/api_export_files_3.0.5/java/lang/javacard/lang.exp differ diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/java/rmi/javacard/rmi.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/java/rmi/javacard/rmi.exp new file mode 100644 index 00000000..209cdf37 Binary files /dev/null and b/Applet/AndroidSEProvider/api_export_files_3.0.5/java/rmi/javacard/rmi.exp differ diff --git a/Applet/api_export_files_3.0.5/javacard/framework/javacard/framework.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/javacard/framework.exp similarity index 76% rename from Applet/api_export_files_3.0.5/javacard/framework/javacard/framework.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/javacard/framework.exp index f604261a..fd14eac7 100644 Binary files a/Applet/api_export_files_3.0.5/javacard/framework/javacard/framework.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/javacard/framework.exp differ diff --git a/Applet/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp similarity index 76% rename from Applet/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp index e83ae8a4..8fbef2f6 100644 Binary files a/Applet/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp differ diff --git a/Applet/api_export_files_3.0.5/javacard/security/javacard/security.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/security/javacard/security.exp similarity index 67% rename from Applet/api_export_files_3.0.5/javacard/security/javacard/security.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/security/javacard/security.exp index 9b2b8d44..39e57627 100644 Binary files a/Applet/api_export_files_3.0.5/javacard/security/javacard/security.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/security/javacard/security.exp differ diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp new file mode 100644 index 00000000..c9183d4f Binary files /dev/null and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp differ diff --git a/Applet/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp similarity index 52% rename from Applet/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp index cf2fc718..6a1e9e1e 100644 Binary files a/Applet/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp similarity index 60% rename from Applet/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp index f1779d01..fb46fa30 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp similarity index 68% rename from Applet/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp index 057adb00..88527985 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp similarity index 92% rename from Applet/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp index b6f6b2f8..e1ff132d 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/external/javacard/external.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/external/javacard/external.exp similarity index 67% rename from Applet/api_export_files_3.0.5/javacardx/external/javacard/external.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/external/javacard/external.exp index cd85799e..4af91e53 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/external/javacard/external.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/external/javacard/external.exp differ diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp similarity index 63% rename from Applet/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp index af2f608c..89a1ac6c 100644 Binary files a/Applet/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp similarity index 67% rename from Applet/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp index ef6c5cb7..7a3b73c3 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp similarity index 72% rename from Applet/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp index 5a6d027c..58495fb0 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp differ diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp new file mode 100644 index 00000000..881a9612 Binary files /dev/null and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp differ diff --git a/Applet/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp similarity index 68% rename from Applet/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp index 25358d9d..a1ce7e96 100644 Binary files a/Applet/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp differ diff --git a/Applet/api_export_files_3.1.0/javacardx/security/javacard/security.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/security/javacard/security.exp similarity index 59% rename from Applet/api_export_files_3.1.0/javacardx/security/javacard/security.exp rename to Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/security/javacard/security.exp index 30b3ed6e..5153a68d 100644 Binary files a/Applet/api_export_files_3.1.0/javacardx/security/javacard/security.exp and b/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/security/javacard/security.exp differ diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.exp b/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.exp new file mode 100644 index 00000000..110117b2 Binary files /dev/null and b/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.exp differ diff --git a/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.jca b/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.jca new file mode 100644 index 00000000..9bb1e3b8 --- /dev/null +++ b/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.jca @@ -0,0 +1,245 @@ +// converted by version 1.3 +// on Wed Feb 14 10:43:54 CET 2018 + +.package org/globalplatform/upgrade { + .aid 0xA0:0x0:0x0:0x1:0x51:0x7; + .version 1.1; + + .imports { + 0xA0:0x0:0x0:0x0:0x62:0x0:0x1 1.0; //java/lang + } + + .constantPool { + // 0 + staticMethodRef 0.0.0()V; // java/lang/Object.()V + } + + .interface public abstract Element 0 { + + .fields { + public static final byte TYPE_SIMPLE = 1; // B + public static final byte TYPE_MAPPED = 2; // B + public static final short SIZE_BOOLEAN = 1; // S + public static final short SIZE_BYTE = 1; // S + public static final short SIZE_SHORT = 2; // S + } + + .method public abstract write(Z)Lorg/globalplatform/upgrade/Element; 0 { + } + + .method public abstract write(B)Lorg/globalplatform/upgrade/Element; 1 { + } + + .method public abstract write(S)Lorg/globalplatform/upgrade/Element; 2 { + } + + .method public abstract write(Ljava/lang/Object;)Lorg/globalplatform/upgrade/Element; 3 { + .descriptor Ljava/lang/Object; 0.0; + + } + + .method public abstract canWriteBoolean()S 4 { + } + + .method public abstract canWriteByte()S 5 { + } + + .method public abstract canWriteShort()S 6 { + } + + .method public abstract canWriteObject()S 7 { + } + + .method public abstract initRead()V 8 { + } + + .method public abstract readBoolean()Z 9 { + } + + .method public abstract readByte()B 10 { + } + + .method public abstract readShort()S 11 { + } + + .method public abstract readObject()Ljava/lang/Object; 12 { + .descriptor Ljava/lang/Object; 0.0; + + } + + .method public abstract canReadBoolean()S 13 { + } + + .method public abstract canReadByte()S 14 { + } + + .method public abstract canReadShort()S 15 { + } + + .method public abstract canReadObject()S 16 { + } + + } + + .interface public abstract MappedElement 1 { + + .superInterfaces { + Element; + } + + .method public abstract write(Z)Lorg/globalplatform/upgrade/Element; 0 { + } + + .method public abstract write(B)Lorg/globalplatform/upgrade/Element; 1 { + } + + .method public abstract write(S)Lorg/globalplatform/upgrade/Element; 2 { + } + + .method public abstract write(Ljava/lang/Object;)Lorg/globalplatform/upgrade/Element; 3 { + .descriptor Ljava/lang/Object; 0.0; + + } + + .method public abstract canWriteBoolean()S 4 { + } + + .method public abstract canWriteByte()S 5 { + } + + .method public abstract canWriteShort()S 6 { + } + + .method public abstract canWriteObject()S 7 { + } + + .method public abstract initRead()V 8 { + } + + .method public abstract readBoolean()Z 9 { + } + + .method public abstract readByte()B 10 { + } + + .method public abstract readShort()S 11 { + } + + .method public abstract readObject()Ljava/lang/Object; 12 { + .descriptor Ljava/lang/Object; 0.0; + + } + + .method public abstract canReadBoolean()S 13 { + } + + .method public abstract canReadByte()S 14 { + } + + .method public abstract canReadShort()S 15 { + } + + .method public abstract canReadObject()S 16 { + } + + .method public abstract getMappedObject()Ljava/lang/Object; 17 { + .descriptor Ljava/lang/Object; 0.0; + + } + + .method public abstract setMappedObject(Ljava/lang/Object;)Lorg/globalplatform/upgrade/Element; 18 { + .descriptor Ljava/lang/Object; 0.0; + + } + + } + + .interface public abstract OnUpgradeListener 2 { + + .method public abstract onSave()Lorg/globalplatform/upgrade/Element; 0 { + } + + .method public abstract onCleanup()V 1 { + } + + .method public abstract onRestore(Lorg/globalplatform/upgrade/Element;)V 2 { + } + + .method public abstract onConsolidate()V 3 { + } + + } + + .class public final UpgradeManager 3 extends 0.0 { // extends java/lang/Object + + .publicMethodTable 1 { + equals(Ljava/lang/Object;)Z; + } + + .packageMethodTable 0 { + } + + .method private ()V { + .stack 1; + .locals 0; + + L0: aload_0; + invokespecial 0; // java/lang/Object.()V + return; + } + + .method public static isUpgrading()Z 0 { + .stack 1; + .locals 0; + + L0: sconst_0; + sreturn; + } + + .method public static getPreviousPackageVersion()S 1 { + .stack 1; + .locals 0; + + L0: sconst_0; + sreturn; + } + + .method public static checkPreviousPackageAID([BSB)Z 2 { + .stack 1; + .locals 0; + + L0: sconst_0; + sreturn; + } + + .method public static createElement(BSS)Lorg/globalplatform/upgrade/Element; 3 { + .stack 1; + .locals 0; + + L0: aconst_null; + areturn; + } + + .method public static matchMappedElement(Ljava/lang/Object;)Lorg/globalplatform/upgrade/MappedElement; 4 { + .stack 1; + .locals 0; + + .descriptor Ljava/lang/Object; 0.0; + + L0: aconst_null; + areturn; + } + + .method public static nonNullReference()Ljava/lang/Object; 5 { + .stack 1; + .locals 0; + + .descriptor Ljava/lang/Object; 0.0; + + L0: aconst_null; + areturn; + } + + } + +} diff --git a/Applet/api_export_files_3.0.5/java/io/javacard/io.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/java/io/javacard/io.exp similarity index 100% rename from Applet/api_export_files_3.0.5/java/io/javacard/io.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/java/io/javacard/io.exp diff --git a/Applet/api_export_files_3.0.5/java/lang/javacard/lang.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/java/lang/javacard/lang.exp similarity index 100% rename from Applet/api_export_files_3.0.5/java/lang/javacard/lang.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/java/lang/javacard/lang.exp diff --git a/Applet/api_export_files_3.0.5/java/rmi/javacard/rmi.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/java/rmi/javacard/rmi.exp similarity index 100% rename from Applet/api_export_files_3.0.5/java/rmi/javacard/rmi.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/java/rmi/javacard/rmi.exp diff --git a/Applet/api_export_files_3.1.0/javacard/framework/javacard/framework.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/javacard/framework.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacard/framework/javacard/framework.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/javacard/framework.exp diff --git a/Applet/api_export_files_3.1.0/javacard/framework/service/javacard/service.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/service/javacard/service.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacard/framework/service/javacard/service.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/service/javacard/service.exp diff --git a/Applet/api_export_files_3.1.0/javacard/security/javacard/security.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/security/javacard/security.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacard/security/javacard/security.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/security/javacard/security.exp diff --git a/Applet/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp similarity index 100% rename from Applet/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp diff --git a/Applet/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp similarity index 100% rename from Applet/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/biometry/javacard/biometry.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry/javacard/biometry.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/biometry/javacard/biometry.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry/javacard/biometry.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/biometry1toN/javacard/biometry1toN.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry1toN/javacard/biometry1toN.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/biometry1toN/javacard/biometry1toN.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry1toN/javacard/biometry1toN.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/crypto/javacard/crypto.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/crypto/javacard/crypto.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/crypto/javacard/crypto.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/crypto/javacard/crypto.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/external/javacard/external.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/external/javacard/external.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/external/javacard/external.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/external/javacard/external.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/event/javacard/event.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/event/javacard/event.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/event/javacard/event.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/event/javacard/event.exp diff --git a/Applet/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp similarity index 100% rename from Applet/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/nio/javacard/nio.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/nio/javacard/nio.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/nio/javacard/nio.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/nio/javacard/nio.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/string/javacard/string.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/string/javacard/string.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/string/javacard/string.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/string/javacard/string.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/time/javacard/time.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/time/javacard/time.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/time/javacard/time.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/time/javacard/time.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/tlv/javacard/tlv.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/tlv/javacard/tlv.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/tlv/javacard/tlv.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/tlv/javacard/tlv.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/util/intx/javacard/intx.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/intx/javacard/intx.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/util/intx/javacard/intx.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/intx/javacard/intx.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/framework/util/javacard/util.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/javacard/util.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/framework/util/javacard/util.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/javacard/util.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/security/cert/javacard/cert.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/cert/javacard/cert.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/security/cert/javacard/cert.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/cert/javacard/cert.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/security/derivation/javacard/derivation.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/derivation/javacard/derivation.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/security/derivation/javacard/derivation.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/derivation/javacard/derivation.exp diff --git a/Applet/api_export_files_3.0.5/javacardx/security/javacard/security.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/javacard/security.exp similarity index 100% rename from Applet/api_export_files_3.0.5/javacardx/security/javacard/security.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/javacard/security.exp diff --git a/Applet/api_export_files_3.1.0/javacardx/security/util/javacard/util.exp b/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/util/javacard/util.exp similarity index 100% rename from Applet/api_export_files_3.1.0/javacardx/security/util/javacard/util.exp rename to Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/util/javacard/util.exp diff --git a/Applet/AndroidSEProvider/build.xml b/Applet/AndroidSEProvider/build.xml new file mode 100644 index 00000000..04b1dee6 --- /dev/null +++ b/Applet/AndroidSEProvider/build.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Applet/lib/gpapi-upgrade.jar b/Applet/AndroidSEProvider/lib/gpapi-upgrade.jar similarity index 100% rename from Applet/lib/gpapi-upgrade.jar rename to Applet/AndroidSEProvider/lib/gpapi-upgrade.jar diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java new file mode 100644 index 00000000..1d24f580 --- /dev/null +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java @@ -0,0 +1,71 @@ +package com.android.javacard.keymaster; + +import org.globalplatform.upgrade.Element; +import org.globalplatform.upgrade.OnUpgradeListener; +import org.globalplatform.upgrade.UpgradeManager; + +public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeListener { + + KMAndroidSEApplet(){ + super(new KMAndroidSEProvider(true)); + } + /** + * Installs this applet. + * + * @param bArray the array containing installation parameters + * @param bOffset the starting offset in bArray + * @param bLength the length in bytes of the parameter data in bArray + */ + public static void install(byte[] bArray, short bOffset, byte bLength) { + new KMAndroidSEApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]); + } + + @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; + } + + private short computePrimitveDataSize() { + // provisionStatus + keymasterState + return (short) 2; + } + + private short computeObjectCount() { + return (short) 0; + } +} + diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/AndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java similarity index 99% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/AndroidSEProvider.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index d85dd781..db1cd7f5 100644 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/AndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -35,7 +35,7 @@ import javacardx.crypto.AEADCipher; import javacardx.crypto.Cipher; -public class AndroidSEProvider implements KMSEProvider { +public class KMAndroidSEProvider implements KMSEProvider { // static final variables // -------------------------------------------------------------- // P-256 Curve Parameters @@ -157,13 +157,13 @@ public class AndroidSEProvider implements KMSEProvider { //For storing root certificate and intermediate certificates. private byte[] certificateChain; - private static AndroidSEProvider androidSEProvider = null; + private static KMAndroidSEProvider androidSEProvider = null; - public static AndroidSEProvider getInstance() { + public static KMAndroidSEProvider getInstance() { return androidSEProvider; } - public AndroidSEProvider(boolean isUpgrading) { + public KMAndroidSEProvider(boolean isUpgrading) { // Re-usable AES,DES and HMAC keys in persisted memory. aesKeys = new AESKey[2]; aesKeys[KEYSIZE_128_OFFSET] = (AESKey) KeyBuilder.buildKey( diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java similarity index 99% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMAttestationCertImpl.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 77a97b1e..1e50f620 100644 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -889,7 +889,7 @@ public void build() { tbsLength = (short) (tbsLength - tbsOffset); pushSequenceHeader((short) (last - stackPtr)); certStart = stackPtr; - short sigLen = AndroidSEProvider.getInstance() + short sigLen = KMAndroidSEProvider.getInstance() .ecSign256( KMByteBlob.cast(signPriv).getBuffer(), KMByteBlob.cast(signPriv).getStartOff(), @@ -933,7 +933,7 @@ public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff, scratchPadOff++; timeOffset = KMByteBlob.instance((short) 32); - appIdOff = AndroidSEProvider.getInstance().hmacSign(key, keyOff, keyLen, + appIdOff = KMAndroidSEProvider.getInstance().hmacSign(key, keyOff, keyLen, scratchPad, /* data */ temp, /* data start */ scratchPadOff, /* data length */ diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java similarity index 86% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java index 31abede5..727641c0 100644 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java @@ -75,16 +75,16 @@ public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) CryptoException.throwIt(CryptoException.ILLEGAL_USE); // add zeros to the left if (i1 < MAX_NO_DIGEST_MSG_LEN) { - Util.arrayFillNonAtomic(AndroidSEProvider.getInstance().tmpArray, + Util.arrayFillNonAtomic(KMAndroidSEProvider.getInstance().tmpArray, (short) 0, (short) MAX_NO_DIGEST_MSG_LEN, (byte) 0); } Util.arrayCopyNonAtomic(bytes, i, - AndroidSEProvider.getInstance().tmpArray, + KMAndroidSEProvider.getInstance().tmpArray, (short) (MAX_NO_DIGEST_MSG_LEN - i1), i1); - return inst.signPreComputedHash(AndroidSEProvider.getInstance().tmpArray, + return inst.signPreComputedHash(KMAndroidSEProvider.getInstance().tmpArray, (short) 0, (short) MAX_NO_DIGEST_MSG_LEN, bytes1, i2); } finally { - AndroidSEProvider.getInstance().clean(); + KMAndroidSEProvider.getInstance().clean(); } } @@ -102,17 +102,17 @@ public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, CryptoException.throwIt(CryptoException.ILLEGAL_USE); // add zeros to the left if (i1 < MAX_NO_DIGEST_MSG_LEN) { - Util.arrayFillNonAtomic(AndroidSEProvider.getInstance().tmpArray, + Util.arrayFillNonAtomic(KMAndroidSEProvider.getInstance().tmpArray, (short) 0, (short) MAX_NO_DIGEST_MSG_LEN, (byte) 0); } Util.arrayCopyNonAtomic(bytes, i, - AndroidSEProvider.getInstance().tmpArray, + KMAndroidSEProvider.getInstance().tmpArray, (short) (MAX_NO_DIGEST_MSG_LEN - i1), i1); return inst.verifyPreComputedHash( - AndroidSEProvider.getInstance().tmpArray, (short) 0, + KMAndroidSEProvider.getInstance().tmpArray, (short) 0, (short) MAX_NO_DIGEST_MSG_LEN, bytes1, i2, i3); } finally { - AndroidSEProvider.getInstance().clean(); + KMAndroidSEProvider.getInstance().clean(); } } diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMInstance.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMInstance.java similarity index 100% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMInstance.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMInstance.java diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java similarity index 92% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMOperationImpl.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index 2469dd0c..b1f48827 100644 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -103,7 +103,7 @@ public short update(byte[] inputDataBuf, short inputDataStart, @Override public short finish(byte[] inputDataBuf, short inputDataStart, short inputDataLen, byte[] outputDataBuf, short outputDataStart) { - byte[] tmpArray = AndroidSEProvider.getInstance().tmpArray; + byte[] tmpArray = KMAndroidSEProvider.getInstance().tmpArray; short len = 0; try { if (cipherAlg == KMType.AES && blockMode == KMType.GCM) { @@ -175,8 +175,8 @@ public short finish(byte[] inputDataBuf, short inputDataStart, } } } finally { - AndroidSEProvider.getInstance().clean(); - AndroidSEProvider.getInstance().releaseCipherInstance(cipher); + KMAndroidSEProvider.getInstance().clean(); + KMAndroidSEProvider.getInstance().releaseCipherInstance(cipher); resetCipher(); } return len; @@ -190,7 +190,7 @@ public short sign(byte[] inputDataBuf, short inputDataStart, len = signature.sign(inputDataBuf, inputDataStart, inputDataLength, signBuf, signStart); } finally { - AndroidSEProvider.getInstance().releaseSignatureInstance(signature); + KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature); signature = null; } return len; @@ -204,7 +204,7 @@ public boolean verify(byte[] inputDataBuf, short inputDataStart, ret = signature.verify(inputDataBuf, inputDataStart, inputDataLength, signBuf, signStart, signLength); } finally { - AndroidSEProvider.getInstance().releaseSignatureInstance(signature); + KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature); signature = null; } return ret; @@ -214,14 +214,14 @@ public boolean verify(byte[] inputDataBuf, short inputDataStart, public void abort() { // do nothing if (cipher != null) { - AndroidSEProvider.getInstance().releaseCipherInstance(cipher); + KMAndroidSEProvider.getInstance().releaseCipherInstance(cipher); resetCipher(); } if (signature != null) { - AndroidSEProvider.getInstance().releaseSignatureInstance(signature); + KMAndroidSEProvider.getInstance().releaseSignatureInstance(signature); signature = null; } - AndroidSEProvider.getInstance().releaseOperationInstance(this); + KMAndroidSEProvider.getInstance().releaseOperationInstance(this); } @Override diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java similarity index 95% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java index eb799dfe..71c36a3d 100644 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java @@ -68,8 +68,8 @@ public void update(byte[] bytes, short i, short i1) throws CryptoException { @Override public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) throws CryptoException { - padData(bytes, i, i1, AndroidSEProvider.getInstance().tmpArray, (short) 0); - return inst.doFinal(AndroidSEProvider.getInstance().tmpArray, (short) 0, + padData(bytes, i, i1, KMAndroidSEProvider.getInstance().tmpArray, (short) 0); + return inst.doFinal(KMAndroidSEProvider.getInstance().tmpArray, (short) 0, (short) 256, bytes1, i2); } diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMRsaOAEPEncoding.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java similarity index 98% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMRsaOAEPEncoding.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java index aa35793f..d4f4cb83 100644 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMRsaOAEPEncoding.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsaOAEPEncoding.java @@ -5,7 +5,6 @@ import javacard.security.CryptoException; import javacard.security.Key; import javacard.security.MessageDigest; -import javacard.security.RSAPrivateKey; import javacardx.crypto.Cipher; public class KMRsaOAEPEncoding extends Cipher { @@ -165,7 +164,7 @@ private void I2OS(short i, byte[] out, short offset) { private short rsaOAEPDecode(byte[] encodedMsg, short encodedMsgOff, short encodedMsgLen, byte[] msg, short offset) { MessageDigest.OneShot md = null; - byte[] tmpArray = AndroidSEProvider.getInstance().tmpArray; + byte[] tmpArray = KMAndroidSEProvider.getInstance().tmpArray; try { short hLen = getDigestLength(); @@ -238,7 +237,7 @@ private short rsaOAEPDecode(byte[] encodedMsg, short encodedMsgOff, if (md != null) md.close(); Util.arrayFillNonAtomic(tmpArray, (short) 0, - AndroidSEProvider.TMP_ARRAY_SIZE, (byte) 0); + KMAndroidSEProvider.TMP_ARRAY_SIZE, (byte) 0); } } } \ No newline at end of file diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMUtils.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java similarity index 100% rename from Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMUtils.java rename to Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java diff --git a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMSEProviderImpl.java b/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMSEProviderImpl.java deleted file mode 100644 index 11778a7d..00000000 --- a/Applet/Applet/AndroidSEProvider/com/android/javacard/keymaster/KMSEProviderImpl.java +++ /dev/null @@ -1,8 +0,0 @@ - -package com.android.javacard.keymaster; - -public class KMSEProviderImpl { - public static KMSEProvider instance(boolean isUpgrading){ - return new AndroidSEProvider(isUpgrading); - } -} diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMSEProviderImpl.java b/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMSEProviderImpl.java deleted file mode 100644 index 43eb2f94..00000000 --- a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMSEProviderImpl.java +++ /dev/null @@ -1,9 +0,0 @@ - -package com.android.javacard.keymaster; - -public class KMSEProviderImpl { - public static KMSEProvider instance(boolean isUpgrading) { - //Ignore isUpgrading flag as JCardSimulator does not support upgrade. - return new KMJcardSimulator(); - } -} diff --git a/Applet/JCardSimProvider/build.xml b/Applet/JCardSimProvider/build.xml new file mode 100644 index 00000000..58343402 --- /dev/null +++ b/Applet/JCardSimProvider/build.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Applet/JCardSimProvider/lib/gpapi-upgrade.jar b/Applet/JCardSimProvider/lib/gpapi-upgrade.jar new file mode 100644 index 00000000..e4814bde Binary files /dev/null and b/Applet/JCardSimProvider/lib/gpapi-upgrade.jar differ diff --git a/Applet/lib/hamcrest-core-1.3.jar b/Applet/JCardSimProvider/lib/hamcrest-core-1.3.jar similarity index 100% rename from Applet/lib/hamcrest-core-1.3.jar rename to Applet/JCardSimProvider/lib/hamcrest-core-1.3.jar diff --git a/Applet/lib/jcardsim-3.0.5-SNAPSHOT.jar b/Applet/JCardSimProvider/lib/jcardsim-3.0.5-SNAPSHOT.jar similarity index 100% rename from Applet/lib/jcardsim-3.0.5-SNAPSHOT.jar rename to Applet/JCardSimProvider/lib/jcardsim-3.0.5-SNAPSHOT.jar diff --git a/Applet/lib/junit-4.13.jar b/Applet/JCardSimProvider/lib/junit-4.13.jar similarity index 100% rename from Applet/lib/junit-4.13.jar rename to Applet/JCardSimProvider/lib/junit-4.13.jar diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java similarity index 99% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMAttestationCertImpl.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 9e046264..136ec4ba 100644 --- a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -889,7 +889,7 @@ public void build() { tbsLength = (short) (tbsLength - tbsOffset); pushSequenceHeader((short) (last - stackPtr)); certStart = stackPtr; - short sigLen = KMJcardSimulator.getInstance() + short sigLen = KMJCardSimulator.getInstance() .ecSign256( KMByteBlob.cast(signPriv).getBuffer(), KMByteBlob.cast(signPriv).getStartOff(), @@ -933,7 +933,7 @@ public KMAttestationCert makeUniqueId(byte[] scratchPad, short scratchPadOff, scratchPadOff++; timeOffset = KMByteBlob.instance((short) 32); - appIdOff = KMJcardSimulator.getInstance().hmacSign(key, keyOff, keyLen, + appIdOff = KMJCardSimulator.getInstance().hmacSign(key, keyOff, keyLen, scratchPad, /* data */ temp, /* data start */ scratchPadOff, /* data length */ diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMCipher.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java similarity index 97% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMCipher.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java index b599c003..145fea9d 100644 --- a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMCipher.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java @@ -1,51 +1,51 @@ -package com.android.javacard.keymaster; - -public abstract class KMCipher { - /* - public static final byte CIPHER_RSA = 7; - public static final short PAD_PKCS1_OAEP = 9; - public static final short PAD_PKCS1_OAEP_SHA224 = 13; - public static final byte PAD_PKCS1_OAEP_SHA256 = 14; - public static final short PAD_PKCS1_OAEP_SHA384 = 15; - public static final short PAD_PKCS1_OAEP_SHA512 = 16; - public static final short PAD_NOPAD = 1; - public static final short PAD_PKCS1_PSS = 8; - public static final short PAD_NULL = 0; - public static final short PAD_PKCS7 = 31; // Not supported in javacard - public static final short ALG_DES_CBC_NOPAD = 1; - public static final short ALG_DES_ECB_NOPAD = 5; - public static final short ALG_AES_BLOCK_128_CBC_NOPAD= 13; - public static final short ALG_AES_BLOCK_128_ECB_NOPAD = 14; - public static final short ALG_AES_GCM = -13; - public static final short MODE_ENCRYPT = 2; - public static final short MODE_DECRYPT = 1; - public static final short PAD_PKCS1 = 7; - public static final short AES_BLOCK_SIZE = 16; - public static final short DES_BLOCK_SIZE = 8; - public static final short ALG_AES_CTR = -16; - - */ - public static final short SUN_JCE = 0xE9; - - public abstract short doFinal(byte[] buffer, short startOff, short length, byte[] scratchPad, short i); - - public abstract short update(byte[] buffer, short startOff, short length, byte[] scratchPad, short i); - - public abstract void updateAAD(byte[] buffer, short startOff, short length); - - public abstract short getBlockMode(); - - public abstract void setBlockMode(short mode); - - public abstract short getPaddingAlgorithm(); - - public abstract short getCipherAlgorithm(); - - public abstract void setPaddingAlgorithm(short alg); - - public abstract void setCipherAlgorithm(short alg); - - public abstract short getCipherProvider(); - - public abstract short getAesGcmOutputSize(short len, short macLength); -} +package com.android.javacard.keymaster; + +public abstract class KMCipher { + /* + public static final byte CIPHER_RSA = 7; + public static final short PAD_PKCS1_OAEP = 9; + public static final short PAD_PKCS1_OAEP_SHA224 = 13; + public static final byte PAD_PKCS1_OAEP_SHA256 = 14; + public static final short PAD_PKCS1_OAEP_SHA384 = 15; + public static final short PAD_PKCS1_OAEP_SHA512 = 16; + public static final short PAD_NOPAD = 1; + public static final short PAD_PKCS1_PSS = 8; + public static final short PAD_NULL = 0; + public static final short PAD_PKCS7 = 31; // Not supported in javacard + public static final short ALG_DES_CBC_NOPAD = 1; + public static final short ALG_DES_ECB_NOPAD = 5; + public static final short ALG_AES_BLOCK_128_CBC_NOPAD= 13; + public static final short ALG_AES_BLOCK_128_ECB_NOPAD = 14; + public static final short ALG_AES_GCM = -13; + public static final short MODE_ENCRYPT = 2; + public static final short MODE_DECRYPT = 1; + public static final short PAD_PKCS1 = 7; + public static final short AES_BLOCK_SIZE = 16; + public static final short DES_BLOCK_SIZE = 8; + public static final short ALG_AES_CTR = -16; + + */ + public static final short SUN_JCE = 0xE9; + + public abstract short doFinal(byte[] buffer, short startOff, short length, byte[] scratchPad, short i); + + public abstract short update(byte[] buffer, short startOff, short length, byte[] scratchPad, short i); + + public abstract void updateAAD(byte[] buffer, short startOff, short length); + + public abstract short getBlockMode(); + + public abstract void setBlockMode(short mode); + + public abstract short getPaddingAlgorithm(); + + public abstract short getCipherAlgorithm(); + + public abstract void setPaddingAlgorithm(short alg); + + public abstract void setCipherAlgorithm(short alg); + + public abstract short getCipherProvider(); + + public abstract short getAesGcmOutputSize(short len, short macLength); +} diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMCipherImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java similarity index 97% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMCipherImpl.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java index 65ebfad0..ea65a94c 100644 --- a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMCipherImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java @@ -1,220 +1,220 @@ -package com.android.javacard.keymaster; - -import javacard.framework.Util; -import javacard.security.CryptoException; -import javacardx.crypto.Cipher; -import javax.crypto.AEADBadTagException; -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.ShortBufferException; - - -public class KMCipherImpl extends KMCipher{ - private Cipher cipher; - private javax.crypto.Cipher sunCipher; - private short cipherAlg; - private short padding; - private short mode; - private boolean verificationFlag; - private short blockMode; - KMCipherImpl(Cipher c){ - cipher = c; - } - KMCipherImpl(javax.crypto.Cipher c){ - sunCipher = c; - } - - @Override - public short doFinal(byte[] buffer, short startOff, short length, byte[] scratchPad, short i){ - if(cipherAlg == KMType.RSA && padding == KMType.RSA_OAEP){ - try { - return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); - } catch (ShortBufferException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (BadPaddingException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - }else if(cipherAlg == KMType.AES && blockMode == KMType.GCM){ - try { - return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); - } catch (AEADBadTagException e) { - e.printStackTrace(); - verificationFlag = false; - KMException.throwIt(KMError.VERIFICATION_FAILED); - } catch (ShortBufferException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (IllegalBlockSizeException e) { - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (BadPaddingException e) { - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - } else if(cipherAlg == KMType.AES && blockMode == KMType.CTR){ - try { - return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); - } catch (ShortBufferException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (IllegalBlockSizeException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (BadPaddingException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - } else{ - if(cipherAlg == KMType.RSA && padding == KMType.PADDING_NONE && mode == KMType.ENCRYPT ){ - // Length cannot be greater then key size according to JcardSim - if(length >= 256) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); - // make input equal to 255 bytes - byte[] tmp = new byte[255]; - Util.arrayFillNonAtomic(tmp,(short)0,(short)255, (byte)0); - Util.arrayCopyNonAtomic( - buffer, - startOff, - tmp, (short)(255 - length),length); - startOff = 0; - length = 255; - buffer = tmp; - - }else if((cipherAlg == KMType.DES || cipherAlg == KMType.AES) && padding ==KMType.PKCS7 && mode == KMType.ENCRYPT){ - byte blkSize = 16; - byte paddingBytes; - short len = length; - if (cipherAlg == KMType.DES) blkSize = 8; - // padding bytes - if (len % blkSize == 0) paddingBytes = blkSize; - else paddingBytes = (byte) (blkSize - (len % blkSize)); - // final len with padding - len = (short) (len + paddingBytes); - // intermediate buffer to copy input data+padding - byte[] tmp = new byte[len]; - // fill in the padding - Util.arrayFillNonAtomic(tmp, (short) 0, len, paddingBytes); - // copy the input data - Util.arrayCopyNonAtomic(buffer,startOff,tmp,(short)0,length); - buffer = tmp; - length = len; - startOff = 0; - } - short len = cipher.doFinal(buffer, startOff, length, scratchPad, i); - // JCard Sim removes leading zeros during decryption in case of no padding - so add that back. - if (cipherAlg == KMType.RSA && padding == KMType.PADDING_NONE && mode == KMType.DECRYPT && len < 256) { - byte[] tempBuf = new byte[256]; - Util.arrayFillNonAtomic(tempBuf, (short) 0, (short) 256, (byte) 0); - Util.arrayCopyNonAtomic(scratchPad, (short) 0, tempBuf, (short) (i + 256 - len), len); - Util.arrayCopyNonAtomic(tempBuf, (short) 0, scratchPad, i, (short) 256); - len = 256; - }else if((cipherAlg == KMType.AES || cipherAlg == KMType.DES) // PKCS7 - && padding == KMType.PKCS7 - && mode == KMType.DECRYPT){ - byte blkSize = 16; - if (cipherAlg == KMType.DES) blkSize = 8; - if(len >0) { - //verify if padding is corrupted. - byte paddingByte = scratchPad[i+len -1]; - //padding byte always should be <= block size - if((short)paddingByte > blkSize || - (short)paddingByte <= 0) KMException.throwIt(KMError.INVALID_ARGUMENT); - len = (short)(len - (short)paddingByte);// remove the padding bytes - } - } - return len; - } - return KMType.INVALID_VALUE; - } - - @Override - public short getCipherAlgorithm() { - return cipherAlg; - } - - @Override - public void setCipherAlgorithm(short alg) { - cipherAlg = alg; - } - - @Override - public short update(byte[] buffer, short startOff, short length, byte[] scratchPad, short i) { - if(cipherAlg == KMType.AES && (blockMode == KMType.GCM || blockMode == KMType.CTR)){ - try { - return (short)sunCipher.update(buffer,startOff,length,scratchPad,i); - } catch (ShortBufferException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (IllegalStateException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - } else{ - return cipher.update(buffer, startOff, length, scratchPad, i); - } - return KMType.INVALID_VALUE; - } - - @Override - public void updateAAD(byte[] buffer, short startOff, short length) { - try { - sunCipher.updateAAD(buffer,startOff,length); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (IllegalStateException e) { - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } catch (UnsupportedOperationException e) { - CryptoException.throwIt(CryptoException.ILLEGAL_USE); - } - } - - @Override - public short getPaddingAlgorithm() { - return padding; - } - - @Override - public void setPaddingAlgorithm(short alg) { - padding = alg; - } - - @Override - public void setBlockMode(short mode){ - blockMode = mode; - } - - @Override - public short getBlockMode(){ - return blockMode; - } - - public short getMode() { - return mode; - } - - public void setMode(short mode) { - this.mode = mode; - } - - @Override - public short getCipherProvider() { - return KMCipher.SUN_JCE; - } - - @Override - public short getAesGcmOutputSize(short len, short macLength) { - if (sunCipher != null) { - return (short) sunCipher.getOutputSize(len); - } else { - if (mode == KMType.ENCRYPT) { - return (short) (len + macLength); - } else { - return (short) (len - macLength); - } - } - } - -} +package com.android.javacard.keymaster; + +import javacard.framework.Util; +import javacard.security.CryptoException; +import javacardx.crypto.Cipher; +import javax.crypto.AEADBadTagException; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.ShortBufferException; + + +public class KMCipherImpl extends KMCipher{ + private Cipher cipher; + private javax.crypto.Cipher sunCipher; + private short cipherAlg; + private short padding; + private short mode; + private boolean verificationFlag; + private short blockMode; + KMCipherImpl(Cipher c){ + cipher = c; + } + KMCipherImpl(javax.crypto.Cipher c){ + sunCipher = c; + } + + @Override + public short doFinal(byte[] buffer, short startOff, short length, byte[] scratchPad, short i){ + if(cipherAlg == KMType.RSA && padding == KMType.RSA_OAEP){ + try { + return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); + } catch (ShortBufferException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (BadPaddingException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + }else if(cipherAlg == KMType.AES && blockMode == KMType.GCM){ + try { + return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); + } catch (AEADBadTagException e) { + e.printStackTrace(); + verificationFlag = false; + KMException.throwIt(KMError.VERIFICATION_FAILED); + } catch (ShortBufferException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (IllegalBlockSizeException e) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (BadPaddingException e) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + } else if(cipherAlg == KMType.AES && blockMode == KMType.CTR){ + try { + return (short)sunCipher.doFinal(buffer,startOff,length,scratchPad,i); + } catch (ShortBufferException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (BadPaddingException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + } else{ + if(cipherAlg == KMType.RSA && padding == KMType.PADDING_NONE && mode == KMType.ENCRYPT ){ + // Length cannot be greater then key size according to JcardSim + if(length >= 256) KMException.throwIt(KMError.INVALID_INPUT_LENGTH); + // make input equal to 255 bytes + byte[] tmp = new byte[255]; + Util.arrayFillNonAtomic(tmp,(short)0,(short)255, (byte)0); + Util.arrayCopyNonAtomic( + buffer, + startOff, + tmp, (short)(255 - length),length); + startOff = 0; + length = 255; + buffer = tmp; + + }else if((cipherAlg == KMType.DES || cipherAlg == KMType.AES) && padding ==KMType.PKCS7 && mode == KMType.ENCRYPT){ + byte blkSize = 16; + byte paddingBytes; + short len = length; + if (cipherAlg == KMType.DES) blkSize = 8; + // padding bytes + if (len % blkSize == 0) paddingBytes = blkSize; + else paddingBytes = (byte) (blkSize - (len % blkSize)); + // final len with padding + len = (short) (len + paddingBytes); + // intermediate buffer to copy input data+padding + byte[] tmp = new byte[len]; + // fill in the padding + Util.arrayFillNonAtomic(tmp, (short) 0, len, paddingBytes); + // copy the input data + Util.arrayCopyNonAtomic(buffer,startOff,tmp,(short)0,length); + buffer = tmp; + length = len; + startOff = 0; + } + short len = cipher.doFinal(buffer, startOff, length, scratchPad, i); + // JCard Sim removes leading zeros during decryption in case of no padding - so add that back. + if (cipherAlg == KMType.RSA && padding == KMType.PADDING_NONE && mode == KMType.DECRYPT && len < 256) { + byte[] tempBuf = new byte[256]; + Util.arrayFillNonAtomic(tempBuf, (short) 0, (short) 256, (byte) 0); + Util.arrayCopyNonAtomic(scratchPad, (short) 0, tempBuf, (short) (i + 256 - len), len); + Util.arrayCopyNonAtomic(tempBuf, (short) 0, scratchPad, i, (short) 256); + len = 256; + }else if((cipherAlg == KMType.AES || cipherAlg == KMType.DES) // PKCS7 + && padding == KMType.PKCS7 + && mode == KMType.DECRYPT){ + byte blkSize = 16; + if (cipherAlg == KMType.DES) blkSize = 8; + if(len >0) { + //verify if padding is corrupted. + byte paddingByte = scratchPad[i+len -1]; + //padding byte always should be <= block size + if((short)paddingByte > blkSize || + (short)paddingByte <= 0) KMException.throwIt(KMError.INVALID_ARGUMENT); + len = (short)(len - (short)paddingByte);// remove the padding bytes + } + } + return len; + } + return KMType.INVALID_VALUE; + } + + @Override + public short getCipherAlgorithm() { + return cipherAlg; + } + + @Override + public void setCipherAlgorithm(short alg) { + cipherAlg = alg; + } + + @Override + public short update(byte[] buffer, short startOff, short length, byte[] scratchPad, short i) { + if(cipherAlg == KMType.AES && (blockMode == KMType.GCM || blockMode == KMType.CTR)){ + try { + return (short)sunCipher.update(buffer,startOff,length,scratchPad,i); + } catch (ShortBufferException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (IllegalStateException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + } else{ + return cipher.update(buffer, startOff, length, scratchPad, i); + } + return KMType.INVALID_VALUE; + } + + @Override + public void updateAAD(byte[] buffer, short startOff, short length) { + try { + sunCipher.updateAAD(buffer,startOff,length); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (IllegalStateException e) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } catch (UnsupportedOperationException e) { + CryptoException.throwIt(CryptoException.ILLEGAL_USE); + } + } + + @Override + public short getPaddingAlgorithm() { + return padding; + } + + @Override + public void setPaddingAlgorithm(short alg) { + padding = alg; + } + + @Override + public void setBlockMode(short mode){ + blockMode = mode; + } + + @Override + public short getBlockMode(){ + return blockMode; + } + + public short getMode() { + return mode; + } + + public void setMode(short mode) { + this.mode = mode; + } + + @Override + public short getCipherProvider() { + return KMCipher.SUN_JCE; + } + + @Override + public short getAesGcmOutputSize(short len, short macLength) { + if (sunCipher != null) { + return (short) sunCipher.getOutputSize(len); + } else { + if (mode == KMType.ENCRYPT) { + return (short) (len + macLength); + } else { + return (short) (len - macLength); + } + } + } + +} diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java similarity index 100% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java new file mode 100644 index 00000000..e1ec74f8 --- /dev/null +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java @@ -0,0 +1,19 @@ +package com.android.javacard.keymaster; + +public class KMJCardSimApplet extends KMKeymasterApplet { + + KMJCardSimApplet(){ + super(new KMJCardSimulator()); + } + /** + * Installs this applet. + * + * @param bArray the array containing installation parameters + * @param bOffset the starting offset in bArray + * @param bLength the length in bytes of the parameter data in bArray + */ + public static void install(byte[] bArray, short bOffset, byte bLength) { + new KMJCardSimApplet().register(); + } + +} diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMJcardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java similarity index 99% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMJcardSimulator.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 76ebb3e9..446f8bd2 100644 --- a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMJcardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -65,7 +65,7 @@ * Key, and upto 512 bit HMAC key. Also simulator does not support TRNG, so this implementation just * creates its own RNG using PRNG. */ -public class KMJcardSimulator implements KMSEProvider { +public class KMJCardSimulator implements KMSEProvider { public static final short AES_GCM_TAG_LENGTH = 12; public static final short AES_GCM_NONCE_LENGTH = 12; public static final short MAX_RND_NUM_SIZE = 64; @@ -85,14 +85,14 @@ public class KMJcardSimulator implements KMSEProvider { private static byte[] rndNum; private byte[] certificateChain; - private static KMJcardSimulator jCardSimulator = null; + private static KMJCardSimulator jCardSimulator = null; - public static KMJcardSimulator getInstance() { + public static KMJCardSimulator getInstance() { return jCardSimulator; } // Implements Oracle Simulator based restricted crypto provider - public KMJcardSimulator() { + public KMJCardSimulator() { // Various Keys kdf = Signature.getInstance(Signature.ALG_AES_CMAC_128, false); hmacSignature = Signature.getInstance(Signature.ALG_HMAC_SHA_256, false); diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java similarity index 100% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMOperationImpl.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java similarity index 96% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java index 82793bfb..38e9a3bc 100644 --- a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java @@ -1,120 +1,120 @@ -package com.android.javacard.keymaster; - -import javacard.framework.Util; -import javacard.security.CryptoException; -import javacard.security.Key; -import javacard.security.Signature; -import javacardx.crypto.Cipher; - -public class KMRsa2048NoDigestSignature extends Signature { - private Cipher inst; // ALG_RSA_NOPAD. - private byte padding; - private byte[] rsaModulus; // to compare with the data value - - public KMRsa2048NoDigestSignature(Cipher ciph, byte padding, byte[]mod, short start, short len){ - inst = ciph; - this.padding = padding; - if(len != 256) CryptoException.throwIt(CryptoException.INVALID_INIT); - rsaModulus = new byte[256]; - Util.arrayCopyNonAtomic(mod,start,rsaModulus,(short)0,len); - } - - @Override - public void init(Key key, byte b) throws CryptoException { - - } - - @Override - public void init(Key key, byte b, byte[] bytes, short i, short i1) throws CryptoException { - } - - @Override - public void setInitialDigest(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException { - } - - @Override - public byte getAlgorithm() { - return 0; - } - - @Override - public byte getMessageDigestAlgorithm() { - return 0; - } - - @Override - public byte getCipherAlgorithm() { - return 0; - } - - @Override - public byte getPaddingAlgorithm() { - return 0; - } - - @Override - public short getLength() throws CryptoException { - return 0; - } - - @Override - public void update(byte[] bytes, short i, short i1) throws CryptoException { - } - - @Override - public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) throws CryptoException { - byte[] inputData = padData(bytes,i,i1); - return inst.doFinal(inputData,(short)0,(short)256,bytes1,i2); - } - - @Override - public short signPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1, short i2) throws CryptoException { - return 0; - } - - @Override - public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException { - // Cannot support this method as javacard cipher api does not allow 256 byte for public key - // encryption without padding. It only allows 255 bytes data. - return false; - } - - @Override - public boolean verifyPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException { - return false; - } - - private byte[] padData(byte[] buf, short start, short len){ - byte[] inputData = new byte[256]; - if(!isValidData(buf, start,len)){ - CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); - } - Util.arrayFillNonAtomic(inputData, (short) 0, (short) 256, (byte) 0x00); - if (padding == KMType.PADDING_NONE) { // add zero to right - } else if (padding == KMType.RSA_PKCS1_1_5_SIGN) {// 0x00||0x01||PS||0x00 - inputData[0] = 0x00; - inputData[1] = 0x01; - Util.arrayFillNonAtomic(inputData,(short)2,(short)(256-len-3),(byte)0xFF); - inputData[(short)(256-len-1)] = 0x00; - }else{ - CryptoException.throwIt(CryptoException.ILLEGAL_USE); - } - Util.arrayCopyNonAtomic(buf,start,inputData,(short)(256 -len),len); - return inputData; - } - - private boolean isValidData(byte[] buf, short start, short len) { - if (padding == KMType.PADDING_NONE) { - if (len > 256) return false; - else if (len == 256) { - short v = Util.arrayCompare(buf, start, rsaModulus, (short) 0, len); - if (v > 0) return false; - } - } else {//pkcs1 no digest - if(len > 245){ - return false; - } - } - return true; - } -} +package com.android.javacard.keymaster; + +import javacard.framework.Util; +import javacard.security.CryptoException; +import javacard.security.Key; +import javacard.security.Signature; +import javacardx.crypto.Cipher; + +public class KMRsa2048NoDigestSignature extends Signature { + private Cipher inst; // ALG_RSA_NOPAD. + private byte padding; + private byte[] rsaModulus; // to compare with the data value + + public KMRsa2048NoDigestSignature(Cipher ciph, byte padding, byte[]mod, short start, short len){ + inst = ciph; + this.padding = padding; + if(len != 256) CryptoException.throwIt(CryptoException.INVALID_INIT); + rsaModulus = new byte[256]; + Util.arrayCopyNonAtomic(mod,start,rsaModulus,(short)0,len); + } + + @Override + public void init(Key key, byte b) throws CryptoException { + + } + + @Override + public void init(Key key, byte b, byte[] bytes, short i, short i1) throws CryptoException { + } + + @Override + public void setInitialDigest(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException { + } + + @Override + public byte getAlgorithm() { + return 0; + } + + @Override + public byte getMessageDigestAlgorithm() { + return 0; + } + + @Override + public byte getCipherAlgorithm() { + return 0; + } + + @Override + public byte getPaddingAlgorithm() { + return 0; + } + + @Override + public short getLength() throws CryptoException { + return 0; + } + + @Override + public void update(byte[] bytes, short i, short i1) throws CryptoException { + } + + @Override + public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) throws CryptoException { + byte[] inputData = padData(bytes,i,i1); + return inst.doFinal(inputData,(short)0,(short)256,bytes1,i2); + } + + @Override + public short signPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1, short i2) throws CryptoException { + return 0; + } + + @Override + public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException { + // Cannot support this method as javacard cipher api does not allow 256 byte for public key + // encryption without padding. It only allows 255 bytes data. + return false; + } + + @Override + public boolean verifyPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) throws CryptoException { + return false; + } + + private byte[] padData(byte[] buf, short start, short len){ + byte[] inputData = new byte[256]; + if(!isValidData(buf, start,len)){ + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + Util.arrayFillNonAtomic(inputData, (short) 0, (short) 256, (byte) 0x00); + if (padding == KMType.PADDING_NONE) { // add zero to right + } else if (padding == KMType.RSA_PKCS1_1_5_SIGN) {// 0x00||0x01||PS||0x00 + inputData[0] = 0x00; + inputData[1] = 0x01; + Util.arrayFillNonAtomic(inputData,(short)2,(short)(256-len-3),(byte)0xFF); + inputData[(short)(256-len-1)] = 0x00; + }else{ + CryptoException.throwIt(CryptoException.ILLEGAL_USE); + } + Util.arrayCopyNonAtomic(buf,start,inputData,(short)(256 -len),len); + return inputData; + } + + private boolean isValidData(byte[] buf, short start, short len) { + if (padding == KMType.PADDING_NONE) { + if (len > 256) return false; + else if (len == 256) { + short v = Util.arrayCompare(buf, start, rsaModulus, (short) 0, len); + if (v > 0) return false; + } + } else {//pkcs1 no digest + if(len > 245){ + return false; + } + } + return true; + } +} diff --git a/Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMUtils.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java similarity index 100% rename from Applet/Applet/JCardSimProvider/com/android/javacard/keymaster/KMUtils.java rename to Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java diff --git a/Applet/Applet/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java similarity index 97% rename from Applet/Applet/test/com/android/javacard/test/KMFunctionalTest.java rename to Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index 450e7a60..fb248f2d 100644 --- a/Applet/Applet/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -1,2740 +1,2735 @@ -/* - * 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.test; - -import com.android.javacard.keymaster.KMArray; -import com.android.javacard.keymaster.KMAttestationCert; -import com.android.javacard.keymaster.KMAttestationCertImpl; -import com.android.javacard.keymaster.KMBoolTag; -import com.android.javacard.keymaster.KMByteBlob; -import com.android.javacard.keymaster.KMByteTag; -import com.android.javacard.keymaster.KMSEProvider; -import com.android.javacard.keymaster.KMSEProviderImpl; -import com.android.javacard.keymaster.KMDecoder; -import com.android.javacard.keymaster.KMEncoder; -import com.android.javacard.keymaster.KMEnum; -import com.android.javacard.keymaster.KMEnumArrayTag; -import com.android.javacard.keymaster.KMEnumTag; -import com.android.javacard.keymaster.KMError; -import com.android.javacard.keymaster.KMHardwareAuthToken; -import com.android.javacard.keymaster.KMHmacSharingParameters; -import com.android.javacard.keymaster.KMInteger; -import com.android.javacard.keymaster.KMIntegerTag; -import com.android.javacard.keymaster.KMKeyCharacteristics; -import com.android.javacard.keymaster.KMKeyParameters; -import com.android.javacard.keymaster.KMKeymasterApplet; -import com.android.javacard.keymaster.KMRepository; -import com.android.javacard.keymaster.KMType; -import com.android.javacard.keymaster.KMVerificationToken; -import com.licel.jcardsim.smartcardio.CardSimulator; -import com.licel.jcardsim.utils.AIDUtil; -import javacard.framework.AID; -import javacard.framework.Util; - -import java.security.spec.PKCS8EncodedKeySpec; - -import javax.smartcardio.CommandAPDU; -import javax.smartcardio.ResponseAPDU; -import org.junit.Assert; -import org.junit.Test; - -public class KMFunctionalTest { - private static final byte INS_BEGIN_KM_CMD = 0x00; - private static final byte INS_PROVISION_ATTESTATION_KEY_CMD = INS_BEGIN_KM_CMD + 1; //0x01 - private static final byte INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD = INS_BEGIN_KM_CMD + 2; //0x02 - private static final byte INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD = INS_BEGIN_KM_CMD + 3; //0x03 - private static final byte INS_PROVISION_ATTEST_IDS_CMD = INS_BEGIN_KM_CMD + 4; //0x04 - private static final byte INS_PROVISION_SHARED_SECRET_CMD = INS_BEGIN_KM_CMD + 5; //0x05 - private static final byte INS_SET_BOOT_PARAMS_CMD = INS_BEGIN_KM_CMD + 6; //0x06 - private static final byte INS_LOCK_PROVISIONING_CMD = INS_BEGIN_KM_CMD + 7; //0x07 - private static final byte INS_GET_PROVISION_STATUS_CMD = INS_BEGIN_KM_CMD + 8; //0x08 - // Top 32 commands are reserved for provisioning. - private static final byte INS_END_KM_PROVISION_CMD = 0x20; - - private static final byte INS_GENERATE_KEY_CMD = INS_END_KM_PROVISION_CMD + 1; //0x21 - private static final byte INS_IMPORT_KEY_CMD = INS_END_KM_PROVISION_CMD + 2; //0x22 - private static final byte INS_IMPORT_WRAPPED_KEY_CMD = INS_END_KM_PROVISION_CMD + 3; //0x23 - private static final byte INS_EXPORT_KEY_CMD = INS_END_KM_PROVISION_CMD + 4; //0x24 - private static final byte INS_ATTEST_KEY_CMD = INS_END_KM_PROVISION_CMD + 5; //0x25 - private static final byte INS_UPGRADE_KEY_CMD = INS_END_KM_PROVISION_CMD + 6; //0x26 - private static final byte INS_DELETE_KEY_CMD = INS_END_KM_PROVISION_CMD + 7; //0x27 - private static final byte INS_DELETE_ALL_KEYS_CMD = INS_END_KM_PROVISION_CMD + 8; //0x28 - private static final byte INS_ADD_RNG_ENTROPY_CMD = INS_END_KM_PROVISION_CMD + 9; //0x29 - private static final byte INS_COMPUTE_SHARED_HMAC_CMD = INS_END_KM_PROVISION_CMD + 10; //0x2A - private static final byte INS_DESTROY_ATT_IDS_CMD = INS_END_KM_PROVISION_CMD + 11; //0x2B - private static final byte INS_VERIFY_AUTHORIZATION_CMD = INS_END_KM_PROVISION_CMD + 12; //0x2C - private static final byte INS_GET_HMAC_SHARING_PARAM_CMD = INS_END_KM_PROVISION_CMD + 13; //0x2D - private static final byte INS_GET_KEY_CHARACTERISTICS_CMD = INS_END_KM_PROVISION_CMD + 14; //0x2E - private static final byte INS_GET_HW_INFO_CMD = INS_END_KM_PROVISION_CMD + 15; //0x2F - private static final byte INS_BEGIN_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 16; //0x30 - private static final byte INS_UPDATE_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 17; //0x31 - private static final byte INS_FINISH_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 18; //0x32 - private static final byte INS_ABORT_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 19; //0x33 - private static final byte INS_DEVICE_LOCKED_CMD = INS_END_KM_PROVISION_CMD + 20;//0x34 - private static final byte INS_EARLY_BOOT_ENDED_CMD = INS_END_KM_PROVISION_CMD + 21; //0x35 - private static final byte INS_GET_CERT_CHAIN_CMD = INS_END_KM_PROVISION_CMD + 22; //0x36 - - private static final byte[] kEcPrivKey = { - (byte) 0x21, (byte) 0xe0, (byte) 0x86, (byte) 0x43, (byte) 0x2a, - (byte) 0x15, (byte) 0x19, (byte) 0x84, (byte) 0x59, (byte) 0xcf, - (byte) 0x36, (byte) 0x3a, (byte) 0x50, (byte) 0xfc, (byte) 0x14, - (byte) 0xc9, (byte) 0xda, (byte) 0xad, (byte) 0xf9, (byte) 0x35, - (byte) 0xf5, (byte) 0x27, (byte) 0xc2, (byte) 0xdf, (byte) 0xd7, - (byte) 0x1e, (byte) 0x4d, (byte) 0x6d, (byte) 0xbc, (byte) 0x42, - (byte) 0xe5, (byte) 0x44 }; - private static final byte[] kEcPubKey = { - (byte) 0x04, (byte) 0xeb, (byte) 0x9e, (byte) 0x79, (byte) 0xf8, - (byte) 0x42, (byte) 0x63, (byte) 0x59, (byte) 0xac, (byte) 0xcb, - (byte) 0x2a, (byte) 0x91, (byte) 0x4c, (byte) 0x89, (byte) 0x86, - (byte) 0xcc, (byte) 0x70, (byte) 0xad, (byte) 0x90, (byte) 0x66, - (byte) 0x93, (byte) 0x82, (byte) 0xa9, (byte) 0x73, (byte) 0x26, - (byte) 0x13, (byte) 0xfe, (byte) 0xac, (byte) 0xcb, (byte) 0xf8, - (byte) 0x21, (byte) 0x27, (byte) 0x4c, (byte) 0x21, (byte) 0x74, - (byte) 0x97, (byte) 0x4a, (byte) 0x2a, (byte) 0xfe, (byte) 0xa5, - (byte) 0xb9, (byte) 0x4d, (byte) 0x7f, (byte) 0x66, (byte) 0xd4, - (byte) 0xe0, (byte) 0x65, (byte) 0x10, (byte) 0x66, (byte) 0x35, - (byte) 0xbc, (byte) 0x53, (byte) 0xb7, (byte) 0xa0, (byte) 0xa3, - (byte) 0xa6, (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, - (byte) 0x3e, (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14 }; - - private static final byte[] kEcAttestCert = { - 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x30, (byte) 0x82, - (byte) 0x02, (byte) 0x1e, (byte) 0xa0, (byte) 0x03, (byte) 0x02, - (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x10, 0x01, - (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, - (byte) 0x03, (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0x98, 0x31, - (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, - (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, 0x11, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, - (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, - (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, 0x69, - (byte) 0x61, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, - (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f, (byte) 0x75, 0x6e, - (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x20, - (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, - (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, 0x55, - (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, - (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, - (byte) 0x2c, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, 0x2e, - (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, - (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, 0x6f, - (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x33, (byte) 0x30, - (byte) 0x31, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x03, (byte) 0x0c, (byte) 0x2a, (byte) 0x41, (byte) 0x6e, 0x64, - (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, - (byte) 0x4b, (byte) 0x65, (byte) 0x79, (byte) 0x73, (byte) 0x74, - (byte) 0x6f, (byte) 0x72, (byte) 0x65, (byte) 0x20, (byte) 0x53, 0x6f, - (byte) 0x66, (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72, - (byte) 0x65, (byte) 0x20, (byte) 0x41, (byte) 0x74, (byte) 0x74, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x61, (byte) 0x74, 0x69, - (byte) 0x6f, (byte) 0x6e, (byte) 0x20, (byte) 0x52, (byte) 0x6f, - (byte) 0x6f, (byte) 0x74, (byte) 0x30, (byte) 0x1e, (byte) 0x17, - (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, 0x31, - (byte) 0x31, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, - (byte) 0x30, (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, - (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x30, 0x38, - (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, (byte) 0x30, - (byte) 0x39, (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0x88, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, - (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, - (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, 0x08, - (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, - (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, - (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, 0x13, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, - (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, - (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, (byte) 0x20, 0x49, - (byte) 0x6e, (byte) 0x63, (byte) 0x2e, (byte) 0x31, (byte) 0x10, - (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, 0x6e, - (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, - (byte) 0x31, (byte) 0x3b, (byte) 0x30, (byte) 0x39, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, 0x32, - (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, - (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, - (byte) 0x79, (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, 0x65, - (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, - (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, - (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, 0x74, - (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, - (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, - (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, (byte) 0x69, 0x61, - (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x59, (byte) 0x30, - (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, 0x06, - (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, - (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x03, - (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xeb, (byte) 0x9e, 0x79, - (byte) 0xf8, (byte) 0x42, (byte) 0x63, (byte) 0x59, (byte) 0xac, - (byte) 0xcb, (byte) 0x2a, (byte) 0x91, (byte) 0x4c, (byte) 0x89, - (byte) 0x86, (byte) 0xcc, (byte) 0x70, (byte) 0xad, (byte) 0x90, 0x66, - (byte) 0x93, (byte) 0x82, (byte) 0xa9, (byte) 0x73, (byte) 0x26, - (byte) 0x13, (byte) 0xfe, (byte) 0xac, (byte) 0xcb, (byte) 0xf8, - (byte) 0x21, (byte) 0x27, (byte) 0x4c, (byte) 0x21, (byte) 0x74, - (byte) 0x97, (byte) 0x4a, (byte) 0x2a, (byte) 0xfe, (byte) 0xa5, - (byte) 0xb9, (byte) 0x4d, (byte) 0x7f, (byte) 0x66, (byte) 0xd4, - (byte) 0xe0, (byte) 0x65, (byte) 0x10, (byte) 0x66, (byte) 0x35, - (byte) 0xbc, 0x53, (byte) 0xb7, (byte) 0xa0, (byte) 0xa3, (byte) 0xa6, - (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, (byte) 0x3e, - (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14, (byte) 0xa3, - (byte) 0x66, 0x30, (byte) 0x64, (byte) 0x30, (byte) 0x1d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, - (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x3f, (byte) 0xfc, - (byte) 0xac, (byte) 0xd6, (byte) 0x1a, (byte) 0xb1, (byte) 0x3a, - (byte) 0x9e, (byte) 0x81, (byte) 0x20, (byte) 0xb8, (byte) 0xd5, - (byte) 0x25, (byte) 0x1c, (byte) 0xc5, (byte) 0x65, (byte) 0xbb, - (byte) 0x1e, (byte) 0x91, (byte) 0xa9, (byte) 0x30, (byte) 0x1f, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, - (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, - (byte) 0x14, (byte) 0xc8, (byte) 0xad, (byte) 0xe9, (byte) 0x77, - (byte) 0x4c, (byte) 0x45, (byte) 0xc3, (byte) 0xa3, (byte) 0xcf, - (byte) 0x0d, (byte) 0x16, (byte) 0x10, (byte) 0xe4, (byte) 0x79, - (byte) 0x43, (byte) 0x3a, (byte) 0x21, (byte) 0x5a, 0x30, (byte) 0xcf, - (byte) 0x30, (byte) 0x12, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x1d, (byte) 0x13, (byte) 0x01, (byte) 0x01, (byte) 0xff, - (byte) 0x04, (byte) 0x08, (byte) 0x30, (byte) 0x06, 0x01, (byte) 0x01, - (byte) 0xff, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, - (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, - (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, 0x04, (byte) 0x04, - (byte) 0x03, (byte) 0x02, (byte) 0x02, (byte) 0x84, (byte) 0x30, - (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, 0x03, (byte) 0x02, - (byte) 0x03, (byte) 0x48, (byte) 0x00, (byte) 0x30, (byte) 0x45, - (byte) 0x02, (byte) 0x20, (byte) 0x4b, (byte) 0x8a, (byte) 0x9b, - (byte) 0x7b, (byte) 0xee, (byte) 0x82, (byte) 0xbc, (byte) 0xc0, - (byte) 0x33, (byte) 0x87, (byte) 0xae, (byte) 0x2f, (byte) 0xc0, - (byte) 0x89, (byte) 0x98, (byte) 0xb4, (byte) 0xdd, (byte) 0xc3, - (byte) 0x8d, (byte) 0xab, (byte) 0x27, (byte) 0x2a, (byte) 0x45, - (byte) 0x9f, (byte) 0x69, (byte) 0x0c, (byte) 0xc7, (byte) 0xc3, - (byte) 0x92, (byte) 0xd4, (byte) 0x0f, (byte) 0x8e, (byte) 0x02, - (byte) 0x21, (byte) 0x00, (byte) 0xee, (byte) 0xda, (byte) 0x01, - (byte) 0x5d, (byte) 0xb6, (byte) 0xf4, (byte) 0x32, (byte) 0xe9, - (byte) 0xd4, (byte) 0x84, (byte) 0x3b, (byte) 0x62, (byte) 0x4c, - (byte) 0x94, (byte) 0x04, (byte) 0xef, (byte) 0x3a, (byte) 0x7c, - (byte) 0xcc, (byte) 0xbd, 0x5e, (byte) 0xfb, (byte) 0x22, (byte) 0xbb, - (byte) 0xe7, (byte) 0xfe, (byte) 0xb9, (byte) 0x77, (byte) 0x3f, - (byte) 0x59, (byte) 0x3f, (byte) 0xfb, }; - - private static final byte[] kEcAttestRootCert = { - 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8b, (byte) 0x30, - (byte) 0x82, (byte) 0x02, (byte) 0x32, (byte) 0xa0, (byte) 0x03, - (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x09, - (byte) 0x00, (byte) 0xa2, (byte) 0x05, (byte) 0x9e, (byte) 0xd1, - (byte) 0x0e, (byte) 0x43, (byte) 0x5b, (byte) 0x57, (byte) 0x30, - (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0xce, 0x3d, (byte) 0x04, (byte) 0x03, - (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0x98, (byte) 0x31, - (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, 0x13, (byte) 0x02, - (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, - (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x43, 0x61, - (byte) 0x6c, (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, - (byte) 0x6e, (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x16, - (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55, - 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, - (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, - (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, - (byte) 0x65, 0x77, (byte) 0x31, (byte) 0x15, (byte) 0x30, - (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, - (byte) 0x6f, (byte) 0x67, 0x6c, (byte) 0x65, (byte) 0x2c, - (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, - (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, 0x0b, (byte) 0x0c, - (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, - (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x33, - (byte) 0x30, (byte) 0x31, (byte) 0x06, (byte) 0x03, 0x55, - (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x2a, (byte) 0x41, - (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, - (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, - 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, - (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, - (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, - (byte) 0x41, 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, - (byte) 0x6e, (byte) 0x20, (byte) 0x52, (byte) 0x6f, (byte) 0x6f, - (byte) 0x74, (byte) 0x30, 0x1e, (byte) 0x17, (byte) 0x0d, - (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, - (byte) 0x31, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x33, - (byte) 0x35, (byte) 0x30, (byte) 0x5a, 0x17, (byte) 0x0d, - (byte) 0x33, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x30, - (byte) 0x36, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x33, - (byte) 0x35, (byte) 0x30, (byte) 0x5a, (byte) 0x30, (byte) 0x81, - (byte) 0x98, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, - (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, - 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, - (byte) 0x43, (byte) 0x61, (byte) 0x6c, (byte) 0x69, (byte) 0x66, - (byte) 0x6f, 0x72, (byte) 0x6e, (byte) 0x69, (byte) 0x61, - (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, - (byte) 0x0d, (byte) 0x4d, 0x6f, (byte) 0x75, (byte) 0x6e, - (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x20, - (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, - (byte) 0x15, (byte) 0x30, (byte) 0x13, 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, - (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, - (byte) 0x65, (byte) 0x2c, (byte) 0x20, (byte) 0x49, 0x6e, - (byte) 0x63, (byte) 0x2e, (byte) 0x31, (byte) 0x10, (byte) 0x30, - (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, - 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, - (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x31, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, - (byte) 0x2a, 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, - (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x4b, - (byte) 0x65, (byte) 0x79, (byte) 0x73, (byte) 0x74, (byte) 0x6f, - (byte) 0x72, (byte) 0x65, 0x20, (byte) 0x53, (byte) 0x6f, - (byte) 0x66, (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72, - (byte) 0x65, (byte) 0x20, (byte) 0x41, (byte) 0x74, (byte) 0x74, - (byte) 0x65, (byte) 0x73, (byte) 0x74, 0x61, (byte) 0x74, - (byte) 0x69, (byte) 0x6f, (byte) 0x6e, 0x77, (byte) 0x1f, - (byte) 0x44, (byte) 0x22, (byte) 0x6d, (byte) 0xbd, (byte) 0xb1, - (byte) 0xaf, (byte) 0xfa, (byte) 0x16, (byte) 0xcb, (byte) 0xc7, - (byte) 0xad, (byte) 0xc5, (byte) 0x77, (byte) 0xd2, (byte) 0x20, - (byte) 0x52, (byte) 0x6f, (byte) 0x6f, (byte) 0x74, (byte) 0x30, - (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, - 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, - (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, - (byte) 0x01, 0x07, (byte) 0x03, (byte) 0x42, (byte) 0x00, - (byte) 0x04, (byte) 0xee, (byte) 0x5d, (byte) 0x5e, (byte) 0xc7, - (byte) 0xe1, (byte) 0xc0, (byte) 0xdb, (byte) 0x6d, (byte) 0x03, - (byte) 0xa6, (byte) 0x7e, (byte) 0xe6, (byte) 0xb6, (byte) 0x1b, - (byte) 0xec, (byte) 0x4d, (byte) 0x6a, (byte) 0x5d, (byte) 0x6a, - (byte) 0x68, (byte) 0x2e, (byte) 0x0f, (byte) 0xff, (byte) 0x7f, - (byte) 0x49, (byte) 0x0e, (byte) 0x7d, 0x56, (byte) 0x9c, - (byte) 0xaa, (byte) 0xb7, (byte) 0xb0, (byte) 0x2d, (byte) 0x54, - (byte) 0x01, (byte) 0x5d, (byte) 0x3e, (byte) 0x43, (byte) 0x2b, - (byte) 0x2a, (byte) 0x8e, (byte) 0xd7, (byte) 0x4e, (byte) 0xec, - (byte) 0x48, (byte) 0x75, (byte) 0x41, (byte) 0xa4, (byte) 0xa3, - (byte) 0x63, (byte) 0x30, (byte) 0x61, (byte) 0x30, (byte) 0x1d, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, - 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0xc8, - (byte) 0xad, (byte) 0xe9, (byte) 0x77, (byte) 0x4c, (byte) 0x45, - (byte) 0xc3, (byte) 0xa3, (byte) 0xcf, (byte) 0x0d, (byte) 0x16, - (byte) 0x10, (byte) 0xe4, (byte) 0x79, (byte) 0x43, (byte) 0x3a, - (byte) 0x21, (byte) 0x5a, (byte) 0x30, (byte) 0xcf, (byte) 0x30, - (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, - (byte) 0x23, (byte) 0x04, 0x18, (byte) 0x30, (byte) 0x16, - (byte) 0x80, (byte) 0x14, (byte) 0xc8, (byte) 0xad, (byte) 0xe9, - (byte) 0x77, (byte) 0x4c, (byte) 0x45, (byte) 0xc3, (byte) 0xa3, - (byte) 0xcf, (byte) 0x0d, (byte) 0x16, 0x10, (byte) 0xe4, - (byte) 0x79, (byte) 0x43, (byte) 0x3a, (byte) 0x21, (byte) 0x5a, - (byte) 0x30, (byte) 0xcf, (byte) 0x30, (byte) 0x0f, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, 0x01, - (byte) 0x01, (byte) 0xff, (byte) 0x04, (byte) 0x05, (byte) 0x30, - (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, - (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, - 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04, - (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x02, (byte) 0x84, - (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, - (byte) 0x86, 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, - (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x47, (byte) 0x00, - (byte) 0x30, (byte) 0x44, (byte) 0x02, (byte) 0x20, (byte) 0x35, - (byte) 0x21, (byte) 0xa3, (byte) 0xef, (byte) 0x8b, (byte) 0x34, - (byte) 0x46, (byte) 0x1e, (byte) 0x9c, (byte) 0xd5, (byte) 0x60, - (byte) 0xf3, (byte) 0x1d, (byte) 0x58, (byte) 0x89, (byte) 0x20, - (byte) 0x6a, (byte) 0xdc, (byte) 0xa3, 0x65, (byte) 0x41, - (byte) 0xf6, (byte) 0x0d, (byte) 0x9e, (byte) 0xce, (byte) 0x8a, - (byte) 0x19, (byte) 0x8c, (byte) 0x66, (byte) 0x48, (byte) 0x60, - (byte) 0x7b, (byte) 0x02, (byte) 0x20, (byte) 0x4d, 0x0b, - (byte) 0xf3, (byte) 0x51, (byte) 0xd9, (byte) 0x30, (byte) 0x7c, - (byte) 0x7d, (byte) 0x5b, (byte) 0xda, (byte) 0x35, (byte) 0x34, - (byte) 0x1d, (byte) 0xa8, (byte) 0x47, (byte) 0x1b, (byte) 0x63, - (byte) 0xa5, (byte) 0x85, (byte) 0x65, (byte) 0x3c, (byte) 0xad, - (byte) 0x4f, (byte) 0x24, (byte) 0xa7, (byte) 0xe7, (byte) 0x4d, - (byte) 0xaf, (byte) 0x41, (byte) 0x7d, (byte) 0xf1, - (byte) 0xbf, }; - - private static final byte[] X509Issuer = { - (byte) 0x30, (byte) 0x81, (byte) 0x88, (byte) 0x31, (byte) 0x0b, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, - (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, - (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, - (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, - (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, - (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, - (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, - (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, - (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, - (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, - (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x3b, - (byte) 0x30, (byte) 0x39, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x32, (byte) 0x41, - (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, - (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, - (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, - (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, - (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, - (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, - (byte) 0x6e, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, - (byte) 0x65, (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, - (byte) 0x69, (byte) 0x61, (byte) 0x74, (byte) 0x65 }; - // AttestationApplicationId ::= SEQUENCE { - // * packageInfoRecords SET OF PackageInfoRecord, - // * signatureDigests SET OF OCTET_STRING, - // * } - // * - // * PackageInfoRecord ::= SEQUENCE { - // * packageName OCTET_STRING, - // * version INTEGER, - // * } - private static final byte[] attAppId = {0x30, 0x10, 0x31, 0x0B, 0x30, 0x04, 0x05, 'A', 'B', 'C', - 'D', 'E', 0x02, 0x01, 0x01, 0x31, 0x02, 0x04, 0x00}; - private static final byte[] attChallenge = {'c','h','a','l','l','e','n','g','e'}; - private static final byte[] expiryTime = {(byte)0x32, (byte)0x36, (byte)0x30, (byte)0x31, (byte)0x30, (byte)0x38, (byte)0x30, (byte)0x30, (byte)0x34, (byte)0x36, (byte)0x30, (byte)0x39, (byte)0x5a}; - private static final byte[] authKeyId = { (byte)0x80, (byte)0x14, (byte)0xc8, (byte)0xad, (byte)0xe9, (byte)0x77, (byte)0x4c, (byte)0x45, (byte)0xc3, (byte)0xa3, (byte)0xcf, (byte)0x0d, (byte)0x16, (byte)0x10, (byte)0xe4, (byte)0x79, (byte)0x43, (byte)0x3a, (byte)0x21, (byte)0x5a, (byte)0x30, (byte)0xcf}; - - private KMSEProvider sim; - private CardSimulator simulator; - private KMEncoder encoder; - private KMDecoder decoder; - private KMSEProvider cryptoProvider; - - public KMFunctionalTest(){ - cryptoProvider = KMSEProviderImpl.instance(false); - sim = KMSEProviderImpl.instance(false); - simulator = new CardSimulator(); - encoder = new KMEncoder(); - decoder = new KMDecoder(); - } - - private void init(){ - // Create simulator - AID appletAID = AIDUtil.create("A000000062"); - simulator.installApplet(appletAID, KMKeymasterApplet.class); - // Select applet - simulator.selectApplet(appletAID); - // provision attest key - provisionCmd(simulator); - } - - private void setBootParams(CardSimulator simulator, short osVersion, - short osPatchLevel, short vendorPatchLevel, short bootPatchLevel) { - // Argument 1 OS Version - short versionPtr = KMInteger.uint_16(osVersion); - // short versionTagPtr = KMIntegerTag.instance(KMType.UINT_TAG, - // KMType.OS_VERSION,versionPatchPtr); - // Argument 2 OS Patch level - short patchPtr = KMInteger.uint_16(osPatchLevel); - short vendorpatchPtr = KMInteger.uint_16((short) vendorPatchLevel); - short bootpatchPtr = KMInteger.uint_16((short) bootPatchLevel); - // Argument 3 Verified Boot Key - byte[] bootKeyHash = "00011122233344455566677788899900".getBytes(); - short bootKeyPtr = KMByteBlob.instance(bootKeyHash, (short) 0, - (short) bootKeyHash.length); - // Argument 4 Verified Boot Hash - short bootHashPtr = KMByteBlob.instance(bootKeyHash, (short) 0, - (short) bootKeyHash.length); - // Argument 5 Verified Boot State - short bootStatePtr = KMEnum.instance(KMType.VERIFIED_BOOT_STATE, - KMType.VERIFIED_BOOT); - // Argument 6 Device Locked - short deviceLockedPtr = KMEnum.instance(KMType.DEVICE_LOCKED, - KMType.DEVICE_LOCKED_FALSE); - // Arguments - short arrPtr = KMArray.instance((short) 8); - KMArray vals = KMArray.cast(arrPtr); - vals.add((short) 0, versionPtr); - vals.add((short) 1, patchPtr); - vals.add((short) 2, vendorpatchPtr); - vals.add((short) 3, bootpatchPtr); - vals.add((short) 4, bootKeyPtr); - vals.add((short) 5, bootHashPtr); - vals.add((short) 6, bootStatePtr); - vals.add((short) 7, deviceLockedPtr); - CommandAPDU apdu = encodeApdu((byte) INS_SET_BOOT_PARAMS_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - - } - - private void provisionSigningCertificate(CardSimulator simulator) { - short byteBlobPtr = KMByteBlob.instance( - (short) (kEcAttestCert.length + kEcAttestRootCert.length)); - Util.arrayCopyNonAtomic(kEcAttestCert, (short) 0, - KMByteBlob.cast(byteBlobPtr).getBuffer(), - KMByteBlob.cast(byteBlobPtr).getStartOff(), - (short) kEcAttestCert.length); - Util.arrayCopyNonAtomic(kEcAttestRootCert, (short) 0, - KMByteBlob.cast(byteBlobPtr).getBuffer(), - (short) (KMByteBlob.cast(byteBlobPtr).getStartOff() - + kEcAttestCert.length), - (short) kEcAttestRootCert.length); - CommandAPDU apdu = encodeApdu( - (byte) INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD, byteBlobPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - } - - private void provisionSigningKey(CardSimulator simulator) { - // KeyParameters. - short arrPtr = KMArray.instance((short) 4); - short ecCurve = KMEnumTag.instance(KMType.ECCURVE, KMType.P_256); - short byteBlob = KMByteBlob.instance((short) 1); - KMByteBlob.cast(byteBlob).add((short) 0, KMType.SHA2_256); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - short byteBlob2 = KMByteBlob.instance((short) 1); - KMByteBlob.cast(byteBlob2).add((short) 0, KMType.ATTEST_KEY); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob2); - KMArray.cast(arrPtr).add((short) 0, ecCurve); - KMArray.cast(arrPtr).add((short) 1, digest); - KMArray.cast(arrPtr).add((short) 2, - KMEnumTag.instance(KMType.ALGORITHM, KMType.EC)); - KMArray.cast(arrPtr).add((short) 3, purpose); - short keyParams = KMKeyParameters.instance(arrPtr); - // Note: VTS uses PKCS8 KeyFormat RAW - short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW); - - // Key - short signKeyPtr = KMArray.instance((short) 2); - KMArray.cast(signKeyPtr).add((short) 0, KMByteBlob.instance(kEcPrivKey, - (short) 0, (short) kEcPrivKey.length)); - KMArray.cast(signKeyPtr).add((short) 1, KMByteBlob.instance(kEcPubKey, - (short) 0, (short) kEcPubKey.length)); - byte[] keyBuf = new byte[120]; - short len = encoder.encode(signKeyPtr, keyBuf, (short) 0); - short signKeyBstr = KMByteBlob.instance(keyBuf, (short) 0, len); - - short finalArrayPtr = KMArray.instance((short) 3); - KMArray.cast(finalArrayPtr).add((short) 0, keyParams); - KMArray.cast(finalArrayPtr).add((short) 1, keyFormatPtr); - KMArray.cast(finalArrayPtr).add((short) 2, signKeyBstr); - - CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_ATTESTATION_KEY_CMD, - finalArrayPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - } - - private void provisionCertificateParams(CardSimulator simulator) { - - short arrPtr = KMArray.instance((short) 3); - short byteBlob1 = KMByteBlob.instance(X509Issuer, (short) 0, - (short) X509Issuer.length); - KMArray.cast(arrPtr).add((short) 0, byteBlob1); - short byteBlob2 = KMByteBlob.instance(expiryTime, (short) 0, - (short) expiryTime.length); - KMArray.cast(arrPtr).add((short) 1, byteBlob2); - short byteBlob3 = KMByteBlob.instance(authKeyId, (short) 0, - (short) authKeyId.length); - KMArray.cast(arrPtr).add((short) 2, byteBlob3); - - CommandAPDU apdu = encodeApdu( - (byte) INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - } - - private void provisionSharedSecret(CardSimulator simulator) { - byte[] sharedKeySecret = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - short arrPtr = KMArray.instance((short) 1); - short byteBlob = KMByteBlob.instance(sharedKeySecret, (short) 0, - (short) sharedKeySecret.length); - KMArray.cast(arrPtr).add((short) 0, byteBlob); - - CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_SHARED_SECRET_CMD, - arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - } - - private void provisionAttestIds(CardSimulator simulator) { - short arrPtr = KMArray.instance((short) 8); - - byte[] buf = "Attestation Id".getBytes(); - - KMArray.cast(arrPtr).add((short) 0, - KMByteTag.instance(KMType.ATTESTATION_ID_BRAND, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 1, - KMByteTag.instance(KMType.ATTESTATION_ID_PRODUCT, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 2, - KMByteTag.instance(KMType.ATTESTATION_ID_DEVICE, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 3, - KMByteTag.instance(KMType.ATTESTATION_ID_MODEL, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 4, - KMByteTag.instance(KMType.ATTESTATION_ID_IMEI, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 5, - KMByteTag.instance(KMType.ATTESTATION_ID_MEID, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 6, - KMByteTag.instance(KMType.ATTESTATION_ID_MANUFACTURER, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - KMArray.cast(arrPtr).add((short) 7, - KMByteTag.instance(KMType.ATTESTATION_ID_SERIAL, - KMByteBlob.instance(buf, (short) 0, (short) buf.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - short outerArrPtr = KMArray.instance((short) 1); - KMArray.cast(outerArrPtr).add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_ATTEST_IDS_CMD, - outerArrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - } - - private void provisionLocked(CardSimulator simulator) { - CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_LOCK_PROVISIONING_CMD, - 0x40, 0x00); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(commandAPDU); - Assert.assertEquals(0x9000, response.getSW()); - } - - private void provisionCmd(CardSimulator simulator) { - provisionSigningKey(simulator); - provisionSigningCertificate(simulator); - provisionCertificateParams(simulator); - provisionSharedSecret(simulator); - provisionAttestIds(simulator); - // set bootup parameters - setBootParams(simulator,(short)1,(short)1, (short)0, (short)0); - provisionLocked(simulator); - } - - private void cleanUp(){ - AID appletAID = AIDUtil.create("A000000062"); - // Delete i.e. uninstall applet - simulator.deleteApplet(appletAID); - } - - private void cleanUpBkUpStore(){ - AID appletAID = AIDUtil.create("A000000063"); - // Delete i.e. uninstall applet - simulator.deleteApplet(appletAID); - } - private CommandAPDU encodeApdu(byte ins, short cmd){ - byte[] buf = new byte[2500]; - buf[0] = (byte)0x80; - buf[1] = ins; - buf[2] = (byte)0x40; - buf[3] = (byte)0x00; - buf[4] = 0; - short len = encoder.encode(cmd, buf, (short) 7); - Util.setShort(buf, (short)5, len); - byte[] apdu = new byte[7+len]; - Util.arrayCopyNonAtomic(buf,(short)0,apdu,(short)0,(short)(7+len)); - //CommandAPDU commandAPDU = new CommandAPDU(0x80, 0x10, 0x40, 0x00, buf, 0, actualLen); - return new CommandAPDU(apdu); - } - - @Test - public void testAesImportKeySuccess() { - init(); - byte[] aesKeySecret = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - short arrPtr = KMArray.instance((short)5); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ECB); - short blockMode = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.PKCS7); - short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - KMArray.cast(arrPtr).add((short)0, boolTag); - KMArray.cast(arrPtr).add((short)1, keySize); - KMArray.cast(arrPtr).add((short)2, blockMode); - KMArray.cast(arrPtr).add((short)3, paddingMode); - KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.AES)); - short keyParams = KMKeyParameters.instance(arrPtr); - short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW); - short keyBlob = KMArray.instance((short)1); - KMArray.cast(keyBlob).add((short)0, KMByteBlob.instance(aesKeySecret,(short)0,(short)16)); - byte[] blob = new byte[256]; - short len = encoder.encode(keyBlob,blob,(short)0); - keyBlob = KMByteBlob.instance(blob, (short)0, len); - arrPtr = KMArray.instance((short)3); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - arg.add((short)1, keyFormatPtr); - arg.add((short)2, keyBlob); - CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); - Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.PKCS7)); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.BLOCK_MODE, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.ECB)); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.AES); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); - cleanUp(); - } - - @Test - public void testHmacImportKeySuccess() { - init(); - byte[] hmacKeySecret = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - short arrPtr = KMArray.instance((short)5); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - short minMacLength = KMIntegerTag.instance(KMType.UINT_TAG,KMType.MIN_MAC_LENGTH, KMInteger.uint_16((short)256)); - KMArray.cast(arrPtr).add((short)0, boolTag); - KMArray.cast(arrPtr).add((short)1, keySize); - KMArray.cast(arrPtr).add((short)2, digest); - KMArray.cast(arrPtr).add((short)3, minMacLength); - KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.HMAC)); - short keyParams = KMKeyParameters.instance(arrPtr); - short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW); - short keyBlob = KMArray.instance((short)1); - KMArray.cast(keyBlob).add((short)0, KMByteBlob.instance(hmacKeySecret,(short)0,(short)16)); - byte[] blob = new byte[256]; - short len = encoder.encode(keyBlob,blob,(short)0); - keyBlob = KMByteBlob.instance(blob, (short)0, len); - arrPtr = KMArray.instance((short)3); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - arg.add((short)1, keyFormatPtr); - arg.add((short)2, keyBlob); - CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); - Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 256); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.HMAC); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); - cleanUp(); - } - - @Test - public void testRsaImportKeySuccess() { - init(); - /* - KeyPair rsaKeyPair = cryptoProvider.createRsaKeyPair(); - byte[] pub = new byte[4]; - short len = ((RSAPublicKey)rsaKeyPair.getPublic()).getExponent(pub,(short)1); - byte[] priv = new byte[256]; - byte[] mod = new byte[256]; - len = ((RSAPrivateKey)rsaKeyPair.getPrivate()).getModulus(mod,(short)0); - len = ((RSAPrivateKey)rsaKeyPair.getPrivate()).getExponent(priv,(short)0); - */ - - byte[] pub = new byte[]{0x00,0x01,0x00,0x01}; - byte[] mod = new byte[256]; - byte[] priv = new byte[256]; - short[] lengths = new short[2]; - cryptoProvider.createAsymmetricKey(KMType.RSA,priv,(short)0,(short)256,mod,(short)0, (short)256,lengths); - short arrPtr = KMArray.instance((short)6); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)2048)); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - short rsaPubExpTag = KMIntegerTag.instance(KMType.ULONG_TAG,KMType.RSA_PUBLIC_EXPONENT, - KMInteger.uint_32(pub, (short)0)); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.RSA_PSS); - short padding = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - KMArray.cast(arrPtr).add((short)0, boolTag); - KMArray.cast(arrPtr).add((short)1, keySize); - KMArray.cast(arrPtr).add((short)2, digest); - KMArray.cast(arrPtr).add((short)3, rsaPubExpTag); - KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.RSA)); - KMArray.cast(arrPtr).add((short)5, padding); - short keyParams = KMKeyParameters.instance(arrPtr); - short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW);// Note: VTS uses PKCS8 - short keyBlob = KMArray.instance((short)2); - KMArray.cast(keyBlob).add((short)0, KMByteBlob.instance(priv,(short)0,(short)256)); - KMArray.cast(keyBlob).add((short)1, KMByteBlob.instance(mod,(short)0,(short)256)); - byte[] blob = new byte[620]; - short len = encoder.encode(keyBlob,blob,(short)0); - keyBlob = KMByteBlob.instance(blob, (short)0, len); - arrPtr = KMArray.instance((short)3); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - arg.add((short)1, keyFormatPtr); - arg.add((short)2, keyBlob); - CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); - Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 2048); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.RSA_PSS)); - tag = KMKeyParameters.findTag(KMType.ULONG_TAG, KMType.RSA_PUBLIC_EXPONENT, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getSignificantShort(), 0x01); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 0x01); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.RSA); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); - cleanUp(); - } - - @Test - public void testDeviceLocked(){ - init(); - byte[] hmacKey = new byte[32]; - cryptoProvider.newRandomNumber(hmacKey,(short)0,(short)32); - KMRepository.instance().initComputedHmac(hmacKey,(short)0,(short)32); - // generate aes key with unlocked_device_required - short aesKey = generateAesDesKey(KMType.AES,(short)128,null,null, true); - short keyBlobPtr = KMArray.cast(aesKey).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), - KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - // encrypt something - short inParams = getAesDesParams(KMType.AES, KMType.ECB, KMType.PKCS7, null); - byte[] plainData= "Hello World 123!".getBytes(); - short ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.ENCRYPT, - KMKeyParameters.instance(inParams), - (short)0,null,false, false - ); - keyBlobPtr = KMArray.cast(ret).get((short)2); - byte[] cipherData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - cipherData,(short)0, (short)cipherData.length); - // create verification token - short verToken = KMVerificationToken.instance(); - KMVerificationToken.cast(verToken).setTimestamp(KMInteger.uint_16((short)1)); - verToken = signVerificationToken(verToken); - // device locked request - deviceLock(verToken); - // decrypt should fail - inParams = getAesDesParams(KMType.AES, KMType.ECB, KMType.PKCS7, null); - short beginResp = begin(KMType.DECRYPT, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), KMKeyParameters.instance(inParams), (short)0); - Assert.assertEquals(beginResp,KMError.DEVICE_LOCKED); - short hwToken = KMHardwareAuthToken.instance(); - KMHardwareAuthToken.cast(hwToken).setTimestamp(KMInteger.uint_16((byte)2)); - KMHardwareAuthToken.cast(hwToken).setHwAuthenticatorType(KMEnum.instance(KMType.USER_AUTH_TYPE, (byte)KMType.PASSWORD)); - inParams = getAesDesParams(KMType.AES, KMType.ECB, KMType.PKCS7, null); - hwToken = signHwToken(hwToken); - ret = processMessage(cipherData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.DECRYPT, - KMKeyParameters.instance(inParams),hwToken,null,false, false - ); - ret = KMArray.cast(ret).get((short)0); - Assert.assertEquals(KMInteger.cast(ret).getShort(), KMError.OK); - cleanUp(); - } - - private short signHwToken(short hwToken){ - short len = 0; - byte[] scratchPad = new byte[256]; - // add 0 - Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); - len = 1; - // concatenate challenge - 8 bytes - short ptr = KMHardwareAuthToken.cast(hwToken).getChallenge(); - KMInteger.cast(ptr) - .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); - len += 8; - // concatenate user id - 8 bytes - ptr = KMHardwareAuthToken.cast(hwToken).getUserId(); - KMInteger.cast(ptr) - .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); - len += 8; - // concatenate authenticator id - 8 bytes - ptr = KMHardwareAuthToken.cast(hwToken).getAuthenticatorId(); - KMInteger.cast(ptr) - .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); - len += 8; - // concatenate authenticator type - 4 bytes - ptr = KMHardwareAuthToken.cast(hwToken).getHwAuthenticatorType(); - scratchPad[(short) (len + 3)] = KMEnum.cast(ptr).getVal(); - len += 4; - // concatenate timestamp -8 bytes - ptr = KMHardwareAuthToken.cast(hwToken).getTimestamp(); - KMInteger.cast(ptr) - .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); - len += 8; - // hmac the data -/* HMACKey key = - cryptoProvider.createHMACKey( - KMRepository.instance().getComputedHmacKey(), - (short) 0, - (short) KMRepository.instance().getComputedHmacKey().length); - - */ - byte[] mac = new byte[32]; - /* - len = - cryptoProvider.hmacSign(key, scratchPad, (short) 0, len, - mac, - (short)0); - */ - short key = KMRepository.instance().getComputedHmacKey(); - cryptoProvider.hmacSign( - KMByteBlob.cast(key).getBuffer(), - KMByteBlob.cast(key).getStartOff(), - KMByteBlob.cast(key).length(), - scratchPad, (short) 0, len, - mac, - (short)0); - KMHardwareAuthToken.cast(hwToken).setMac(KMByteBlob.instance(mac,(short)0,(short)mac.length)); - return hwToken; - } - private void deviceLock(short verToken) { - short req = KMArray.instance((short)2); - KMArray.cast(req).add((short)0, KMInteger.uint_8((byte)1)); - KMArray.cast(req).add((short)1, verToken); - CommandAPDU apdu = encodeApdu((byte)INS_DEVICE_LOCKED_CMD,req); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 1); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - byte[] respBuf = response.getBytes(); - Assert.assertEquals(respBuf[0],KMError.OK); - } - - private short signVerificationToken(short verToken) { - byte[] scratchPad = new byte[256]; - byte[] authVer = "Auth Verification".getBytes(); - //print(authVer,(short)0,(short)authVer.length); - // concatenation length will be 37 + length of verified parameters list - which is typically empty - Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); - short params = KMVerificationToken.cast(verToken).getParametersVerified(); - // Add "Auth Verification" - 17 bytes. - Util.arrayCopy(authVer,(short)0, scratchPad, (short)0, (short)authVer.length); - short len = (short)authVer.length; - // concatenate challenge - 8 bytes - short ptr = KMVerificationToken.cast(verToken).getChallenge(); - KMInteger.cast(ptr) - .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); - len += 8; - // concatenate timestamp -8 bytes - ptr = KMVerificationToken.cast(verToken).getTimestamp(); - KMInteger.cast(ptr) - .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); - len += 8; - // concatenate security level - 4 bytes - ptr = KMVerificationToken.cast(verToken).getSecurityLevel(); - scratchPad[(short) (len + 3)] = KMEnum.cast(ptr).getVal(); - len += 4; - // concatenate Parameters verified - blob of encoded data. - ptr = KMVerificationToken.cast(verToken).getParametersVerified(); - if (KMByteBlob.cast(ptr).length() != 0) { - len += KMByteBlob.cast(ptr).getValues(scratchPad, (short) 0); - } - // hmac the data - /* HMACKey key = - cryptoProvider.createHMACKey( - KMRepository.instance().getComputedHmacKey(), - (short) 0, - (short) KMRepository.instance().getComputedHmacKey().length); - - */ - ptr = KMVerificationToken.cast(verToken).getMac(); - byte[] mac = new byte[32]; - /*len = - cryptoProvider.hmacSign(key, scratchPad, (short) 0, len, - mac, - (short)0); - */ - short key = KMRepository.instance().getComputedHmacKey(); - cryptoProvider.hmacSign(KMByteBlob.cast(key).getBuffer(), - KMByteBlob.cast(key).getStartOff(), - KMByteBlob.cast(key).length(), - scratchPad, (short) 0, len, - mac, - (short)0); - KMVerificationToken.cast(verToken).setMac(KMByteBlob.instance(mac,(short)0,(short)mac.length)); - return verToken; - } - - @Test - public void testEcImportKeySuccess() { - init(); - /* - KeyPair ecKeyPair = cryptoProvider.createECKeyPair(); - byte[] pub = new byte[128]; - short len = ((ECPublicKey)ecKeyPair.getPublic()).getW(pub,(short)0); - byte[] priv = new byte[128]; - len = ((ECPrivateKey)ecKeyPair.getPrivate()).getS(priv,(short)0); - */ - byte[] pub = new byte[128]; - byte[] priv = new byte[128]; - short[] lengths = new short[2]; - cryptoProvider.createAsymmetricKey(KMType.EC,priv,(short)0,(short)128,pub,(short)0, (short)128,lengths); - short pubBlob = KMByteBlob.instance(pub,(short)0,lengths[1]); - short privBlob = KMByteBlob.instance(priv,(short)0,lengths[0]); - short arrPtr = KMArray.instance((short)5); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)256)); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - short ecCurve = KMEnumTag.instance(KMType.ECCURVE, KMType.P_256); - KMArray.cast(arrPtr).add((short)0, boolTag); - KMArray.cast(arrPtr).add((short)1, keySize); - KMArray.cast(arrPtr).add((short)2, digest); - KMArray.cast(arrPtr).add((short)3, ecCurve); - KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.EC)); - short keyParams = KMKeyParameters.instance(arrPtr); - short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW);// Note: VTS uses PKCS8 - short keyBlob = KMArray.instance((short)2); - KMArray.cast(keyBlob).add((short)0, privBlob); - KMArray.cast(keyBlob).add((short)1, pubBlob); - byte[] blob = new byte[128]; - short len = encoder.encode(keyBlob,blob,(short)0); - keyBlob = KMByteBlob.instance(blob, (short)0, len); - arrPtr = KMArray.instance((short)3); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - arg.add((short)1, keyFormatPtr); - arg.add((short)2, keyBlob); - CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short blobArr = extractKeyBlobArray(KMArray.cast(ret).get((short)1)); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); - Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 256); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ECCURVE, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.P_256); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.EC); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); - cleanUp(); - } - - private short extractKeyBlobArray(short keyBlob) { - short ret = KMArray.instance((short) 5); - KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_SECRET, KMByteBlob.exp()); - KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_AUTH_TAG, KMByteBlob.exp()); - KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_NONCE, KMByteBlob.exp()); - short ptr = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_KEYCHAR, ptr); - KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_PUB_KEY, KMByteBlob.exp()); - ret = - decoder.decodeArray( - ret, - KMByteBlob.cast(keyBlob).getBuffer(), - KMByteBlob.cast(keyBlob).getStartOff(), - KMByteBlob.cast(keyBlob).length()); - short len = KMArray.cast(ret).length(); - ptr = KMArray.cast(ret).get((short)4); -// print(KMByteBlob.cast(ptr).getBuffer(),KMByteBlob.cast(ptr).getStartOff(),KMByteBlob.cast(ptr).length()); - return ret; - } - - @Test - public void testRsaGenerateKeySuccess() { - init(); - short ret = generateRsaKey(null, null); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 2048); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.DIGEST_NONE)); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.RSA_PKCS1_1_5_ENCRYPT)); - tag = KMKeyParameters.findTag(KMType.ULONG_TAG, KMType.RSA_PUBLIC_EXPONENT, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getSignificantShort(), 0x01); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 0x01); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.RSA); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.GENERATED); - cleanUp(); - } - - private short generateRsaKey(byte[] clientId, byte[] appData){ - byte[] activeAndCreationDateTime = {0,0,0x01,0x73,0x51,0x7C,(byte)0xCC,0x00}; - short tagCount = 11; - if(clientId != null) tagCount++; - if(appData != null) tagCount++; - short arrPtr = KMArray.instance(tagCount); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)2048)); - short byteBlob = KMByteBlob.instance((short)3); - KMByteBlob.cast(byteBlob).add((short)0, KMType.DIGEST_NONE); - KMByteBlob.cast(byteBlob).add((short)1, KMType.SHA2_256); - KMByteBlob.cast(byteBlob).add((short)2, KMType.SHA1); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - byteBlob = KMByteBlob.instance((short)5); - KMByteBlob.cast(byteBlob).add((short)0, KMType.RSA_PKCS1_1_5_ENCRYPT); - KMByteBlob.cast(byteBlob).add((short)1, KMType.RSA_PKCS1_1_5_SIGN); - KMByteBlob.cast(byteBlob).add((short)2, KMType.RSA_OAEP); - KMByteBlob.cast(byteBlob).add((short)3, KMType.RSA_PSS); - KMByteBlob.cast(byteBlob).add((short)4, KMType.PADDING_NONE); - short padding = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - byteBlob = KMByteBlob.instance((short)5); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SIGN); - KMByteBlob.cast(byteBlob).add((short)1, KMType.VERIFY); - KMByteBlob.cast(byteBlob).add((short)2, KMType.ENCRYPT); - KMByteBlob.cast(byteBlob).add((short)3, KMType.DECRYPT); - KMByteBlob.cast(byteBlob).add((short)4, KMType.WRAP_KEY); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - byte[] pub = {0,1,0,1}; - short rsaPubExpTag = KMIntegerTag.instance(KMType.ULONG_TAG,KMType.RSA_PUBLIC_EXPONENT, KMInteger.uint_32(pub, (short)0)); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.INCLUDE_UNIQUE_ID)); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.RESET_SINCE_ID_ROTATION)); - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, digest); - KMArray.cast(arrPtr).add(tagIndex++, rsaPubExpTag); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.RSA)); - KMArray.cast(arrPtr).add(tagIndex++, padding); - short dateTag = KMInteger.uint_64(activeAndCreationDateTime,(short)0); - KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.DATE_TAG,KMType.ACTIVE_DATETIME,dateTag)); - KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.DATE_TAG,KMType.CREATION_DATETIME,dateTag)); - - if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); - if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - arrPtr = KMArray.instance((short)1); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - return ret; - } - - private short generateAttestationKey(){ - // 15th July 2020 00.00.00 - byte[] activeAndCreationDateTime = {0,0,0x01,0x73,0x51,0x7C,(byte)0xCC,0x00}; - short tagCount = 11; - short arrPtr = KMArray.instance(tagCount); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)2048)); - short byteBlob = KMByteBlob.instance((short)3); - KMByteBlob.cast(byteBlob).add((short)0, KMType.DIGEST_NONE); - KMByteBlob.cast(byteBlob).add((short)1, KMType.SHA2_256); - KMByteBlob.cast(byteBlob).add((short)2, KMType.SHA1); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.RSA_PKCS1_1_5_SIGN); - short padding = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ATTEST_KEY); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - byte[] pub = {0,1,0,1}; - short rsaPubExpTag = KMIntegerTag.instance(KMType.ULONG_TAG,KMType.RSA_PUBLIC_EXPONENT, KMInteger.uint_32(pub, (short)0)); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.INCLUDE_UNIQUE_ID)); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.RESET_SINCE_ID_ROTATION)); - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, digest); - KMArray.cast(arrPtr).add(tagIndex++, rsaPubExpTag); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.RSA)); - KMArray.cast(arrPtr).add(tagIndex++, padding); - short dateTag = KMInteger.uint_64(activeAndCreationDateTime,(short)0); - KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.ULONG_TAG,KMType.ACTIVE_DATETIME,dateTag)); - KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.ULONG_TAG,KMType.CREATION_DATETIME,dateTag)); - short keyParams = KMKeyParameters.instance(arrPtr); - arrPtr = KMArray.instance((short)1); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - return ret; - } - - @Test - public void testEcGenerateKeySuccess() { - init(); - short ret = generateEcKey(null, null); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 256); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.DIGEST_NONE)); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.EC); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.GENERATED); - cleanUp(); - } - public short generateEcKey(byte[] clientId, byte[] appData) { - byte[] activeAndCreationDateTime = {0,0,0x01,0x73,0x51,0x7C,(byte)0xCC,0x00}; - short tagCount = 6; - if(clientId != null) tagCount++; - if(appData != null) tagCount++; - short arrPtr = KMArray.instance(tagCount); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)256)); - short byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.DIGEST_NONE); - KMByteBlob.cast(byteBlob).add((short)1, KMType.SHA2_256); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SIGN); - KMByteBlob.cast(byteBlob).add((short)1, KMType.VERIFY); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, digest); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.EC)); - short dateTag = KMInteger.uint_64(activeAndCreationDateTime,(short)0); - KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.DATE_TAG,KMType.CREATION_DATETIME,dateTag)); - if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); - if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - arrPtr = KMArray.instance((short)1); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - return ret; - } - - @Test - public void testHmacGenerateKeySuccess() { - init(); - short ret = generateHmacKey(null, null); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 160); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.HMAC); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.GENERATED); - cleanUp(); - } - public short generateHmacKey(byte[] clientId, byte[] appData){ - short tagCount = 6; - if(clientId != null) tagCount++; - if(appData != null) tagCount++; - short arrPtr = KMArray.instance(tagCount); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); - short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.SIGN); - KMByteBlob.cast(byteBlob).add((short)1, KMType.VERIFY); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short minMacLen = KMIntegerTag.instance(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, KMInteger.uint_16((short)/*256*/160)); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, minMacLen); - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, digest); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.HMAC)); - if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); - if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - arrPtr = KMArray.instance((short)1); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - return ret; - } - public short generateAesDesKey(byte alg, short keysize, byte[] clientId, byte[] appData, boolean unlockReqd) { - short tagCount = 7; - if(clientId != null) tagCount++; - if(appData != null) tagCount++; - if(unlockReqd)tagCount++; - short arrPtr = KMArray.instance(tagCount); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16(keysize)); - short byteBlob = KMByteBlob.instance((short)3); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ECB); - KMByteBlob.cast(byteBlob).add((short)1, KMType.CBC); - KMByteBlob.cast(byteBlob).add((short)2, KMType.CTR); - short blockModeTag = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.PKCS7); - KMByteBlob.cast(byteBlob).add((short)1, KMType.PADDING_NONE); - short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ENCRYPT); - KMByteBlob.cast(byteBlob).add((short)1, KMType.DECRYPT); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, blockModeTag); - KMArray.cast(arrPtr).add(tagIndex++, paddingMode); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, alg)); - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.CALLER_NONCE)); - if(unlockReqd)KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.UNLOCKED_DEVICE_REQUIRED)); - if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); - if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - arrPtr = KMArray.instance((short)1); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - return ret; - } - public short generateAesGcmKey(short keysize, byte[] clientId, byte[] appData) { - short tagCount = 8; - if(clientId != null) tagCount++; - if(appData != null) tagCount++; - short arrPtr = KMArray.instance(tagCount); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16(keysize)); - short macLength = KMIntegerTag.instance(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, KMInteger.uint_16((short)96)); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.GCM); - short blockModeTag = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, KMType.PADDING_NONE); - short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ENCRYPT); - KMByteBlob.cast(byteBlob).add((short)1, KMType.DECRYPT); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, macLength); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, blockModeTag); - KMArray.cast(arrPtr).add(tagIndex++, paddingMode); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.AES)); - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.CALLER_NONCE)); - if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); - if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - arrPtr = KMArray.instance((short)1); - KMArray arg = KMArray.cast(arrPtr); - arg.add((short) 0, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - return ret; - } - - @Test - public void testComputeHmacParams(){ - init(); - // Get Hmac parameters - short ret = getHmacSharingParams(); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - KMHmacSharingParameters params = KMHmacSharingParameters.cast(KMArray.cast(ret).get((short)1)); - short seed = params.getSeed(); - short nonce = params.getNonce(); - - short params1 = KMHmacSharingParameters.instance(); - KMHmacSharingParameters.cast(params1).setSeed(KMByteBlob.instance((short)0)); - short num = KMByteBlob.instance((short)32); - Util.arrayCopyNonAtomic( - KMByteBlob.cast(nonce).getBuffer(), - KMByteBlob.cast(nonce).getStartOff(), - KMByteBlob.cast(num).getBuffer(), - KMByteBlob.cast(num).getStartOff(), - KMByteBlob.cast(num).length()); - // cryptoProvider.newRandomNumber( -// KMByteBlob.cast(num).getBuffer(), -// KMByteBlob.cast(num).getStartOff(), -// KMByteBlob.cast(num).length()); - KMHmacSharingParameters.cast(params1).setNonce(num); - short params2 = KMHmacSharingParameters.instance(); - KMHmacSharingParameters.cast(params2).setSeed(KMByteBlob.instance((short)0)); - num = KMByteBlob.instance((short)32); - cryptoProvider.newRandomNumber( - KMByteBlob.cast(num).getBuffer(), - KMByteBlob.cast(num).getStartOff(), - KMByteBlob.cast(num).length()); - KMHmacSharingParameters.cast(params2).setNonce(num); - short arr = KMArray.instance((short)2); - KMArray.cast(arr).add((short)0, params1); - KMArray.cast(arr).add((short)1,params2); - short arrPtr = KMArray.instance((short)1); - KMArray.cast(arrPtr).add((short)0,arr); - CommandAPDU apdu = encodeApdu((byte)INS_COMPUTE_SHARED_HMAC_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - Assert.assertEquals(0x9000, response.getSW()); - ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - - cleanUp(); - } - @Test - public void testGetHmacSharingParams(){ - init(); - CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_GET_HMAC_SHARING_PARAM_CMD, 0x40, 0x00); - //print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(commandAPDU); - KMDecoder dec = new KMDecoder(); - short ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - short inst = KMHmacSharingParameters.exp(); - KMArray.cast(ret).add((short) 1, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - KMHmacSharingParameters params = KMHmacSharingParameters.cast(KMArray.cast(ret).get((short)1)); - short seed = params.getSeed(); - short nonce = params.getNonce(); - Assert.assertTrue(KMByteBlob.cast(seed).length() == 0); - Assert.assertTrue(KMByteBlob.cast(nonce).length() == 32); - //print(seed); - //print(nonce); - Assert.assertEquals(error, KMError.OK); - cleanUp(); - } - public short getHmacSharingParams(){ - CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_GET_HMAC_SHARING_PARAM_CMD, 0x40, 0x00); - //print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(commandAPDU); - KMDecoder dec = new KMDecoder(); - short ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - short inst = KMHmacSharingParameters.exp(); - KMArray.cast(ret).add((short) 1, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - return ret; - } - - @Test - public void testImportWrappedKey(){ - init(); - byte[] wrappedKey = new byte[16]; - cryptoProvider.newRandomNumber(wrappedKey,(short)0,(short)16); - byte[] encWrappedKey = new byte[16]; - //AESKey transportKey = cryptoProvider.createAESKey((short)256); - byte[] transportKeyMaterial = new byte[32]; - cryptoProvider.newRandomNumber(transportKeyMaterial,(short)0,(short)32); - //transportKey.setKey(transportKeyMaterial,(short)0); - byte[] nonce = new byte[12]; - cryptoProvider.newRandomNumber(nonce,(short)0,(short)12); - byte[] authData = "Auth Data".getBytes(); - byte[] authTag = new byte[12]; - cryptoProvider.aesGCMEncrypt(transportKeyMaterial,(short)0,(short)32,wrappedKey, - (short)0,(short)16,encWrappedKey,(short)0, - nonce,(short)0, (short)12,authData,(short)0,(short)authData.length, - authTag, (short)0, (short)12); - byte[] maskingKey = {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0}; - byte[] maskedTransportKey = new byte[32]; - for(int i=0; i< maskingKey.length;i++){ - maskedTransportKey[i] = (byte)(transportKeyMaterial[i] ^ maskingKey[i]); - } - short rsaKeyArr = generateRsaKey(null,null); - short keyBlobPtr = KMArray.cast(rsaKeyArr).get((short)1); - byte[] wrappingKeyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), - KMByteBlob.cast(keyBlobPtr).getStartOff(), - wrappingKeyBlob,(short)0, (short)wrappingKeyBlob.length); - short inParams = getRsaParams(KMType.SHA2_256, KMType.RSA_OAEP); - short ret = processMessage(maskedTransportKey, - KMByteBlob.instance(wrappingKeyBlob,(short)0, (short)wrappingKeyBlob.length), - KMType.ENCRYPT, - KMKeyParameters.instance(inParams), - (short)0,null,false,false - ); - keyBlobPtr = KMArray.cast(ret).get((short)2); - byte[] encTransportKey = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - encTransportKey,(short)0, (short)encTransportKey.length); - short tagCount = 7; - short arrPtr = KMArray.instance(tagCount); - short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); - short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); - short byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ECB); - KMByteBlob.cast(byteBlob).add((short)1, KMType.CBC); - short blockModeTag = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.PKCS7); - KMByteBlob.cast(byteBlob).add((short)1, KMType.PADDING_NONE); - short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); - byteBlob = KMByteBlob.instance((short)2); - KMByteBlob.cast(byteBlob).add((short)0, KMType.ENCRYPT); - KMByteBlob.cast(byteBlob).add((short)1, KMType.DECRYPT); - short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); - short tagIndex = 0; - KMArray.cast(arrPtr).add(tagIndex++, boolTag); - KMArray.cast(arrPtr).add(tagIndex++, keySize); - KMArray.cast(arrPtr).add(tagIndex++, blockModeTag); - KMArray.cast(arrPtr).add(tagIndex++, paddingMode); - KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.AES)); - KMArray.cast(arrPtr).add(tagIndex++, purpose); - KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.CALLER_NONCE)); - short keyParams = KMKeyParameters.instance(arrPtr); - short nullParams = KMArray.instance((short)0); - nullParams = KMKeyParameters.instance(nullParams); - short arr = KMArray.instance((short)12); - KMArray.cast(arr).add((short) 0, keyParams); // Key Params of wrapped key - KMArray.cast(arr).add((short) 1, KMEnum.instance(KMType.KEY_FORMAT,KMType.RAW)); // Key Format - KMArray.cast(arr).add((short) 2, KMByteBlob.instance(encWrappedKey,(short)0,(short)encWrappedKey.length)); // Wrapped Import Key Blob - KMArray.cast(arr).add((short) 3, KMByteBlob.instance(authTag,(short)0,(short)authTag.length)); // Auth Tag - KMArray.cast(arr).add((short) 4, KMByteBlob.instance(nonce,(short)0,(short)nonce.length)); // IV - Nonce - KMArray.cast(arr).add((short) 5, KMByteBlob.instance(encTransportKey,(short)0,(short)encTransportKey.length)); // Encrypted Transport Key - KMArray.cast(arr).add((short) 6, KMByteBlob.instance(wrappingKeyBlob,(short)0, (short)wrappingKeyBlob.length)); // Wrapping Key KeyBlob - KMArray.cast(arr).add((short) 7, KMByteBlob.instance(maskingKey,(short)0,(short)maskingKey.length)); // Masking Key - KMArray.cast(arr).add((short) 8, nullParams); // Un-wrapping Params - KMArray.cast(arr).add((short) 9, KMByteBlob.instance(authData,(short)0,(short)authData.length)); // Wrapped Key ASSOCIATED AUTH DATA - KMArray.cast(arr).add((short) 10, KMInteger.uint_8((byte)0)); // Password Sid - KMArray.cast(arr).add((short) 11, KMInteger.uint_8((byte)0)); // Biometric Sid - CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_WRAPPED_KEY_CMD, arr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - Assert.assertEquals(0x9000, response.getSW()); - Assert.assertEquals(error, KMError.OK); - short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); - Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); - tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); - Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.PKCS7)); - tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.BLOCK_MODE, hwParams); - Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.ECB)); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.AES); - tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); - Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.SECURELY_IMPORTED); - cleanUp(); - } - - @Test - public void testGetKeyCharacteristicsWithIdDataSuccess() { - init(); - byte[] clientId = "clientId".getBytes(); - byte[] appData = "appData".getBytes(); - short ret = generateRsaKey(clientId,appData); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - short keyBlob = KMArray.cast(ret).get((short)1); - - short arrPtr = KMArray.instance((short)3); - KMArray.cast(arrPtr).add((short)0, keyBlob); - KMArray.cast(arrPtr).add((short)1, KMByteBlob.instance(clientId,(short)0, (short)clientId.length)); - KMArray.cast(arrPtr).add((short)2, KMByteBlob.instance(appData,(short)0, (short)appData.length)); - CommandAPDU apdu = encodeApdu((byte)INS_GET_KEY_CHARACTERISTICS_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 1, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - cleanUp(); - } - - @Test - public void testGetKeyCharacteristicsSuccess() { - init(); - short ret = generateRsaKey(null, null); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - short keyBlob = KMArray.cast(ret).get((short)1); - - short arrPtr = KMArray.instance((short)3); - KMArray.cast(arrPtr).add((short)0, keyBlob); - KMArray.cast(arrPtr).add((short)1, KMByteBlob.instance((short)0)); - KMArray.cast(arrPtr).add((short)2, KMByteBlob.instance((short)0)); - CommandAPDU apdu = encodeApdu((byte)INS_GET_KEY_CHARACTERISTICS_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 1, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - cleanUp(); - } - - @Test - public void testDeleteKeySuccess() { - init(); - short ret = generateRsaKey(null, null); - short keyBlobPtr = KMArray.cast(ret).get((short)1); - byte[] keyBlob = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - short len = KMByteBlob.cast(keyBlobPtr).getValues(keyBlob, (short)0); - ret = getKeyCharacteristics(keyBlobPtr); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - ret = deleteKey(KMByteBlob.instance(keyBlob,(short)0,(short)keyBlob.length)); - Assert.assertEquals(ret, KMError.OK); -/* ret = getKeyCharacteristics(KMByteBlob.instance(keyBlob,(short)0,(short)keyBlob.length)); - short err = KMByteBlob.cast(ret).get((short)1); - Assert.assertEquals(KMError.INVALID_KEY_BLOB,err); - - */ - cleanUp(); - } - - @Test - public void testDeleteAllKeySuccess() { - init(); - short ret1 = generateRsaKey(null, null); - short keyBlobPtr = KMArray.cast(ret1).get((short)1); - byte[] keyBlob1 = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - short len = KMByteBlob.cast(keyBlobPtr).getValues(keyBlob1, (short)0); - short ret2 = generateRsaKey(null, null); - keyBlobPtr = KMArray.cast(ret2).get((short)1); - byte[] keyBlob2 = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - len = KMByteBlob.cast(keyBlobPtr).getValues(keyBlob2, (short)0); - CommandAPDU apdu = new CommandAPDU(0x80, INS_DELETE_ALL_KEYS_CMD, 0x40, 0x00); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - byte[] respBuf = response.getBytes(); - Assert.assertEquals(respBuf[0], KMError.OK); -/* short ret = getKeyCharacteristics(KMByteBlob.instance(keyBlob1,(short)0,(short)keyBlob1.length)); - short err = KMByteBlob.cast(ret).get((short)1); - Assert.assertEquals(KMError.INVALID_KEY_BLOB,err); - ret = getKeyCharacteristics(KMByteBlob.instance(keyBlob2,(short)0,(short)keyBlob2.length)); - err = KMByteBlob.cast(ret).get((short)1); - Assert.assertEquals(KMError.INVALID_KEY_BLOB,err); - - */ - cleanUp(); - } - - private short deleteKey(short keyBlob) { - short arrPtr = KMArray.instance((short)1); - KMArray.cast(arrPtr).add((short)0, keyBlob); - CommandAPDU apdu = encodeApdu((byte)INS_DELETE_KEY_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - byte[] respBuf = response.getBytes(); - return respBuf[0]; - } - - private short abort(short opHandle) { - short arrPtr = KMArray.instance((short)1); - KMArray.cast(arrPtr).add((short)0, opHandle); - CommandAPDU apdu = encodeApdu((byte)INS_ABORT_OPERATION_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - byte[] respBuf = response.getBytes(); - return respBuf[0]; - } - - public short getKeyCharacteristics(short keyBlob){ - short arrPtr = KMArray.instance((short)3); - KMArray.cast(arrPtr).add((short)0, keyBlob); - KMArray.cast(arrPtr).add((short)1, KMByteBlob.instance((short)0)); - KMArray.cast(arrPtr).add((short)2, KMByteBlob.instance((short)0)); - CommandAPDU apdu = encodeApdu((byte)INS_GET_KEY_CHARACTERISTICS_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 1, inst); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - if( len > 5) - ret = decoder.decode(ret, respBuf, (short) 0, len); - else - ret = KMByteBlob.instance(respBuf, (short)0, len); - return ret; - } - - @Test - public void testWithAesGcmWithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.GCM, KMType.PADDING_NONE,true); - cleanUp(); - } - @Test - public void testWithAesEcbPkcs7WithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PKCS7,true); - cleanUp(); - } - - @Test - public void testWithAesCtrNoPadWithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.CTR, KMType.PADDING_NONE,true); - cleanUp(); - } - - @Test - public void testWithAesCtrNoPad(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.CTR, KMType.PADDING_NONE,false); - cleanUp(); - } - - @Test - public void testWithAesEcbNoPadWithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PADDING_NONE,true); - cleanUp(); - } - @Test - public void testWithDesEcbPkcs7WithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PKCS7,true); - cleanUp(); - } - @Test - public void testWithDesEcbNoPadWithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PADDING_NONE,true); - cleanUp(); - } - @Test - public void testWithAesCbcPkcs7WithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PKCS7,true); - cleanUp(); - } - @Test - public void testWithAesCbcNoPadWithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PADDING_NONE,true); - cleanUp(); - } - @Test - public void testWithDesCbcPkcs7WithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PKCS7,true); - cleanUp(); - } - @Test - public void testWithDesCbcNoPadWithUpdate(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PADDING_NONE,true); - cleanUp(); - } - - @Test - public void testWithAesEcbPkcs7(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PKCS7,false); - cleanUp(); - } - @Test - public void testWithAesCbcPkcs7(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PKCS7,false); - cleanUp(); - } - @Test - public void testWithAesEcbNoPad(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PADDING_NONE,false); - cleanUp(); - } - - @Test - public void testWithAesCbcNoPad(){ - init(); - testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PADDING_NONE,false); - cleanUp(); - } - - @Test - public void testWithDesCbcPkcs7(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PKCS7,false); - cleanUp(); - } - - @Test - public void testWithDesCbcNoPad(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PADDING_NONE,false); - cleanUp(); - } - @Test - public void testWithDesEcbNoPad(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PADDING_NONE,false); - cleanUp(); - } - @Test - public void testWithDesEcbPkcs7(){ - init(); - testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PKCS7,false); - cleanUp(); - } - - @Test - public void testWithRsa256Oaep(){ - init(); - testEncryptDecryptWithRsa(KMType.SHA2_256, KMType.RSA_OAEP); - cleanUp(); - } - @Test - public void testWithRsaSha1Oaep(){ - init(); - testEncryptDecryptWithRsa(KMType.SHA1, KMType.RSA_OAEP); - cleanUp(); - } - - @Test - public void testWithRsaNonePkcs1(){ - init(); - testEncryptDecryptWithRsa(KMType.DIGEST_NONE, KMType.RSA_PKCS1_1_5_ENCRYPT); - cleanUp(); - } - - @Test - public void testWithRsaNoneNoPad(){ - init(); - testEncryptDecryptWithRsa(KMType.DIGEST_NONE, KMType.PADDING_NONE); - cleanUp(); - } - - // TODO Signing with no digest is not supported by crypto provider or javacard - @Test - public void testSignWithRsaNoneNoPad(){ - init(); - testSignVerifyWithRsa(KMType.DIGEST_NONE, KMType.PADDING_NONE,false, false); - cleanUp(); - } - - @Test - public void testSignWithRsaNonePkcs1(){ - init(); - testSignVerifyWithRsa(KMType.DIGEST_NONE, KMType.RSA_PKCS1_1_5_SIGN,false, false); - cleanUp(); - } - - @Test - public void testSignVerifyWithHmacSHA256WithUpdate(){ - init(); - testSignVerifyWithHmac(KMType.SHA2_256, true); - cleanUp(); - } - - @Test - public void testSignVerifyWithHmacSHA256(){ - init(); - testSignVerifyWithHmac(KMType.SHA2_256, false); - cleanUp(); - } - - @Test - public void testSignVerifyWithEcdsaSHA256WithUpdate(){ - init(); - testSignVerifyWithEcdsa(KMType.SHA2_256, true); - cleanUp(); - } - @Test - public void testSignVerifyWithEcdsaSHA256(){ - init(); - testSignVerifyWithEcdsa(KMType.SHA2_256, false); - cleanUp(); - } - @Test - public void testSignVerifyWithRsaSHA256Pkcs1(){ - init(); - testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PKCS1_1_5_SIGN,false, true); - cleanUp(); - } - @Test - public void testSignVerifyWithRsaSHA256Pss(){ - init(); - testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PSS,false, true); - cleanUp(); - } - - @Test - public void testSignVerifyWithRsaSHA256Pkcs1WithUpdate(){ - init(); - testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PKCS1_1_5_SIGN,true, true); - cleanUp(); - } - - @Test - public void testProvisionSuccess(){ - AID appletAID1 = AIDUtil.create("A000000062"); - simulator.installApplet(appletAID1, KMKeymasterApplet.class); - // Select applet - simulator.selectApplet(appletAID1); - // provision attest key - provisionCmd(simulator); - cleanUp(); - } - - @Test - public void testAttestRsaKey(){ - init(); - short key = generateRsaKey(null,null); - short keyBlobPtr = KMArray.cast(key).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic( - KMByteBlob.cast(keyBlobPtr).getBuffer(), - KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - testAttestKey(keyBlob); - cleanUp(); - } - - @Test - public void testAttestEcKey(){ - init(); - short key = generateEcKey(null,null); - short keyBlobPtr = KMArray.cast(key).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic( - KMByteBlob.cast(keyBlobPtr).getBuffer(), - KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - testAttestKey(keyBlob); - cleanUp(); - } - - public void testAttestKey(byte[] keyBlob){ - /* - short key = generateRsaKey(null,null); - short keyBlobPtr = KMArray.cast(key).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic( - KMByteBlob.cast(keyBlobPtr).getBuffer(), - KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - */ - short arrPtr = KMArray.instance((short)2); - KMArray.cast(arrPtr).add((short)0, KMByteTag.instance(KMType.ATTESTATION_APPLICATION_ID, - KMByteBlob.instance(attAppId,(short)0,(short)attAppId.length))); - KMArray.cast(arrPtr).add((short)1, KMByteTag.instance(KMType.ATTESTATION_CHALLENGE, - KMByteBlob.instance(attChallenge,(short)0,(short)attChallenge.length))); - short keyParams = KMKeyParameters.instance(arrPtr); - short args = KMArray.instance((short)2); - KMArray.cast(args).add((short)0, KMByteBlob.instance(keyBlob,(short)0,(short)keyBlob.length)); - KMArray.cast(args).add((short)1, keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_ATTEST_KEY_CMD, args); - //print(apdu.getBytes(),(short)0,(short)apdu.getBytes().length); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 2); - short arrBlobs = KMArray.instance((short)1); - KMArray.cast(arrBlobs).add((short)0, KMByteBlob.exp()); - KMArray.cast(ret).add((short)0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, arrBlobs); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - //(respBuf,(short)0,(short)respBuf.length); - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - arrBlobs = KMArray.cast(ret).get((short)1); - short cert = KMArray.cast(arrBlobs).get((short)0); - //printCert(KMByteBlob.cast(cert).getBuffer(),KMByteBlob.cast(cert).getStartOff(),KMByteBlob.cast(cert).length()); - } - - @Test - public void testUpgradeKey(){ - init(); - short ret = generateHmacKey(null, null); - short keyBlobPtr = KMArray.cast(ret).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - short osVersion = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_VERSION,hwParams); - osVersion = KMIntegerTag.cast(osVersion).getValue(); - short osPatch = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_PATCH_LEVEL,hwParams); - osPatch = KMIntegerTag.cast(osPatch).getValue(); - Assert.assertEquals(KMInteger.cast(osVersion).getShort(), 1); - Assert.assertEquals(KMInteger.cast(osPatch).getShort(), 1); - setBootParams(simulator,(short) 2,(short)2, (short)1, (short)1); - ret = upgradeKey(KMByteBlob.instance(keyBlob, (short)0, (short)keyBlob.length),null, null); - keyBlobPtr = KMArray.cast(ret).get((short)1); - ret = getKeyCharacteristics(keyBlobPtr); - keyCharacteristics = KMArray.cast(ret).get((short)1); - hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - osVersion = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_VERSION,hwParams); - osVersion = KMIntegerTag.cast(osVersion).getValue(); - osPatch = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_PATCH_LEVEL,hwParams); - osPatch = KMIntegerTag.cast(osPatch).getValue(); - Assert.assertEquals(KMInteger.cast(osVersion).getShort(), 2); - Assert.assertEquals(KMInteger.cast(osPatch).getShort(), 2); - cleanUp(); - } - - @Test - public void testDestroyAttIds(){ - init(); - CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_DESTROY_ATT_IDS_CMD, 0x40, 0x00); - ResponseAPDU response = simulator.transmitCommand(commandAPDU); - byte[] respBuf = response.getBytes(); - Assert.assertEquals(respBuf[0], 0); - cleanUp(); - } - - private short upgradeKey(short keyBlobPtr, byte[] clientId, byte[] appData){ - short tagCount = 0; - short clientIdTag = 0; - short appDataTag = 0; - if(clientId != null) tagCount++; - if(appData != null) tagCount++; - short keyParams = KMArray.instance(tagCount); - short tagIndex=0; - if(clientId != null)KMArray.cast(keyBlobPtr).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); - if(appData != null)KMArray.cast(keyParams).add(tagIndex++, - KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); - keyParams = KMKeyParameters.instance(keyParams); - short arr = KMArray.instance((short)2); - KMArray.cast(arr).add((short)0,keyBlobPtr); - KMArray.cast(arr).add((short)1,keyParams); - CommandAPDU apdu = encodeApdu((byte)INS_UPGRADE_KEY_CMD, arr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 2); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - return ret; - } - @Test - public void testSignVerifyWithRsaSHA256PssWithUpdate(){ - init(); - testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PSS,true, true); - cleanUp(); - } - @Test - public void testAbortOperation(){ - init(); - short aesDesKeyArr = generateAesDesKey(KMType.AES, (short)128,null, null, false);; - short keyBlobPtr = KMArray.cast(aesDesKeyArr).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - byte[] nonce = new byte[16]; - cryptoProvider.newRandomNumber(nonce,(short)0,(short)16); - short inParams = getAesDesParams(KMType.AES,KMType.ECB, KMType.PKCS7, nonce); - byte[] plainData= "Hello World 123!".getBytes(); - short ret = begin(KMType.ENCRYPT, KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), KMKeyParameters.instance(inParams), (short)0); - short opHandle = KMArray.cast(ret).get((short) 2); - opHandle = KMInteger.cast(opHandle).getShort(); - abort(KMInteger.uint_16(opHandle)); - short dataPtr = KMByteBlob.instance(plainData, (short) 0, (short) plainData.length); - ret = update(KMInteger.uint_16(opHandle), dataPtr, (short) 0, (short) 0, (short) 0); - Assert.assertEquals(KMError.INVALID_OPERATION_HANDLE,ret); - cleanUp(); - } - - public void testEncryptDecryptWithAesDes(byte alg, byte blockMode, byte padding, boolean update){ - short aesDesKeyArr; - boolean aesGcmFlag = false; - if(alg == KMType.AES){ - if(blockMode == KMType.GCM){ - aesDesKeyArr = generateAesGcmKey((short)128,null,null); - aesGcmFlag = true; - } else { - aesDesKeyArr = generateAesDesKey(alg, (short) 128, null, null, false); - } - } else{ - aesDesKeyArr = generateAesDesKey(alg, (short)168,null, null, false); - } - short keyBlobPtr = KMArray.cast(aesDesKeyArr).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - byte[] nonce = new byte[16]; - cryptoProvider.newRandomNumber(nonce,(short)0,(short)16); - short inParams = getAesDesParams(alg,blockMode, padding, nonce); - byte[] plainData= "Hello World 123!".getBytes(); - if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); - //Encrypt - short ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.ENCRYPT, - KMKeyParameters.instance(inParams), - (short)0,null,update, aesGcmFlag - ); - inParams = getAesDesParams(alg,blockMode, padding, nonce); - keyBlobPtr = KMArray.cast(ret).get((short)2); - //print(keyBlobPtr); - byte[] cipherData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - cipherData,(short)0, (short)cipherData.length); - ret = processMessage(cipherData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.DECRYPT, - KMKeyParameters.instance(inParams), - (short)0,null,update, aesGcmFlag - ); - keyBlobPtr = KMArray.cast(ret).get((short)2); - //print(plainData,(short)0,(short)plainData.length); - //print(keyBlobPtr); - short equal = Util.arrayCompare(plainData,(short)0,KMByteBlob.cast(keyBlobPtr).getBuffer(), - KMByteBlob.cast(keyBlobPtr).getStartOff(),(short)plainData.length); - Assert.assertTrue(equal == 0); - } - - public void testEncryptDecryptWithRsa(byte digest, byte padding){ - short rsaKeyArr = generateRsaKey(null, null); - short keyBlobPtr = KMArray.cast(rsaKeyArr).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - short inParams = getRsaParams(digest, padding); - byte[] plainData = "Hello World 123!".getBytes(); - //Encrypt - short ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.ENCRYPT, - KMKeyParameters.instance(inParams), - (short)0,null,false, false - ); - inParams = getRsaParams(digest, padding); - keyBlobPtr = KMArray.cast(ret).get((short)2); - byte[] cipherData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - cipherData,(short)0, (short)cipherData.length); - ret = processMessage(cipherData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.DECRYPT, - KMKeyParameters.instance(inParams), - (short)0,null,false,false - ); - keyBlobPtr = KMArray.cast(ret).get((short)2); - short len = KMByteBlob.cast(keyBlobPtr).length(); - short start = KMByteBlob.cast(keyBlobPtr).getStartOff(); - short equal = Util.arrayCompare(plainData,(short)0,KMByteBlob.cast(keyBlobPtr).getBuffer(), - (short)(start+len-plainData.length),(short)plainData.length); - Assert.assertTrue(equal == 0); - } - - public void testSignVerifyWithRsa(byte digest, byte padding, boolean update, boolean verifyFlag){ - short rsaKeyArr = generateRsaKey(null, null); - short keyBlobPtr = KMArray.cast(rsaKeyArr).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - short inParams = getRsaParams(digest, padding); - byte[] plainData = "Hello World 123!".getBytes(); - if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); - //Sign - short ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.SIGN, - KMKeyParameters.instance(inParams), - (short)0,null,update,false - ); - inParams = getRsaParams(digest, padding); - keyBlobPtr = KMArray.cast(ret).get((short)2); - byte[] signatureData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - signatureData,(short)0, (short)signatureData.length); - if(verifyFlag == false) { - Assert.assertEquals(signatureData.length,256); - return; - } - ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.VERIFY, - KMKeyParameters.instance(inParams), - (short)0,signatureData,update,false - ); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - } - - public void testSignVerifyWithEcdsa(byte digest, boolean update){ - short ecKeyArr = generateEcKey(null, null); - short keyBlobPtr = KMArray.cast(ecKeyArr).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - short inParams = getEcParams(digest); - byte[] plainData = "Hello World 123!".getBytes(); - if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); - //Sign - short ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.SIGN, - KMKeyParameters.instance(inParams), - (short)0,null,update,false - ); - inParams = getEcParams(digest); - keyBlobPtr = KMArray.cast(ret).get((short)2); - byte[] signatureData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - signatureData,(short)0, (short)signatureData.length); - ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.VERIFY, - KMKeyParameters.instance(inParams), - (short)0,signatureData,update,false - ); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - } - public void testSignVerifyWithHmac(byte digest, boolean update){ - short hmacKeyArr = generateHmacKey(null, null); - short keyBlobPtr = KMArray.cast(hmacKeyArr).get((short)1); - byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - keyBlob,(short)0, (short)keyBlob.length); - short inParams = getHmacParams(digest,true); - byte[] plainData = "Hello World 123!".getBytes(); - if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); - //Sign - short ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.SIGN, - KMKeyParameters.instance(inParams), - (short)0,null,update,false - ); - inParams = getHmacParams(digest,false); - keyBlobPtr = KMArray.cast(ret).get((short)2); - byte[] signatureData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; - Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), - signatureData,(short)0, (short)signatureData.length); - ret = processMessage(plainData, - KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), - KMType.VERIFY, - KMKeyParameters.instance(inParams), - (short)0,signatureData,update,false - ); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - } - - private short getAesDesParams(byte alg, byte blockMode, byte padding, byte[] nonce) { - short inParams; - if(blockMode == KMType.GCM){ - inParams = KMArray.instance((short)5); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, blockMode); - KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob)); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, padding); - KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); - short nonceLen = 12; - byteBlob = KMByteBlob.instance(nonce,(short)0, nonceLen); - KMArray.cast(inParams).add((short)2, KMByteTag.instance(KMType.NONCE, byteBlob)); - short macLen = KMInteger.uint_16((short)128); - macLen = KMIntegerTag.instance(KMType.UINT_TAG,KMType.MAC_LENGTH,macLen); - KMArray.cast(inParams).add((short)3, macLen); - byte[] authData = "AuthData".getBytes(); - short associatedData = KMByteBlob.instance(authData,(short)0,(short)authData.length); - associatedData = KMByteTag.instance(KMType.ASSOCIATED_DATA,associatedData); - KMArray.cast(inParams).add((short)4, associatedData); - }else if(blockMode == KMType.ECB){ - inParams = KMArray.instance((short)2); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, blockMode); - KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob)); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, padding); - KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); - }else{ - inParams = KMArray.instance((short)3); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, blockMode); - KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob)); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, padding); - KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); - short nonceLen = 16; - if(alg == KMType.DES) nonceLen = 8; - byteBlob = KMByteBlob.instance(nonce,(short)0, nonceLen); - KMArray.cast(inParams).add((short)2, KMByteTag.instance(KMType.NONCE, byteBlob)); - } - return inParams; - } - - private short getRsaParams(byte digest, byte padding) { - short inParams = KMArray.instance((short)2); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, digest); - KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.DIGEST, byteBlob)); - byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, padding); - KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); - return inParams; - } - - private short getEcParams(byte digest) { - short inParams = KMArray.instance((short)1); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, digest); - KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.DIGEST, byteBlob)); - return inParams; - } - private short getHmacParams(byte digest, boolean sign) { - short paramsize = (short) (sign ? 2 : 1); - short inParams = KMArray.instance((short)paramsize); - short byteBlob = KMByteBlob.instance((short)1); - KMByteBlob.cast(byteBlob).add((short)0, digest); - KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.DIGEST, byteBlob)); - short macLength = KMIntegerTag.instance(KMType.UINT_TAG,KMType.MAC_LENGTH, KMInteger.uint_16((short)/*256*/160)); - if(sign) - KMArray.cast(inParams).add((short)1, macLength); - return inParams; - } - - public short processMessage( - byte[] data, - short keyBlob, - byte keyPurpose, - short inParams, - short hwToken, - byte[] signature, - boolean updateFlag, - boolean aesGcmFlag) { - short beginResp = begin(keyPurpose, keyBlob, inParams, hwToken); - short opHandle = KMArray.cast(beginResp).get((short) 2); - opHandle = KMInteger.cast(opHandle).getShort(); - short dataPtr = KMByteBlob.instance(data, (short) 0, (short) data.length); - short ret = KMType.INVALID_VALUE; - byte[] outputData = new byte[128]; - short len=0; - inParams = 0; - //Test - short firstDataLen =16; - if (keyPurpose == KMType.DECRYPT) { - firstDataLen = 32; - } - - //Test - - if (updateFlag) { - dataPtr = KMByteBlob.instance(data, (short) 0, (short) /*16*/firstDataLen); - if(aesGcmFlag){ - byte[] authData = "AuthData".getBytes(); - short associatedData = KMByteBlob.instance(authData,(short)0,(short)authData.length); - associatedData = KMByteTag.instance(KMType.ASSOCIATED_DATA,associatedData); - inParams = KMArray.instance((short)1); - KMArray.cast(inParams).add((short)0, associatedData); - inParams = KMKeyParameters.instance(inParams); - } - ret = update(KMInteger.uint_16(opHandle), dataPtr, inParams, (short) 0, (short) 0); - dataPtr = KMArray.cast(ret).get((short) 3); - if (KMByteBlob.cast(dataPtr).length() > 0) { - Util.arrayCopyNonAtomic( - KMByteBlob.cast(dataPtr).getBuffer(), - KMByteBlob.cast(dataPtr).getStartOff(), - outputData, - (short) 0, - KMByteBlob.cast(dataPtr).length()); - len = KMByteBlob.cast(dataPtr).length(); - dataPtr = KMByteBlob.instance(data, len, (short) (data.length - len)); - }else{ - dataPtr = KMByteBlob.instance(data, (short)/*16*/firstDataLen, (short) (data.length - /*16*/firstDataLen)); - } - } - - if (keyPurpose == KMType.VERIFY) { - ret = finish(KMInteger.uint_16(opHandle), dataPtr, signature, (short) 0, (short) 0, (short) 0); - } else { - ret = finish(KMInteger.uint_16(opHandle), dataPtr, null, (short) 0, (short) 0, (short) 0); - } - if(len >0){ - dataPtr = KMArray.cast(ret).get((short)2); - if(KMByteBlob.cast(dataPtr).length() >0){ - Util.arrayCopyNonAtomic( - KMByteBlob.cast(dataPtr).getBuffer(), - KMByteBlob.cast(dataPtr).getStartOff(), - outputData, - len, - KMByteBlob.cast(dataPtr).length()); - len = (short)(len + KMByteBlob.cast(dataPtr).length()); - } - KMArray.cast(ret).add((short)2, KMByteBlob.instance(outputData,(short)0,len)); - } - return ret; - } - - public short begin(byte keyPurpose, short keyBlob, short keyParmas, short hwToken) { - short arrPtr = KMArray.instance((short)4); - KMArray.cast(arrPtr).add((short)0, KMEnum.instance(KMType.PURPOSE, keyPurpose)); - KMArray.cast(arrPtr).add((short)1, keyBlob); - KMArray.cast(arrPtr).add((short)2, keyParmas); - if(hwToken == 0) { - hwToken = KMHardwareAuthToken.instance(); - } - KMArray.cast(arrPtr).add((short)3, hwToken); - CommandAPDU apdu = encodeApdu((byte)INS_BEGIN_OPERATION_CMD, arrPtr); - //print(apdu.getBytes(),(short)0,(short)apdu.getBytes().length); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - short outParams = KMKeyParameters.exp(); - KMArray.cast(ret).add((short)0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, outParams); - KMArray.cast(ret).add((short)2, KMInteger.exp()); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - if(len > 5){ - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - return ret;}else{ - if(len == 3) return respBuf[0]; - if(len == 4) return respBuf[1]; - return Util.getShort(respBuf,(short)0); - } - } - - public short finish(short operationHandle, short data, byte[] signature, short inParams, short hwToken, short verToken) { - if(hwToken == 0) { - hwToken = KMHardwareAuthToken.instance(); - } - if(verToken == 0){ - verToken = KMVerificationToken.instance(); - } - short signatureTag; - if(signature == null){ - signatureTag = KMByteBlob.instance((short)0); - }else{ - signatureTag = KMByteBlob.instance(signature,(short)0,(short)signature.length); - } - if(inParams == 0){ - short arr = KMArray.instance((short)0); - inParams = KMKeyParameters.instance(arr); - } - short arrPtr = KMArray.instance((short)6); - KMArray.cast(arrPtr).add((short)0, operationHandle); - KMArray.cast(arrPtr).add((short)1, inParams); - KMArray.cast(arrPtr).add((short)2, data); - KMArray.cast(arrPtr).add((short)3, signatureTag); - KMArray.cast(arrPtr).add((short)4, hwToken); - KMArray.cast(arrPtr).add((short)5, verToken); - CommandAPDU apdu = encodeApdu((byte)INS_FINISH_OPERATION_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 3); - short outParams = KMKeyParameters.exp(); - KMArray.cast(ret).add((short)0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, outParams); - KMArray.cast(ret).add((short)2, KMByteBlob.exp()); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - Assert.assertEquals(error, KMError.OK); - return ret; - } - public short update(short operationHandle, short data, short inParams, short hwToken, short verToken) { - if(hwToken == 0) { - hwToken = KMHardwareAuthToken.instance(); - } - if(verToken == 0){ - verToken = KMVerificationToken.instance(); - } - if(inParams == 0){ - short arr = KMArray.instance((short)0); - inParams = KMKeyParameters.instance(arr); - } - short arrPtr = KMArray.instance((short)5); - KMArray.cast(arrPtr).add((short)0, operationHandle); - KMArray.cast(arrPtr).add((short)1, inParams); - KMArray.cast(arrPtr).add((short)2, data); - KMArray.cast(arrPtr).add((short)3, hwToken); - KMArray.cast(arrPtr).add((short)4, verToken); - CommandAPDU apdu = encodeApdu((byte)INS_UPDATE_OPERATION_CMD, arrPtr); - // print(commandAPDU.getBytes()); - ResponseAPDU response = simulator.transmitCommand(apdu); - short ret = KMArray.instance((short) 4); - short outParams = KMKeyParameters.exp(); - KMArray.cast(ret).add((short)0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMInteger.exp()); - KMArray.cast(ret).add((short)2, outParams); - KMArray.cast(ret).add((short)3, KMByteBlob.exp()); - byte[] respBuf = response.getBytes(); - short len = (short) respBuf.length; - if (len > 5) { - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short) 0)).getShort(); - Assert.assertEquals(error, KMError.OK); - }else{ - ret = respBuf[1]; - } - return ret; - } - - private void print(short blob){ - print(KMByteBlob.cast(blob).getBuffer(),KMByteBlob.cast(blob).getStartOff(),KMByteBlob.cast(blob).length()); - } - private void print(byte[] buf, short start, short length){ - StringBuilder sb = new StringBuilder(); - for(int i = start; i < (start+length); i++){ - sb.append(String.format(" 0x%02X", buf[i])) ; - } - System.out.println(sb.toString()); - } - private void printCert(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])) ; - } - System.out.println(sb.toString()); - } - - -/* - @Test - public void testApdu(){ - init(); - byte[] cmd = {(byte)0x80,0x11,0x40,0x00,0x00,0x00,0x4C,(byte)0x83,(byte)0xA5,0x1A,0x70,0x00,0x01,(byte)0xF7,0x01,0x1A,0x10, - 0x00,0x00,0x02,0x03,0x1A,0x30,0x00,0x00,0x03,0x19,0x01,0x00,0x1A,0x20,0x00,0x00,0x01,0x42,0x02, - 0x03,0x1A,0x20,0x00,0x00,0x05,0x41,0x04,0x03,0x58,0x24,(byte)0x82,0x58,0x20,0x73,0x7C,0x2E,(byte)0xCD, - 0x7B,(byte)0x8D,0x19,0x40,(byte)0xBF,0x29,0x30,(byte)0xAA,(byte)0x9B,0x4E, - (byte)0xD3,(byte)0xFF,(byte)0x94,0x1E,(byte)0xED,0x09,0x36,0x6B, - (byte)0xC0,0x32,(byte)0x99,(byte)0x98,0x64,(byte)0x81,(byte)0xF3,(byte)0xA4,(byte)0xD8,0x59,0x40}; - CommandAPDU cmdApdu = new CommandAPDU(cmd); - ResponseAPDU resp = simulator.transmitCommand(cmdApdu); - short ret = KMArray.instance((short) 3); - KMArray.cast(ret).add((short) 0, KMInteger.exp()); - KMArray.cast(ret).add((short)1, KMByteBlob.exp()); - short inst = KMKeyCharacteristics.exp(); - KMArray.cast(ret).add((short) 2, inst); - byte[] respBuf = resp.getBytes(); - short len = (short) respBuf.length; - ret = decoder.decode(ret, respBuf, (short) 0, len); - short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); - short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); - short blobArr = extractKeyBlobArray(KMArray.cast(ret).get((short)1)); - short keyCharacteristics = KMArray.cast(ret).get((short)2); - short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); - short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); - cleanUp(); - } - */ -} +/* + * 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.test; + +import com.android.javacard.keymaster.KMArray; +import com.android.javacard.keymaster.KMAttestationCert; +import com.android.javacard.keymaster.KMAttestationCertImpl; +import com.android.javacard.keymaster.KMBoolTag; +import com.android.javacard.keymaster.KMByteBlob; +import com.android.javacard.keymaster.KMByteTag; +import com.android.javacard.keymaster.KMJCardSimApplet; +import com.android.javacard.keymaster.KMJCardSimulator; +import com.android.javacard.keymaster.KMSEProvider; +import com.android.javacard.keymaster.KMDecoder; +import com.android.javacard.keymaster.KMEncoder; +import com.android.javacard.keymaster.KMEnum; +import com.android.javacard.keymaster.KMEnumArrayTag; +import com.android.javacard.keymaster.KMEnumTag; +import com.android.javacard.keymaster.KMError; +import com.android.javacard.keymaster.KMHardwareAuthToken; +import com.android.javacard.keymaster.KMHmacSharingParameters; +import com.android.javacard.keymaster.KMInteger; +import com.android.javacard.keymaster.KMIntegerTag; +import com.android.javacard.keymaster.KMKeyCharacteristics; +import com.android.javacard.keymaster.KMKeyParameters; +import com.android.javacard.keymaster.KMKeymasterApplet; +import com.android.javacard.keymaster.KMRepository; +import com.android.javacard.keymaster.KMType; +import com.android.javacard.keymaster.KMVerificationToken; +import com.licel.jcardsim.smartcardio.CardSimulator; +import com.licel.jcardsim.utils.AIDUtil; +import javacard.framework.AID; +import javacard.framework.Util; + +import java.security.spec.PKCS8EncodedKeySpec; + +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; +import org.junit.Assert; +import org.junit.Test; + +public class KMFunctionalTest { + private static final byte INS_BEGIN_KM_CMD = 0x00; + private static final byte INS_PROVISION_ATTESTATION_KEY_CMD = INS_BEGIN_KM_CMD + 1; //0x01 + private static final byte INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD = INS_BEGIN_KM_CMD + 2; //0x02 + private static final byte INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD = INS_BEGIN_KM_CMD + 3; //0x03 + private static final byte INS_PROVISION_ATTEST_IDS_CMD = INS_BEGIN_KM_CMD + 4; //0x04 + private static final byte INS_PROVISION_SHARED_SECRET_CMD = INS_BEGIN_KM_CMD + 5; //0x05 + private static final byte INS_SET_BOOT_PARAMS_CMD = INS_BEGIN_KM_CMD + 6; //0x06 + private static final byte INS_LOCK_PROVISIONING_CMD = INS_BEGIN_KM_CMD + 7; //0x07 + private static final byte INS_GET_PROVISION_STATUS_CMD = INS_BEGIN_KM_CMD + 8; //0x08 + // Top 32 commands are reserved for provisioning. + private static final byte INS_END_KM_PROVISION_CMD = 0x20; + + private static final byte INS_GENERATE_KEY_CMD = INS_END_KM_PROVISION_CMD + 1; //0x21 + private static final byte INS_IMPORT_KEY_CMD = INS_END_KM_PROVISION_CMD + 2; //0x22 + private static final byte INS_IMPORT_WRAPPED_KEY_CMD = INS_END_KM_PROVISION_CMD + 3; //0x23 + private static final byte INS_EXPORT_KEY_CMD = INS_END_KM_PROVISION_CMD + 4; //0x24 + private static final byte INS_ATTEST_KEY_CMD = INS_END_KM_PROVISION_CMD + 5; //0x25 + private static final byte INS_UPGRADE_KEY_CMD = INS_END_KM_PROVISION_CMD + 6; //0x26 + private static final byte INS_DELETE_KEY_CMD = INS_END_KM_PROVISION_CMD + 7; //0x27 + private static final byte INS_DELETE_ALL_KEYS_CMD = INS_END_KM_PROVISION_CMD + 8; //0x28 + private static final byte INS_ADD_RNG_ENTROPY_CMD = INS_END_KM_PROVISION_CMD + 9; //0x29 + private static final byte INS_COMPUTE_SHARED_HMAC_CMD = INS_END_KM_PROVISION_CMD + 10; //0x2A + private static final byte INS_DESTROY_ATT_IDS_CMD = INS_END_KM_PROVISION_CMD + 11; //0x2B + private static final byte INS_VERIFY_AUTHORIZATION_CMD = INS_END_KM_PROVISION_CMD + 12; //0x2C + private static final byte INS_GET_HMAC_SHARING_PARAM_CMD = INS_END_KM_PROVISION_CMD + 13; //0x2D + private static final byte INS_GET_KEY_CHARACTERISTICS_CMD = INS_END_KM_PROVISION_CMD + 14; //0x2E + private static final byte INS_GET_HW_INFO_CMD = INS_END_KM_PROVISION_CMD + 15; //0x2F + private static final byte INS_BEGIN_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 16; //0x30 + private static final byte INS_UPDATE_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 17; //0x31 + private static final byte INS_FINISH_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 18; //0x32 + private static final byte INS_ABORT_OPERATION_CMD = INS_END_KM_PROVISION_CMD + 19; //0x33 + private static final byte INS_DEVICE_LOCKED_CMD = INS_END_KM_PROVISION_CMD + 20;//0x34 + private static final byte INS_EARLY_BOOT_ENDED_CMD = INS_END_KM_PROVISION_CMD + 21; //0x35 + private static final byte INS_GET_CERT_CHAIN_CMD = INS_END_KM_PROVISION_CMD + 22; //0x36 + + private static final byte[] kEcPrivKey = { + (byte) 0x21, (byte) 0xe0, (byte) 0x86, (byte) 0x43, (byte) 0x2a, + (byte) 0x15, (byte) 0x19, (byte) 0x84, (byte) 0x59, (byte) 0xcf, + (byte) 0x36, (byte) 0x3a, (byte) 0x50, (byte) 0xfc, (byte) 0x14, + (byte) 0xc9, (byte) 0xda, (byte) 0xad, (byte) 0xf9, (byte) 0x35, + (byte) 0xf5, (byte) 0x27, (byte) 0xc2, (byte) 0xdf, (byte) 0xd7, + (byte) 0x1e, (byte) 0x4d, (byte) 0x6d, (byte) 0xbc, (byte) 0x42, + (byte) 0xe5, (byte) 0x44 }; + private static final byte[] kEcPubKey = { + (byte) 0x04, (byte) 0xeb, (byte) 0x9e, (byte) 0x79, (byte) 0xf8, + (byte) 0x42, (byte) 0x63, (byte) 0x59, (byte) 0xac, (byte) 0xcb, + (byte) 0x2a, (byte) 0x91, (byte) 0x4c, (byte) 0x89, (byte) 0x86, + (byte) 0xcc, (byte) 0x70, (byte) 0xad, (byte) 0x90, (byte) 0x66, + (byte) 0x93, (byte) 0x82, (byte) 0xa9, (byte) 0x73, (byte) 0x26, + (byte) 0x13, (byte) 0xfe, (byte) 0xac, (byte) 0xcb, (byte) 0xf8, + (byte) 0x21, (byte) 0x27, (byte) 0x4c, (byte) 0x21, (byte) 0x74, + (byte) 0x97, (byte) 0x4a, (byte) 0x2a, (byte) 0xfe, (byte) 0xa5, + (byte) 0xb9, (byte) 0x4d, (byte) 0x7f, (byte) 0x66, (byte) 0xd4, + (byte) 0xe0, (byte) 0x65, (byte) 0x10, (byte) 0x66, (byte) 0x35, + (byte) 0xbc, (byte) 0x53, (byte) 0xb7, (byte) 0xa0, (byte) 0xa3, + (byte) 0xa6, (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, + (byte) 0x3e, (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14 }; + + private static final byte[] kEcAttestCert = { + 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x30, (byte) 0x82, + (byte) 0x02, (byte) 0x1e, (byte) 0xa0, (byte) 0x03, (byte) 0x02, + (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x10, 0x01, + (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, + (byte) 0x03, (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0x98, 0x31, + (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, 0x11, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, 0x69, + (byte) 0x61, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, + (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f, (byte) 0x75, 0x6e, + (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x20, + (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, + (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, 0x55, + (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, + (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, + (byte) 0x2c, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, 0x6f, + (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x33, (byte) 0x30, + (byte) 0x31, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x0c, (byte) 0x2a, (byte) 0x41, (byte) 0x6e, 0x64, + (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, + (byte) 0x4b, (byte) 0x65, (byte) 0x79, (byte) 0x73, (byte) 0x74, + (byte) 0x6f, (byte) 0x72, (byte) 0x65, (byte) 0x20, (byte) 0x53, 0x6f, + (byte) 0x66, (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72, + (byte) 0x65, (byte) 0x20, (byte) 0x41, (byte) 0x74, (byte) 0x74, + (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x61, (byte) 0x74, 0x69, + (byte) 0x6f, (byte) 0x6e, (byte) 0x20, (byte) 0x52, (byte) 0x6f, + (byte) 0x6f, (byte) 0x74, (byte) 0x30, (byte) 0x1e, (byte) 0x17, + (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, 0x31, + (byte) 0x31, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, + (byte) 0x30, (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, + (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x30, 0x38, + (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x36, (byte) 0x30, + (byte) 0x39, (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0x88, + (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, + (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, + (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, 0x13, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, + (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, (byte) 0x6f, + (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, (byte) 0x20, 0x49, + (byte) 0x6e, (byte) 0x63, (byte) 0x2e, (byte) 0x31, (byte) 0x10, + (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, 0x6e, + (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, + (byte) 0x31, (byte) 0x3b, (byte) 0x30, (byte) 0x39, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, 0x32, + (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, + (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, + (byte) 0x79, (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, 0x74, + (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, + (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, (byte) 0x69, 0x61, + (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x59, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, 0x06, + (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, + (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x03, + (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xeb, (byte) 0x9e, 0x79, + (byte) 0xf8, (byte) 0x42, (byte) 0x63, (byte) 0x59, (byte) 0xac, + (byte) 0xcb, (byte) 0x2a, (byte) 0x91, (byte) 0x4c, (byte) 0x89, + (byte) 0x86, (byte) 0xcc, (byte) 0x70, (byte) 0xad, (byte) 0x90, 0x66, + (byte) 0x93, (byte) 0x82, (byte) 0xa9, (byte) 0x73, (byte) 0x26, + (byte) 0x13, (byte) 0xfe, (byte) 0xac, (byte) 0xcb, (byte) 0xf8, + (byte) 0x21, (byte) 0x27, (byte) 0x4c, (byte) 0x21, (byte) 0x74, + (byte) 0x97, (byte) 0x4a, (byte) 0x2a, (byte) 0xfe, (byte) 0xa5, + (byte) 0xb9, (byte) 0x4d, (byte) 0x7f, (byte) 0x66, (byte) 0xd4, + (byte) 0xe0, (byte) 0x65, (byte) 0x10, (byte) 0x66, (byte) 0x35, + (byte) 0xbc, 0x53, (byte) 0xb7, (byte) 0xa0, (byte) 0xa3, (byte) 0xa6, + (byte) 0x71, (byte) 0x58, (byte) 0x3e, (byte) 0xdb, (byte) 0x3e, + (byte) 0x11, (byte) 0xae, (byte) 0x10, (byte) 0x14, (byte) 0xa3, + (byte) 0x66, 0x30, (byte) 0x64, (byte) 0x30, (byte) 0x1d, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, + (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x3f, (byte) 0xfc, + (byte) 0xac, (byte) 0xd6, (byte) 0x1a, (byte) 0xb1, (byte) 0x3a, + (byte) 0x9e, (byte) 0x81, (byte) 0x20, (byte) 0xb8, (byte) 0xd5, + (byte) 0x25, (byte) 0x1c, (byte) 0xc5, (byte) 0x65, (byte) 0xbb, + (byte) 0x1e, (byte) 0x91, (byte) 0xa9, (byte) 0x30, (byte) 0x1f, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, + (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, + (byte) 0x14, (byte) 0xc8, (byte) 0xad, (byte) 0xe9, (byte) 0x77, + (byte) 0x4c, (byte) 0x45, (byte) 0xc3, (byte) 0xa3, (byte) 0xcf, + (byte) 0x0d, (byte) 0x16, (byte) 0x10, (byte) 0xe4, (byte) 0x79, + (byte) 0x43, (byte) 0x3a, (byte) 0x21, (byte) 0x5a, 0x30, (byte) 0xcf, + (byte) 0x30, (byte) 0x12, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x1d, (byte) 0x13, (byte) 0x01, (byte) 0x01, (byte) 0xff, + (byte) 0x04, (byte) 0x08, (byte) 0x30, (byte) 0x06, 0x01, (byte) 0x01, + (byte) 0xff, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, 0x04, (byte) 0x04, + (byte) 0x03, (byte) 0x02, (byte) 0x02, (byte) 0x84, (byte) 0x30, + (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, 0x03, (byte) 0x02, + (byte) 0x03, (byte) 0x48, (byte) 0x00, (byte) 0x30, (byte) 0x45, + (byte) 0x02, (byte) 0x20, (byte) 0x4b, (byte) 0x8a, (byte) 0x9b, + (byte) 0x7b, (byte) 0xee, (byte) 0x82, (byte) 0xbc, (byte) 0xc0, + (byte) 0x33, (byte) 0x87, (byte) 0xae, (byte) 0x2f, (byte) 0xc0, + (byte) 0x89, (byte) 0x98, (byte) 0xb4, (byte) 0xdd, (byte) 0xc3, + (byte) 0x8d, (byte) 0xab, (byte) 0x27, (byte) 0x2a, (byte) 0x45, + (byte) 0x9f, (byte) 0x69, (byte) 0x0c, (byte) 0xc7, (byte) 0xc3, + (byte) 0x92, (byte) 0xd4, (byte) 0x0f, (byte) 0x8e, (byte) 0x02, + (byte) 0x21, (byte) 0x00, (byte) 0xee, (byte) 0xda, (byte) 0x01, + (byte) 0x5d, (byte) 0xb6, (byte) 0xf4, (byte) 0x32, (byte) 0xe9, + (byte) 0xd4, (byte) 0x84, (byte) 0x3b, (byte) 0x62, (byte) 0x4c, + (byte) 0x94, (byte) 0x04, (byte) 0xef, (byte) 0x3a, (byte) 0x7c, + (byte) 0xcc, (byte) 0xbd, 0x5e, (byte) 0xfb, (byte) 0x22, (byte) 0xbb, + (byte) 0xe7, (byte) 0xfe, (byte) 0xb9, (byte) 0x77, (byte) 0x3f, + (byte) 0x59, (byte) 0x3f, (byte) 0xfb, }; + + private static final byte[] kEcAttestRootCert = { + 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8b, (byte) 0x30, + (byte) 0x82, (byte) 0x02, (byte) 0x32, (byte) 0xa0, (byte) 0x03, + (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x02, (byte) 0x09, + (byte) 0x00, (byte) 0xa2, (byte) 0x05, (byte) 0x9e, (byte) 0xd1, + (byte) 0x0e, (byte) 0x43, (byte) 0x5b, (byte) 0x57, (byte) 0x30, + (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, 0x3d, (byte) 0x04, (byte) 0x03, + (byte) 0x02, (byte) 0x30, (byte) 0x81, (byte) 0x98, (byte) 0x31, + (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x06, 0x13, (byte) 0x02, + (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, + (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x43, 0x61, + (byte) 0x6c, (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, + (byte) 0x6e, (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x16, + (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55, + 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, + (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, + (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, + (byte) 0x65, 0x77, (byte) 0x31, (byte) 0x15, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, 0x6c, (byte) 0x65, (byte) 0x2c, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x33, + (byte) 0x30, (byte) 0x31, (byte) 0x06, (byte) 0x03, 0x55, + (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x2a, (byte) 0x41, + (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, + (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, + 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, + (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, + (byte) 0x6e, (byte) 0x20, (byte) 0x52, (byte) 0x6f, (byte) 0x6f, + (byte) 0x74, (byte) 0x30, 0x1e, (byte) 0x17, (byte) 0x0d, + (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, + (byte) 0x31, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x33, + (byte) 0x35, (byte) 0x30, (byte) 0x5a, 0x17, (byte) 0x0d, + (byte) 0x33, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x30, + (byte) 0x36, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x33, + (byte) 0x35, (byte) 0x30, (byte) 0x5a, (byte) 0x30, (byte) 0x81, + (byte) 0x98, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, + (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, + 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, + (byte) 0x43, (byte) 0x61, (byte) 0x6c, (byte) 0x69, (byte) 0x66, + (byte) 0x6f, 0x72, (byte) 0x6e, (byte) 0x69, (byte) 0x61, + (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, + (byte) 0x0d, (byte) 0x4d, 0x6f, (byte) 0x75, (byte) 0x6e, + (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x20, + (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, + (byte) 0x15, (byte) 0x30, (byte) 0x13, 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, + (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, + (byte) 0x65, (byte) 0x2c, (byte) 0x20, (byte) 0x49, 0x6e, + (byte) 0x63, (byte) 0x2e, (byte) 0x31, (byte) 0x10, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, + 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, + (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x31, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, + (byte) 0x2a, 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x4b, + (byte) 0x65, (byte) 0x79, (byte) 0x73, (byte) 0x74, (byte) 0x6f, + (byte) 0x72, (byte) 0x65, 0x20, (byte) 0x53, (byte) 0x6f, + (byte) 0x66, (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72, + (byte) 0x65, (byte) 0x20, (byte) 0x41, (byte) 0x74, (byte) 0x74, + (byte) 0x65, (byte) 0x73, (byte) 0x74, 0x61, (byte) 0x74, + (byte) 0x69, (byte) 0x6f, (byte) 0x6e, 0x77, (byte) 0x1f, + (byte) 0x44, (byte) 0x22, (byte) 0x6d, (byte) 0xbd, (byte) 0xb1, + (byte) 0xaf, (byte) 0xfa, (byte) 0x16, (byte) 0xcb, (byte) 0xc7, + (byte) 0xad, (byte) 0xc5, (byte) 0x77, (byte) 0xd2, (byte) 0x20, + (byte) 0x52, (byte) 0x6f, (byte) 0x6f, (byte) 0x74, (byte) 0x30, + (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, + 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, + (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, + (byte) 0x01, 0x07, (byte) 0x03, (byte) 0x42, (byte) 0x00, + (byte) 0x04, (byte) 0xee, (byte) 0x5d, (byte) 0x5e, (byte) 0xc7, + (byte) 0xe1, (byte) 0xc0, (byte) 0xdb, (byte) 0x6d, (byte) 0x03, + (byte) 0xa6, (byte) 0x7e, (byte) 0xe6, (byte) 0xb6, (byte) 0x1b, + (byte) 0xec, (byte) 0x4d, (byte) 0x6a, (byte) 0x5d, (byte) 0x6a, + (byte) 0x68, (byte) 0x2e, (byte) 0x0f, (byte) 0xff, (byte) 0x7f, + (byte) 0x49, (byte) 0x0e, (byte) 0x7d, 0x56, (byte) 0x9c, + (byte) 0xaa, (byte) 0xb7, (byte) 0xb0, (byte) 0x2d, (byte) 0x54, + (byte) 0x01, (byte) 0x5d, (byte) 0x3e, (byte) 0x43, (byte) 0x2b, + (byte) 0x2a, (byte) 0x8e, (byte) 0xd7, (byte) 0x4e, (byte) 0xec, + (byte) 0x48, (byte) 0x75, (byte) 0x41, (byte) 0xa4, (byte) 0xa3, + (byte) 0x63, (byte) 0x30, (byte) 0x61, (byte) 0x30, (byte) 0x1d, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, + 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0xc8, + (byte) 0xad, (byte) 0xe9, (byte) 0x77, (byte) 0x4c, (byte) 0x45, + (byte) 0xc3, (byte) 0xa3, (byte) 0xcf, (byte) 0x0d, (byte) 0x16, + (byte) 0x10, (byte) 0xe4, (byte) 0x79, (byte) 0x43, (byte) 0x3a, + (byte) 0x21, (byte) 0x5a, (byte) 0x30, (byte) 0xcf, (byte) 0x30, + (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + (byte) 0x23, (byte) 0x04, 0x18, (byte) 0x30, (byte) 0x16, + (byte) 0x80, (byte) 0x14, (byte) 0xc8, (byte) 0xad, (byte) 0xe9, + (byte) 0x77, (byte) 0x4c, (byte) 0x45, (byte) 0xc3, (byte) 0xa3, + (byte) 0xcf, (byte) 0x0d, (byte) 0x16, 0x10, (byte) 0xe4, + (byte) 0x79, (byte) 0x43, (byte) 0x3a, (byte) 0x21, (byte) 0x5a, + (byte) 0x30, (byte) 0xcf, (byte) 0x30, (byte) 0x0f, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, 0x01, + (byte) 0x01, (byte) 0xff, (byte) 0x04, (byte) 0x05, (byte) 0x30, + (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, + (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04, + (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x02, (byte) 0x84, + (byte) 0x30, (byte) 0x0a, (byte) 0x06, (byte) 0x08, (byte) 0x2a, + (byte) 0x86, 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x04, + (byte) 0x03, (byte) 0x02, (byte) 0x03, (byte) 0x47, (byte) 0x00, + (byte) 0x30, (byte) 0x44, (byte) 0x02, (byte) 0x20, (byte) 0x35, + (byte) 0x21, (byte) 0xa3, (byte) 0xef, (byte) 0x8b, (byte) 0x34, + (byte) 0x46, (byte) 0x1e, (byte) 0x9c, (byte) 0xd5, (byte) 0x60, + (byte) 0xf3, (byte) 0x1d, (byte) 0x58, (byte) 0x89, (byte) 0x20, + (byte) 0x6a, (byte) 0xdc, (byte) 0xa3, 0x65, (byte) 0x41, + (byte) 0xf6, (byte) 0x0d, (byte) 0x9e, (byte) 0xce, (byte) 0x8a, + (byte) 0x19, (byte) 0x8c, (byte) 0x66, (byte) 0x48, (byte) 0x60, + (byte) 0x7b, (byte) 0x02, (byte) 0x20, (byte) 0x4d, 0x0b, + (byte) 0xf3, (byte) 0x51, (byte) 0xd9, (byte) 0x30, (byte) 0x7c, + (byte) 0x7d, (byte) 0x5b, (byte) 0xda, (byte) 0x35, (byte) 0x34, + (byte) 0x1d, (byte) 0xa8, (byte) 0x47, (byte) 0x1b, (byte) 0x63, + (byte) 0xa5, (byte) 0x85, (byte) 0x65, (byte) 0x3c, (byte) 0xad, + (byte) 0x4f, (byte) 0x24, (byte) 0xa7, (byte) 0xe7, (byte) 0x4d, + (byte) 0xaf, (byte) 0x41, (byte) 0x7d, (byte) 0xf1, + (byte) 0xbf, }; + + private static final byte[] X509Issuer = { + (byte) 0x30, (byte) 0x81, (byte) 0x88, (byte) 0x31, (byte) 0x0b, + (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, + (byte) 0x53, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, + (byte) 0x0c, (byte) 0x0a, (byte) 0x43, (byte) 0x61, (byte) 0x6c, + (byte) 0x69, (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x6e, + (byte) 0x69, (byte) 0x61, (byte) 0x31, (byte) 0x15, (byte) 0x30, + (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2c, + (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x63, (byte) 0x2e, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, + (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, + (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x3b, + (byte) 0x30, (byte) 0x39, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x32, (byte) 0x41, + (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, + (byte) 0x64, (byte) 0x20, (byte) 0x4b, (byte) 0x65, (byte) 0x79, + (byte) 0x73, (byte) 0x74, (byte) 0x6f, (byte) 0x72, (byte) 0x65, + (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66, (byte) 0x74, + (byte) 0x77, (byte) 0x61, (byte) 0x72, (byte) 0x65, (byte) 0x20, + (byte) 0x41, (byte) 0x74, (byte) 0x74, (byte) 0x65, (byte) 0x73, + (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6f, + (byte) 0x6e, (byte) 0x20, (byte) 0x49, (byte) 0x6e, (byte) 0x74, + (byte) 0x65, (byte) 0x72, (byte) 0x6d, (byte) 0x65, (byte) 0x64, + (byte) 0x69, (byte) 0x61, (byte) 0x74, (byte) 0x65 }; + // AttestationApplicationId ::= SEQUENCE { + // * packageInfoRecords SET OF PackageInfoRecord, + // * signatureDigests SET OF OCTET_STRING, + // * } + // * + // * PackageInfoRecord ::= SEQUENCE { + // * packageName OCTET_STRING, + // * version INTEGER, + // * } + private static final byte[] attAppId = {0x30, 0x10, 0x31, 0x0B, 0x30, 0x04, 0x05, 'A', 'B', 'C', + 'D', 'E', 0x02, 0x01, 0x01, 0x31, 0x02, 0x04, 0x00}; + private static final byte[] attChallenge = {'c','h','a','l','l','e','n','g','e'}; + private static final byte[] expiryTime = {(byte)0x32, (byte)0x36, (byte)0x30, (byte)0x31, (byte)0x30, (byte)0x38, (byte)0x30, (byte)0x30, (byte)0x34, (byte)0x36, (byte)0x30, (byte)0x39, (byte)0x5a}; + private static final byte[] authKeyId = { (byte)0x80, (byte)0x14, (byte)0xc8, (byte)0xad, (byte)0xe9, (byte)0x77, (byte)0x4c, (byte)0x45, (byte)0xc3, (byte)0xa3, (byte)0xcf, (byte)0x0d, (byte)0x16, (byte)0x10, (byte)0xe4, (byte)0x79, (byte)0x43, (byte)0x3a, (byte)0x21, (byte)0x5a, (byte)0x30, (byte)0xcf}; + + private CardSimulator simulator; + private KMEncoder encoder; + private KMDecoder decoder; + private KMSEProvider cryptoProvider; + + public KMFunctionalTest(){ + cryptoProvider = new KMJCardSimulator(); + simulator = new CardSimulator(); + encoder = new KMEncoder(); + decoder = new KMDecoder(); + } + + private void init(){ + // Create simulator + AID appletAID = AIDUtil.create("A000000062"); + simulator.installApplet(appletAID, KMJCardSimApplet.class); + // Select applet + simulator.selectApplet(appletAID); + // provision attest key + provisionCmd(simulator); + } + + private void setBootParams(CardSimulator simulator, short osVersion, + short osPatchLevel, short vendorPatchLevel, short bootPatchLevel) { + // Argument 1 OS Version + short versionPtr = KMInteger.uint_16(osVersion); + // short versionTagPtr = KMIntegerTag.instance(KMType.UINT_TAG, + // KMType.OS_VERSION,versionPatchPtr); + // Argument 2 OS Patch level + short patchPtr = KMInteger.uint_16(osPatchLevel); + short vendorpatchPtr = KMInteger.uint_16((short) vendorPatchLevel); + short bootpatchPtr = KMInteger.uint_16((short) bootPatchLevel); + // Argument 3 Verified Boot Key + byte[] bootKeyHash = "00011122233344455566677788899900".getBytes(); + short bootKeyPtr = KMByteBlob.instance(bootKeyHash, (short) 0, + (short) bootKeyHash.length); + // Argument 4 Verified Boot Hash + short bootHashPtr = KMByteBlob.instance(bootKeyHash, (short) 0, + (short) bootKeyHash.length); + // Argument 5 Verified Boot State + short bootStatePtr = KMEnum.instance(KMType.VERIFIED_BOOT_STATE, + KMType.VERIFIED_BOOT); + // Argument 6 Device Locked + short deviceLockedPtr = KMEnum.instance(KMType.DEVICE_LOCKED, + KMType.DEVICE_LOCKED_FALSE); + // Arguments + short arrPtr = KMArray.instance((short) 8); + KMArray vals = KMArray.cast(arrPtr); + vals.add((short) 0, versionPtr); + vals.add((short) 1, patchPtr); + vals.add((short) 2, vendorpatchPtr); + vals.add((short) 3, bootpatchPtr); + vals.add((short) 4, bootKeyPtr); + vals.add((short) 5, bootHashPtr); + vals.add((short) 6, bootStatePtr); + vals.add((short) 7, deviceLockedPtr); + CommandAPDU apdu = encodeApdu((byte) INS_SET_BOOT_PARAMS_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + + } + + private void provisionSigningCertificate(CardSimulator simulator) { + short byteBlobPtr = KMByteBlob.instance( + (short) (kEcAttestCert.length + kEcAttestRootCert.length)); + Util.arrayCopyNonAtomic(kEcAttestCert, (short) 0, + KMByteBlob.cast(byteBlobPtr).getBuffer(), + KMByteBlob.cast(byteBlobPtr).getStartOff(), + (short) kEcAttestCert.length); + Util.arrayCopyNonAtomic(kEcAttestRootCert, (short) 0, + KMByteBlob.cast(byteBlobPtr).getBuffer(), + (short) (KMByteBlob.cast(byteBlobPtr).getStartOff() + + kEcAttestCert.length), + (short) kEcAttestRootCert.length); + CommandAPDU apdu = encodeApdu( + (byte) INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD, byteBlobPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + } + + private void provisionSigningKey(CardSimulator simulator) { + // KeyParameters. + short arrPtr = KMArray.instance((short) 4); + short ecCurve = KMEnumTag.instance(KMType.ECCURVE, KMType.P_256); + short byteBlob = KMByteBlob.instance((short) 1); + KMByteBlob.cast(byteBlob).add((short) 0, KMType.SHA2_256); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + short byteBlob2 = KMByteBlob.instance((short) 1); + KMByteBlob.cast(byteBlob2).add((short) 0, KMType.ATTEST_KEY); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob2); + KMArray.cast(arrPtr).add((short) 0, ecCurve); + KMArray.cast(arrPtr).add((short) 1, digest); + KMArray.cast(arrPtr).add((short) 2, + KMEnumTag.instance(KMType.ALGORITHM, KMType.EC)); + KMArray.cast(arrPtr).add((short) 3, purpose); + short keyParams = KMKeyParameters.instance(arrPtr); + // Note: VTS uses PKCS8 KeyFormat RAW + short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW); + + // Key + short signKeyPtr = KMArray.instance((short) 2); + KMArray.cast(signKeyPtr).add((short) 0, KMByteBlob.instance(kEcPrivKey, + (short) 0, (short) kEcPrivKey.length)); + KMArray.cast(signKeyPtr).add((short) 1, KMByteBlob.instance(kEcPubKey, + (short) 0, (short) kEcPubKey.length)); + byte[] keyBuf = new byte[120]; + short len = encoder.encode(signKeyPtr, keyBuf, (short) 0); + short signKeyBstr = KMByteBlob.instance(keyBuf, (short) 0, len); + + short finalArrayPtr = KMArray.instance((short) 3); + KMArray.cast(finalArrayPtr).add((short) 0, keyParams); + KMArray.cast(finalArrayPtr).add((short) 1, keyFormatPtr); + KMArray.cast(finalArrayPtr).add((short) 2, signKeyBstr); + + CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_ATTESTATION_KEY_CMD, + finalArrayPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + } + + private void provisionCertificateParams(CardSimulator simulator) { + + short arrPtr = KMArray.instance((short) 3); + short byteBlob1 = KMByteBlob.instance(X509Issuer, (short) 0, + (short) X509Issuer.length); + KMArray.cast(arrPtr).add((short) 0, byteBlob1); + short byteBlob2 = KMByteBlob.instance(expiryTime, (short) 0, + (short) expiryTime.length); + KMArray.cast(arrPtr).add((short) 1, byteBlob2); + short byteBlob3 = KMByteBlob.instance(authKeyId, (short) 0, + (short) authKeyId.length); + KMArray.cast(arrPtr).add((short) 2, byteBlob3); + + CommandAPDU apdu = encodeApdu( + (byte) INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + } + + private void provisionSharedSecret(CardSimulator simulator) { + byte[] sharedKeySecret = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + short arrPtr = KMArray.instance((short) 1); + short byteBlob = KMByteBlob.instance(sharedKeySecret, (short) 0, + (short) sharedKeySecret.length); + KMArray.cast(arrPtr).add((short) 0, byteBlob); + + CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_SHARED_SECRET_CMD, + arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + } + + private void provisionAttestIds(CardSimulator simulator) { + short arrPtr = KMArray.instance((short) 8); + + byte[] buf = "Attestation Id".getBytes(); + + KMArray.cast(arrPtr).add((short) 0, + KMByteTag.instance(KMType.ATTESTATION_ID_BRAND, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 1, + KMByteTag.instance(KMType.ATTESTATION_ID_PRODUCT, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 2, + KMByteTag.instance(KMType.ATTESTATION_ID_DEVICE, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 3, + KMByteTag.instance(KMType.ATTESTATION_ID_MODEL, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 4, + KMByteTag.instance(KMType.ATTESTATION_ID_IMEI, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 5, + KMByteTag.instance(KMType.ATTESTATION_ID_MEID, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 6, + KMByteTag.instance(KMType.ATTESTATION_ID_MANUFACTURER, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + KMArray.cast(arrPtr).add((short) 7, + KMByteTag.instance(KMType.ATTESTATION_ID_SERIAL, + KMByteBlob.instance(buf, (short) 0, (short) buf.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + short outerArrPtr = KMArray.instance((short) 1); + KMArray.cast(outerArrPtr).add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_ATTEST_IDS_CMD, + outerArrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + } + + private void provisionLocked(CardSimulator simulator) { + CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_LOCK_PROVISIONING_CMD, + 0x40, 0x00); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(commandAPDU); + Assert.assertEquals(0x9000, response.getSW()); + } + + private void provisionCmd(CardSimulator simulator) { + provisionSigningKey(simulator); + provisionSigningCertificate(simulator); + provisionCertificateParams(simulator); + provisionSharedSecret(simulator); + provisionAttestIds(simulator); + // set bootup parameters + setBootParams(simulator,(short)1,(short)1, (short)0, (short)0); + provisionLocked(simulator); + } + + private void cleanUp(){ + AID appletAID = AIDUtil.create("A000000062"); + // Delete i.e. uninstall applet + simulator.deleteApplet(appletAID); + } + + + private CommandAPDU encodeApdu(byte ins, short cmd){ + byte[] buf = new byte[2500]; + buf[0] = (byte)0x80; + buf[1] = ins; + buf[2] = (byte)0x40; + buf[3] = (byte)0x00; + buf[4] = 0; + short len = encoder.encode(cmd, buf, (short) 7); + Util.setShort(buf, (short)5, len); + byte[] apdu = new byte[7+len]; + Util.arrayCopyNonAtomic(buf,(short)0,apdu,(short)0,(short)(7+len)); + //CommandAPDU commandAPDU = new CommandAPDU(0x80, 0x10, 0x40, 0x00, buf, 0, actualLen); + return new CommandAPDU(apdu); + } + + @Test + public void testAesImportKeySuccess() { + init(); + byte[] aesKeySecret = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + short arrPtr = KMArray.instance((short)5); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ECB); + short blockMode = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.PKCS7); + short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + KMArray.cast(arrPtr).add((short)0, boolTag); + KMArray.cast(arrPtr).add((short)1, keySize); + KMArray.cast(arrPtr).add((short)2, blockMode); + KMArray.cast(arrPtr).add((short)3, paddingMode); + KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.AES)); + short keyParams = KMKeyParameters.instance(arrPtr); + short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW); + short keyBlob = KMArray.instance((short)1); + KMArray.cast(keyBlob).add((short)0, KMByteBlob.instance(aesKeySecret,(short)0,(short)16)); + byte[] blob = new byte[256]; + short len = encoder.encode(keyBlob,blob,(short)0); + keyBlob = KMByteBlob.instance(blob, (short)0, len); + arrPtr = KMArray.instance((short)3); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + arg.add((short)1, keyFormatPtr); + arg.add((short)2, keyBlob); + CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); + Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.PKCS7)); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.BLOCK_MODE, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.ECB)); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.AES); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); + cleanUp(); + } + + @Test + public void testHmacImportKeySuccess() { + init(); + byte[] hmacKeySecret = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + short arrPtr = KMArray.instance((short)5); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + short minMacLength = KMIntegerTag.instance(KMType.UINT_TAG,KMType.MIN_MAC_LENGTH, KMInteger.uint_16((short)256)); + KMArray.cast(arrPtr).add((short)0, boolTag); + KMArray.cast(arrPtr).add((short)1, keySize); + KMArray.cast(arrPtr).add((short)2, digest); + KMArray.cast(arrPtr).add((short)3, minMacLength); + KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.HMAC)); + short keyParams = KMKeyParameters.instance(arrPtr); + short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW); + short keyBlob = KMArray.instance((short)1); + KMArray.cast(keyBlob).add((short)0, KMByteBlob.instance(hmacKeySecret,(short)0,(short)16)); + byte[] blob = new byte[256]; + short len = encoder.encode(keyBlob,blob,(short)0); + keyBlob = KMByteBlob.instance(blob, (short)0, len); + arrPtr = KMArray.instance((short)3); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + arg.add((short)1, keyFormatPtr); + arg.add((short)2, keyBlob); + CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); + Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 256); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.HMAC); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); + cleanUp(); + } + + @Test + public void testRsaImportKeySuccess() { + init(); + /* + KeyPair rsaKeyPair = cryptoProvider.createRsaKeyPair(); + byte[] pub = new byte[4]; + short len = ((RSAPublicKey)rsaKeyPair.getPublic()).getExponent(pub,(short)1); + byte[] priv = new byte[256]; + byte[] mod = new byte[256]; + len = ((RSAPrivateKey)rsaKeyPair.getPrivate()).getModulus(mod,(short)0); + len = ((RSAPrivateKey)rsaKeyPair.getPrivate()).getExponent(priv,(short)0); + */ + + byte[] pub = new byte[]{0x00,0x01,0x00,0x01}; + byte[] mod = new byte[256]; + byte[] priv = new byte[256]; + short[] lengths = new short[2]; + cryptoProvider.createAsymmetricKey(KMType.RSA,priv,(short)0,(short)256,mod,(short)0, (short)256,lengths); + short arrPtr = KMArray.instance((short)6); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)2048)); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + short rsaPubExpTag = KMIntegerTag.instance(KMType.ULONG_TAG,KMType.RSA_PUBLIC_EXPONENT, + KMInteger.uint_32(pub, (short)0)); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.RSA_PSS); + short padding = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + KMArray.cast(arrPtr).add((short)0, boolTag); + KMArray.cast(arrPtr).add((short)1, keySize); + KMArray.cast(arrPtr).add((short)2, digest); + KMArray.cast(arrPtr).add((short)3, rsaPubExpTag); + KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.RSA)); + KMArray.cast(arrPtr).add((short)5, padding); + short keyParams = KMKeyParameters.instance(arrPtr); + short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW);// Note: VTS uses PKCS8 + short keyBlob = KMArray.instance((short)2); + KMArray.cast(keyBlob).add((short)0, KMByteBlob.instance(priv,(short)0,(short)256)); + KMArray.cast(keyBlob).add((short)1, KMByteBlob.instance(mod,(short)0,(short)256)); + byte[] blob = new byte[620]; + short len = encoder.encode(keyBlob,blob,(short)0); + keyBlob = KMByteBlob.instance(blob, (short)0, len); + arrPtr = KMArray.instance((short)3); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + arg.add((short)1, keyFormatPtr); + arg.add((short)2, keyBlob); + CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); + Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 2048); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.RSA_PSS)); + tag = KMKeyParameters.findTag(KMType.ULONG_TAG, KMType.RSA_PUBLIC_EXPONENT, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getSignificantShort(), 0x01); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 0x01); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.RSA); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); + cleanUp(); + } + + @Test + public void testDeviceLocked(){ + init(); + byte[] hmacKey = new byte[32]; + cryptoProvider.newRandomNumber(hmacKey,(short)0,(short)32); + KMRepository.instance().initComputedHmac(hmacKey,(short)0,(short)32); + // generate aes key with unlocked_device_required + short aesKey = generateAesDesKey(KMType.AES,(short)128,null,null, true); + short keyBlobPtr = KMArray.cast(aesKey).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), + KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + // encrypt something + short inParams = getAesDesParams(KMType.AES, KMType.ECB, KMType.PKCS7, null); + byte[] plainData= "Hello World 123!".getBytes(); + short ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.ENCRYPT, + KMKeyParameters.instance(inParams), + (short)0,null,false, false + ); + keyBlobPtr = KMArray.cast(ret).get((short)2); + byte[] cipherData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + cipherData,(short)0, (short)cipherData.length); + // create verification token + short verToken = KMVerificationToken.instance(); + KMVerificationToken.cast(verToken).setTimestamp(KMInteger.uint_16((short)1)); + verToken = signVerificationToken(verToken); + // device locked request + deviceLock(verToken); + // decrypt should fail + inParams = getAesDesParams(KMType.AES, KMType.ECB, KMType.PKCS7, null); + short beginResp = begin(KMType.DECRYPT, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), KMKeyParameters.instance(inParams), (short)0); + Assert.assertEquals(beginResp,KMError.DEVICE_LOCKED); + short hwToken = KMHardwareAuthToken.instance(); + KMHardwareAuthToken.cast(hwToken).setTimestamp(KMInteger.uint_16((byte)2)); + KMHardwareAuthToken.cast(hwToken).setHwAuthenticatorType(KMEnum.instance(KMType.USER_AUTH_TYPE, (byte)KMType.PASSWORD)); + inParams = getAesDesParams(KMType.AES, KMType.ECB, KMType.PKCS7, null); + hwToken = signHwToken(hwToken); + ret = processMessage(cipherData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.DECRYPT, + KMKeyParameters.instance(inParams),hwToken,null,false, false + ); + ret = KMArray.cast(ret).get((short)0); + Assert.assertEquals(KMInteger.cast(ret).getShort(), KMError.OK); + cleanUp(); + } + + private short signHwToken(short hwToken){ + short len = 0; + byte[] scratchPad = new byte[256]; + // add 0 + Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); + len = 1; + // concatenate challenge - 8 bytes + short ptr = KMHardwareAuthToken.cast(hwToken).getChallenge(); + KMInteger.cast(ptr) + .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); + len += 8; + // concatenate user id - 8 bytes + ptr = KMHardwareAuthToken.cast(hwToken).getUserId(); + KMInteger.cast(ptr) + .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); + len += 8; + // concatenate authenticator id - 8 bytes + ptr = KMHardwareAuthToken.cast(hwToken).getAuthenticatorId(); + KMInteger.cast(ptr) + .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); + len += 8; + // concatenate authenticator type - 4 bytes + ptr = KMHardwareAuthToken.cast(hwToken).getHwAuthenticatorType(); + scratchPad[(short) (len + 3)] = KMEnum.cast(ptr).getVal(); + len += 4; + // concatenate timestamp -8 bytes + ptr = KMHardwareAuthToken.cast(hwToken).getTimestamp(); + KMInteger.cast(ptr) + .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); + len += 8; + // hmac the data +/* HMACKey key = + cryptoProvider.createHMACKey( + KMRepository.instance().getComputedHmacKey(), + (short) 0, + (short) KMRepository.instance().getComputedHmacKey().length); + + */ + byte[] mac = new byte[32]; + /* + len = + cryptoProvider.hmacSign(key, scratchPad, (short) 0, len, + mac, + (short)0); + */ + short key = KMRepository.instance().getComputedHmacKey(); + cryptoProvider.hmacSign( + KMByteBlob.cast(key).getBuffer(), + KMByteBlob.cast(key).getStartOff(), + KMByteBlob.cast(key).length(), + scratchPad, (short) 0, len, + mac, + (short)0); + KMHardwareAuthToken.cast(hwToken).setMac(KMByteBlob.instance(mac,(short)0,(short)mac.length)); + return hwToken; + } + private void deviceLock(short verToken) { + short req = KMArray.instance((short)2); + KMArray.cast(req).add((short)0, KMInteger.uint_8((byte)1)); + KMArray.cast(req).add((short)1, verToken); + CommandAPDU apdu = encodeApdu((byte)INS_DEVICE_LOCKED_CMD,req); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 1); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + byte[] respBuf = response.getBytes(); + Assert.assertEquals(respBuf[0],KMError.OK); + } + + private short signVerificationToken(short verToken) { + byte[] scratchPad = new byte[256]; + byte[] authVer = "Auth Verification".getBytes(); + //print(authVer,(short)0,(short)authVer.length); + // concatenation length will be 37 + length of verified parameters list - which is typically empty + Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0); + short params = KMVerificationToken.cast(verToken).getParametersVerified(); + // Add "Auth Verification" - 17 bytes. + Util.arrayCopy(authVer,(short)0, scratchPad, (short)0, (short)authVer.length); + short len = (short)authVer.length; + // concatenate challenge - 8 bytes + short ptr = KMVerificationToken.cast(verToken).getChallenge(); + KMInteger.cast(ptr) + .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); + len += 8; + // concatenate timestamp -8 bytes + ptr = KMVerificationToken.cast(verToken).getTimestamp(); + KMInteger.cast(ptr) + .value(scratchPad, (short) (len + (short) (8 - KMInteger.cast(ptr).length()))); + len += 8; + // concatenate security level - 4 bytes + ptr = KMVerificationToken.cast(verToken).getSecurityLevel(); + scratchPad[(short) (len + 3)] = KMEnum.cast(ptr).getVal(); + len += 4; + // concatenate Parameters verified - blob of encoded data. + ptr = KMVerificationToken.cast(verToken).getParametersVerified(); + if (KMByteBlob.cast(ptr).length() != 0) { + len += KMByteBlob.cast(ptr).getValues(scratchPad, (short) 0); + } + // hmac the data + /* HMACKey key = + cryptoProvider.createHMACKey( + KMRepository.instance().getComputedHmacKey(), + (short) 0, + (short) KMRepository.instance().getComputedHmacKey().length); + + */ + ptr = KMVerificationToken.cast(verToken).getMac(); + byte[] mac = new byte[32]; + /*len = + cryptoProvider.hmacSign(key, scratchPad, (short) 0, len, + mac, + (short)0); + */ + short key = KMRepository.instance().getComputedHmacKey(); + cryptoProvider.hmacSign(KMByteBlob.cast(key).getBuffer(), + KMByteBlob.cast(key).getStartOff(), + KMByteBlob.cast(key).length(), + scratchPad, (short) 0, len, + mac, + (short)0); + KMVerificationToken.cast(verToken).setMac(KMByteBlob.instance(mac,(short)0,(short)mac.length)); + return verToken; + } + + @Test + public void testEcImportKeySuccess() { + init(); + /* + KeyPair ecKeyPair = cryptoProvider.createECKeyPair(); + byte[] pub = new byte[128]; + short len = ((ECPublicKey)ecKeyPair.getPublic()).getW(pub,(short)0); + byte[] priv = new byte[128]; + len = ((ECPrivateKey)ecKeyPair.getPrivate()).getS(priv,(short)0); + */ + byte[] pub = new byte[128]; + byte[] priv = new byte[128]; + short[] lengths = new short[2]; + cryptoProvider.createAsymmetricKey(KMType.EC,priv,(short)0,(short)128,pub,(short)0, (short)128,lengths); + short pubBlob = KMByteBlob.instance(pub,(short)0,lengths[1]); + short privBlob = KMByteBlob.instance(priv,(short)0,lengths[0]); + short arrPtr = KMArray.instance((short)5); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)256)); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + short ecCurve = KMEnumTag.instance(KMType.ECCURVE, KMType.P_256); + KMArray.cast(arrPtr).add((short)0, boolTag); + KMArray.cast(arrPtr).add((short)1, keySize); + KMArray.cast(arrPtr).add((short)2, digest); + KMArray.cast(arrPtr).add((short)3, ecCurve); + KMArray.cast(arrPtr).add((short)4, KMEnumTag.instance(KMType.ALGORITHM, KMType.EC)); + short keyParams = KMKeyParameters.instance(arrPtr); + short keyFormatPtr = KMEnum.instance(KMType.KEY_FORMAT, KMType.RAW);// Note: VTS uses PKCS8 + short keyBlob = KMArray.instance((short)2); + KMArray.cast(keyBlob).add((short)0, privBlob); + KMArray.cast(keyBlob).add((short)1, pubBlob); + byte[] blob = new byte[128]; + short len = encoder.encode(keyBlob,blob,(short)0); + keyBlob = KMByteBlob.instance(blob, (short)0, len); + arrPtr = KMArray.instance((short)3); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + arg.add((short)1, keyFormatPtr); + arg.add((short)2, keyBlob); + CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short blobArr = extractKeyBlobArray(KMArray.cast(ret).get((short)1)); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); + Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 256); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ECCURVE, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.P_256); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.EC); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.IMPORTED); + cleanUp(); + } + + private short extractKeyBlobArray(short keyBlob) { + short ret = KMArray.instance((short) 5); + KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_SECRET, KMByteBlob.exp()); + KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_AUTH_TAG, KMByteBlob.exp()); + KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_NONCE, KMByteBlob.exp()); + short ptr = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_KEYCHAR, ptr); + KMArray.cast(ret).add(KMKeymasterApplet.KEY_BLOB_PUB_KEY, KMByteBlob.exp()); + ret = + decoder.decodeArray( + ret, + KMByteBlob.cast(keyBlob).getBuffer(), + KMByteBlob.cast(keyBlob).getStartOff(), + KMByteBlob.cast(keyBlob).length()); + short len = KMArray.cast(ret).length(); + ptr = KMArray.cast(ret).get((short)4); +// print(KMByteBlob.cast(ptr).getBuffer(),KMByteBlob.cast(ptr).getStartOff(),KMByteBlob.cast(ptr).length()); + return ret; + } + + @Test + public void testRsaGenerateKeySuccess() { + init(); + short ret = generateRsaKey(null, null); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 2048); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.DIGEST_NONE)); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.RSA_PKCS1_1_5_ENCRYPT)); + tag = KMKeyParameters.findTag(KMType.ULONG_TAG, KMType.RSA_PUBLIC_EXPONENT, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getSignificantShort(), 0x01); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 0x01); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.RSA); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.GENERATED); + cleanUp(); + } + + private short generateRsaKey(byte[] clientId, byte[] appData){ + byte[] activeAndCreationDateTime = {0,0,0x01,0x73,0x51,0x7C,(byte)0xCC,0x00}; + short tagCount = 11; + if(clientId != null) tagCount++; + if(appData != null) tagCount++; + short arrPtr = KMArray.instance(tagCount); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)2048)); + short byteBlob = KMByteBlob.instance((short)3); + KMByteBlob.cast(byteBlob).add((short)0, KMType.DIGEST_NONE); + KMByteBlob.cast(byteBlob).add((short)1, KMType.SHA2_256); + KMByteBlob.cast(byteBlob).add((short)2, KMType.SHA1); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + byteBlob = KMByteBlob.instance((short)5); + KMByteBlob.cast(byteBlob).add((short)0, KMType.RSA_PKCS1_1_5_ENCRYPT); + KMByteBlob.cast(byteBlob).add((short)1, KMType.RSA_PKCS1_1_5_SIGN); + KMByteBlob.cast(byteBlob).add((short)2, KMType.RSA_OAEP); + KMByteBlob.cast(byteBlob).add((short)3, KMType.RSA_PSS); + KMByteBlob.cast(byteBlob).add((short)4, KMType.PADDING_NONE); + short padding = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + byteBlob = KMByteBlob.instance((short)5); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SIGN); + KMByteBlob.cast(byteBlob).add((short)1, KMType.VERIFY); + KMByteBlob.cast(byteBlob).add((short)2, KMType.ENCRYPT); + KMByteBlob.cast(byteBlob).add((short)3, KMType.DECRYPT); + KMByteBlob.cast(byteBlob).add((short)4, KMType.WRAP_KEY); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + byte[] pub = {0,1,0,1}; + short rsaPubExpTag = KMIntegerTag.instance(KMType.ULONG_TAG,KMType.RSA_PUBLIC_EXPONENT, KMInteger.uint_32(pub, (short)0)); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.INCLUDE_UNIQUE_ID)); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.RESET_SINCE_ID_ROTATION)); + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, digest); + KMArray.cast(arrPtr).add(tagIndex++, rsaPubExpTag); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.RSA)); + KMArray.cast(arrPtr).add(tagIndex++, padding); + short dateTag = KMInteger.uint_64(activeAndCreationDateTime,(short)0); + KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.DATE_TAG,KMType.ACTIVE_DATETIME,dateTag)); + KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.DATE_TAG,KMType.CREATION_DATETIME,dateTag)); + + if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); + if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + arrPtr = KMArray.instance((short)1); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + return ret; + } + + private short generateAttestationKey(){ + // 15th July 2020 00.00.00 + byte[] activeAndCreationDateTime = {0,0,0x01,0x73,0x51,0x7C,(byte)0xCC,0x00}; + short tagCount = 11; + short arrPtr = KMArray.instance(tagCount); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)2048)); + short byteBlob = KMByteBlob.instance((short)3); + KMByteBlob.cast(byteBlob).add((short)0, KMType.DIGEST_NONE); + KMByteBlob.cast(byteBlob).add((short)1, KMType.SHA2_256); + KMByteBlob.cast(byteBlob).add((short)2, KMType.SHA1); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.RSA_PKCS1_1_5_SIGN); + short padding = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ATTEST_KEY); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + byte[] pub = {0,1,0,1}; + short rsaPubExpTag = KMIntegerTag.instance(KMType.ULONG_TAG,KMType.RSA_PUBLIC_EXPONENT, KMInteger.uint_32(pub, (short)0)); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.INCLUDE_UNIQUE_ID)); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.RESET_SINCE_ID_ROTATION)); + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, digest); + KMArray.cast(arrPtr).add(tagIndex++, rsaPubExpTag); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.RSA)); + KMArray.cast(arrPtr).add(tagIndex++, padding); + short dateTag = KMInteger.uint_64(activeAndCreationDateTime,(short)0); + KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.ULONG_TAG,KMType.ACTIVE_DATETIME,dateTag)); + KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.ULONG_TAG,KMType.CREATION_DATETIME,dateTag)); + short keyParams = KMKeyParameters.instance(arrPtr); + arrPtr = KMArray.instance((short)1); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + return ret; + } + + @Test + public void testEcGenerateKeySuccess() { + init(); + short ret = generateEcKey(null, null); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 256); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.DIGEST_NONE)); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.EC); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.GENERATED); + cleanUp(); + } + public short generateEcKey(byte[] clientId, byte[] appData) { + byte[] activeAndCreationDateTime = {0,0,0x01,0x73,0x51,0x7C,(byte)0xCC,0x00}; + short tagCount = 6; + if(clientId != null) tagCount++; + if(appData != null) tagCount++; + short arrPtr = KMArray.instance(tagCount); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)256)); + short byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.DIGEST_NONE); + KMByteBlob.cast(byteBlob).add((short)1, KMType.SHA2_256); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SIGN); + KMByteBlob.cast(byteBlob).add((short)1, KMType.VERIFY); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, digest); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.EC)); + short dateTag = KMInteger.uint_64(activeAndCreationDateTime,(short)0); + KMArray.cast(arrPtr).add(tagIndex++, KMIntegerTag.instance(KMType.DATE_TAG,KMType.CREATION_DATETIME,dateTag)); + if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); + if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + arrPtr = KMArray.instance((short)1); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + return ret; + } + + @Test + public void testHmacGenerateKeySuccess() { + init(); + short ret = generateHmacKey(null, null); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.DIGEST, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.SHA2_256)); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 160); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.HMAC); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.GENERATED); + cleanUp(); + } + public short generateHmacKey(byte[] clientId, byte[] appData){ + short tagCount = 6; + if(clientId != null) tagCount++; + if(appData != null) tagCount++; + short arrPtr = KMArray.instance(tagCount); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SHA2_256); + short digest = KMEnumArrayTag.instance(KMType.DIGEST, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.SIGN); + KMByteBlob.cast(byteBlob).add((short)1, KMType.VERIFY); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short minMacLen = KMIntegerTag.instance(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, KMInteger.uint_16((short)/*256*/160)); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, minMacLen); + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, digest); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.HMAC)); + if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); + if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + arrPtr = KMArray.instance((short)1); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + return ret; + } + public short generateAesDesKey(byte alg, short keysize, byte[] clientId, byte[] appData, boolean unlockReqd) { + short tagCount = 7; + if(clientId != null) tagCount++; + if(appData != null) tagCount++; + if(unlockReqd)tagCount++; + short arrPtr = KMArray.instance(tagCount); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16(keysize)); + short byteBlob = KMByteBlob.instance((short)3); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ECB); + KMByteBlob.cast(byteBlob).add((short)1, KMType.CBC); + KMByteBlob.cast(byteBlob).add((short)2, KMType.CTR); + short blockModeTag = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.PKCS7); + KMByteBlob.cast(byteBlob).add((short)1, KMType.PADDING_NONE); + short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ENCRYPT); + KMByteBlob.cast(byteBlob).add((short)1, KMType.DECRYPT); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, blockModeTag); + KMArray.cast(arrPtr).add(tagIndex++, paddingMode); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, alg)); + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.CALLER_NONCE)); + if(unlockReqd)KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.UNLOCKED_DEVICE_REQUIRED)); + if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); + if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + arrPtr = KMArray.instance((short)1); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + return ret; + } + public short generateAesGcmKey(short keysize, byte[] clientId, byte[] appData) { + short tagCount = 8; + if(clientId != null) tagCount++; + if(appData != null) tagCount++; + short arrPtr = KMArray.instance(tagCount); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16(keysize)); + short macLength = KMIntegerTag.instance(KMType.UINT_TAG, KMType.MIN_MAC_LENGTH, KMInteger.uint_16((short)96)); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.GCM); + short blockModeTag = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, KMType.PADDING_NONE); + short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ENCRYPT); + KMByteBlob.cast(byteBlob).add((short)1, KMType.DECRYPT); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, macLength); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, blockModeTag); + KMArray.cast(arrPtr).add(tagIndex++, paddingMode); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.AES)); + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.CALLER_NONCE)); + if(clientId != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); + if(appData != null)KMArray.cast(arrPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + arrPtr = KMArray.instance((short)1); + KMArray arg = KMArray.cast(arrPtr); + arg.add((short) 0, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_GENERATE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + return ret; + } + + @Test + public void testComputeHmacParams(){ + init(); + // Get Hmac parameters + short ret = getHmacSharingParams(); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + KMHmacSharingParameters params = KMHmacSharingParameters.cast(KMArray.cast(ret).get((short)1)); + short seed = params.getSeed(); + short nonce = params.getNonce(); + + short params1 = KMHmacSharingParameters.instance(); + KMHmacSharingParameters.cast(params1).setSeed(KMByteBlob.instance((short)0)); + short num = KMByteBlob.instance((short)32); + Util.arrayCopyNonAtomic( + KMByteBlob.cast(nonce).getBuffer(), + KMByteBlob.cast(nonce).getStartOff(), + KMByteBlob.cast(num).getBuffer(), + KMByteBlob.cast(num).getStartOff(), + KMByteBlob.cast(num).length()); + // cryptoProvider.newRandomNumber( +// KMByteBlob.cast(num).getBuffer(), +// KMByteBlob.cast(num).getStartOff(), +// KMByteBlob.cast(num).length()); + KMHmacSharingParameters.cast(params1).setNonce(num); + short params2 = KMHmacSharingParameters.instance(); + KMHmacSharingParameters.cast(params2).setSeed(KMByteBlob.instance((short)0)); + num = KMByteBlob.instance((short)32); + cryptoProvider.newRandomNumber( + KMByteBlob.cast(num).getBuffer(), + KMByteBlob.cast(num).getStartOff(), + KMByteBlob.cast(num).length()); + KMHmacSharingParameters.cast(params2).setNonce(num); + short arr = KMArray.instance((short)2); + KMArray.cast(arr).add((short)0, params1); + KMArray.cast(arr).add((short)1,params2); + short arrPtr = KMArray.instance((short)1); + KMArray.cast(arrPtr).add((short)0,arr); + CommandAPDU apdu = encodeApdu((byte)INS_COMPUTE_SHARED_HMAC_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + Assert.assertEquals(0x9000, response.getSW()); + ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + + cleanUp(); + } + @Test + public void testGetHmacSharingParams(){ + init(); + CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_GET_HMAC_SHARING_PARAM_CMD, 0x40, 0x00); + //print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(commandAPDU); + KMDecoder dec = new KMDecoder(); + short ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + short inst = KMHmacSharingParameters.exp(); + KMArray.cast(ret).add((short) 1, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + KMHmacSharingParameters params = KMHmacSharingParameters.cast(KMArray.cast(ret).get((short)1)); + short seed = params.getSeed(); + short nonce = params.getNonce(); + Assert.assertTrue(KMByteBlob.cast(seed).length() == 0); + Assert.assertTrue(KMByteBlob.cast(nonce).length() == 32); + //print(seed); + //print(nonce); + Assert.assertEquals(error, KMError.OK); + cleanUp(); + } + public short getHmacSharingParams(){ + CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_GET_HMAC_SHARING_PARAM_CMD, 0x40, 0x00); + //print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(commandAPDU); + KMDecoder dec = new KMDecoder(); + short ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + short inst = KMHmacSharingParameters.exp(); + KMArray.cast(ret).add((short) 1, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + return ret; + } + + @Test + public void testImportWrappedKey(){ + init(); + byte[] wrappedKey = new byte[16]; + cryptoProvider.newRandomNumber(wrappedKey,(short)0,(short)16); + byte[] encWrappedKey = new byte[16]; + //AESKey transportKey = cryptoProvider.createAESKey((short)256); + byte[] transportKeyMaterial = new byte[32]; + cryptoProvider.newRandomNumber(transportKeyMaterial,(short)0,(short)32); + //transportKey.setKey(transportKeyMaterial,(short)0); + byte[] nonce = new byte[12]; + cryptoProvider.newRandomNumber(nonce,(short)0,(short)12); + byte[] authData = "Auth Data".getBytes(); + byte[] authTag = new byte[12]; + cryptoProvider.aesGCMEncrypt(transportKeyMaterial,(short)0,(short)32,wrappedKey, + (short)0,(short)16,encWrappedKey,(short)0, + nonce,(short)0, (short)12,authData,(short)0,(short)authData.length, + authTag, (short)0, (short)12); + byte[] maskingKey = {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0}; + byte[] maskedTransportKey = new byte[32]; + for(int i=0; i< maskingKey.length;i++){ + maskedTransportKey[i] = (byte)(transportKeyMaterial[i] ^ maskingKey[i]); + } + short rsaKeyArr = generateRsaKey(null,null); + short keyBlobPtr = KMArray.cast(rsaKeyArr).get((short)1); + byte[] wrappingKeyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), + KMByteBlob.cast(keyBlobPtr).getStartOff(), + wrappingKeyBlob,(short)0, (short)wrappingKeyBlob.length); + short inParams = getRsaParams(KMType.SHA2_256, KMType.RSA_OAEP); + short ret = processMessage(maskedTransportKey, + KMByteBlob.instance(wrappingKeyBlob,(short)0, (short)wrappingKeyBlob.length), + KMType.ENCRYPT, + KMKeyParameters.instance(inParams), + (short)0,null,false,false + ); + keyBlobPtr = KMArray.cast(ret).get((short)2); + byte[] encTransportKey = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + encTransportKey,(short)0, (short)encTransportKey.length); + short tagCount = 7; + short arrPtr = KMArray.instance(tagCount); + short boolTag = KMBoolTag.instance(KMType.NO_AUTH_REQUIRED); + short keySize = KMIntegerTag.instance(KMType.UINT_TAG, KMType.KEYSIZE, KMInteger.uint_16((short)128)); + short byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ECB); + KMByteBlob.cast(byteBlob).add((short)1, KMType.CBC); + short blockModeTag = KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.PKCS7); + KMByteBlob.cast(byteBlob).add((short)1, KMType.PADDING_NONE); + short paddingMode = KMEnumArrayTag.instance(KMType.PADDING, byteBlob); + byteBlob = KMByteBlob.instance((short)2); + KMByteBlob.cast(byteBlob).add((short)0, KMType.ENCRYPT); + KMByteBlob.cast(byteBlob).add((short)1, KMType.DECRYPT); + short purpose = KMEnumArrayTag.instance(KMType.PURPOSE, byteBlob); + short tagIndex = 0; + KMArray.cast(arrPtr).add(tagIndex++, boolTag); + KMArray.cast(arrPtr).add(tagIndex++, keySize); + KMArray.cast(arrPtr).add(tagIndex++, blockModeTag); + KMArray.cast(arrPtr).add(tagIndex++, paddingMode); + KMArray.cast(arrPtr).add(tagIndex++, KMEnumTag.instance(KMType.ALGORITHM, KMType.AES)); + KMArray.cast(arrPtr).add(tagIndex++, purpose); + KMArray.cast(arrPtr).add(tagIndex++, KMBoolTag.instance(KMType.CALLER_NONCE)); + short keyParams = KMKeyParameters.instance(arrPtr); + short nullParams = KMArray.instance((short)0); + nullParams = KMKeyParameters.instance(nullParams); + short arr = KMArray.instance((short)12); + KMArray.cast(arr).add((short) 0, keyParams); // Key Params of wrapped key + KMArray.cast(arr).add((short) 1, KMEnum.instance(KMType.KEY_FORMAT,KMType.RAW)); // Key Format + KMArray.cast(arr).add((short) 2, KMByteBlob.instance(encWrappedKey,(short)0,(short)encWrappedKey.length)); // Wrapped Import Key Blob + KMArray.cast(arr).add((short) 3, KMByteBlob.instance(authTag,(short)0,(short)authTag.length)); // Auth Tag + KMArray.cast(arr).add((short) 4, KMByteBlob.instance(nonce,(short)0,(short)nonce.length)); // IV - Nonce + KMArray.cast(arr).add((short) 5, KMByteBlob.instance(encTransportKey,(short)0,(short)encTransportKey.length)); // Encrypted Transport Key + KMArray.cast(arr).add((short) 6, KMByteBlob.instance(wrappingKeyBlob,(short)0, (short)wrappingKeyBlob.length)); // Wrapping Key KeyBlob + KMArray.cast(arr).add((short) 7, KMByteBlob.instance(maskingKey,(short)0,(short)maskingKey.length)); // Masking Key + KMArray.cast(arr).add((short) 8, nullParams); // Un-wrapping Params + KMArray.cast(arr).add((short) 9, KMByteBlob.instance(authData,(short)0,(short)authData.length)); // Wrapped Key ASSOCIATED AUTH DATA + KMArray.cast(arr).add((short) 10, KMInteger.uint_8((byte)0)); // Password Sid + KMArray.cast(arr).add((short) 11, KMInteger.uint_8((byte)0)); // Biometric Sid + CommandAPDU apdu = encodeApdu((byte)INS_IMPORT_WRAPPED_KEY_CMD, arr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + Assert.assertEquals(0x9000, response.getSW()); + Assert.assertEquals(error, KMError.OK); + short tag = KMKeyParameters.findTag(KMType.BOOL_TAG, KMType.NO_AUTH_REQUIRED, hwParams); + Assert.assertEquals(KMBoolTag.cast(tag).getVal(),0x01); + tag = KMKeyParameters.findTag(KMType.UINT_TAG, KMType.KEYSIZE, hwParams); + Assert.assertEquals(KMInteger.cast(KMIntegerTag.cast(tag).getValue()).getShort(), 128); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PADDING, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.PKCS7)); + tag = KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.BLOCK_MODE, hwParams); + Assert.assertTrue(KMEnumArrayTag.cast(tag).contains(KMType.ECB)); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ALGORITHM, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.AES); + tag = KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.ORIGIN, hwParams); + Assert.assertEquals(KMEnumTag.cast(tag).getValue(), KMType.SECURELY_IMPORTED); + cleanUp(); + } + + @Test + public void testGetKeyCharacteristicsWithIdDataSuccess() { + init(); + byte[] clientId = "clientId".getBytes(); + byte[] appData = "appData".getBytes(); + short ret = generateRsaKey(clientId,appData); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + short keyBlob = KMArray.cast(ret).get((short)1); + + short arrPtr = KMArray.instance((short)3); + KMArray.cast(arrPtr).add((short)0, keyBlob); + KMArray.cast(arrPtr).add((short)1, KMByteBlob.instance(clientId,(short)0, (short)clientId.length)); + KMArray.cast(arrPtr).add((short)2, KMByteBlob.instance(appData,(short)0, (short)appData.length)); + CommandAPDU apdu = encodeApdu((byte)INS_GET_KEY_CHARACTERISTICS_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 1, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + cleanUp(); + } + + @Test + public void testGetKeyCharacteristicsSuccess() { + init(); + short ret = generateRsaKey(null, null); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + short keyBlob = KMArray.cast(ret).get((short)1); + + short arrPtr = KMArray.instance((short)3); + KMArray.cast(arrPtr).add((short)0, keyBlob); + KMArray.cast(arrPtr).add((short)1, KMByteBlob.instance((short)0)); + KMArray.cast(arrPtr).add((short)2, KMByteBlob.instance((short)0)); + CommandAPDU apdu = encodeApdu((byte)INS_GET_KEY_CHARACTERISTICS_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 1, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + cleanUp(); + } + + @Test + public void testDeleteKeySuccess() { + init(); + short ret = generateRsaKey(null, null); + short keyBlobPtr = KMArray.cast(ret).get((short)1); + byte[] keyBlob = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + short len = KMByteBlob.cast(keyBlobPtr).getValues(keyBlob, (short)0); + ret = getKeyCharacteristics(keyBlobPtr); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + ret = deleteKey(KMByteBlob.instance(keyBlob,(short)0,(short)keyBlob.length)); + Assert.assertEquals(ret, KMError.OK); +/* ret = getKeyCharacteristics(KMByteBlob.instance(keyBlob,(short)0,(short)keyBlob.length)); + short err = KMByteBlob.cast(ret).get((short)1); + Assert.assertEquals(KMError.INVALID_KEY_BLOB,err); + + */ + cleanUp(); + } + + @Test + public void testDeleteAllKeySuccess() { + init(); + short ret1 = generateRsaKey(null, null); + short keyBlobPtr = KMArray.cast(ret1).get((short)1); + byte[] keyBlob1 = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + short len = KMByteBlob.cast(keyBlobPtr).getValues(keyBlob1, (short)0); + short ret2 = generateRsaKey(null, null); + keyBlobPtr = KMArray.cast(ret2).get((short)1); + byte[] keyBlob2 = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + len = KMByteBlob.cast(keyBlobPtr).getValues(keyBlob2, (short)0); + CommandAPDU apdu = new CommandAPDU(0x80, INS_DELETE_ALL_KEYS_CMD, 0x40, 0x00); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + byte[] respBuf = response.getBytes(); + Assert.assertEquals(respBuf[0], KMError.OK); +/* short ret = getKeyCharacteristics(KMByteBlob.instance(keyBlob1,(short)0,(short)keyBlob1.length)); + short err = KMByteBlob.cast(ret).get((short)1); + Assert.assertEquals(KMError.INVALID_KEY_BLOB,err); + ret = getKeyCharacteristics(KMByteBlob.instance(keyBlob2,(short)0,(short)keyBlob2.length)); + err = KMByteBlob.cast(ret).get((short)1); + Assert.assertEquals(KMError.INVALID_KEY_BLOB,err); + + */ + cleanUp(); + } + + private short deleteKey(short keyBlob) { + short arrPtr = KMArray.instance((short)1); + KMArray.cast(arrPtr).add((short)0, keyBlob); + CommandAPDU apdu = encodeApdu((byte)INS_DELETE_KEY_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + byte[] respBuf = response.getBytes(); + return respBuf[0]; + } + + private short abort(short opHandle) { + short arrPtr = KMArray.instance((short)1); + KMArray.cast(arrPtr).add((short)0, opHandle); + CommandAPDU apdu = encodeApdu((byte)INS_ABORT_OPERATION_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + byte[] respBuf = response.getBytes(); + return respBuf[0]; + } + + public short getKeyCharacteristics(short keyBlob){ + short arrPtr = KMArray.instance((short)3); + KMArray.cast(arrPtr).add((short)0, keyBlob); + KMArray.cast(arrPtr).add((short)1, KMByteBlob.instance((short)0)); + KMArray.cast(arrPtr).add((short)2, KMByteBlob.instance((short)0)); + CommandAPDU apdu = encodeApdu((byte)INS_GET_KEY_CHARACTERISTICS_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 1, inst); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + if( len > 5) + ret = decoder.decode(ret, respBuf, (short) 0, len); + else + ret = KMByteBlob.instance(respBuf, (short)0, len); + return ret; + } + + @Test + public void testWithAesGcmWithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.GCM, KMType.PADDING_NONE,true); + cleanUp(); + } + @Test + public void testWithAesEcbPkcs7WithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PKCS7,true); + cleanUp(); + } + + @Test + public void testWithAesCtrNoPadWithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.CTR, KMType.PADDING_NONE,true); + cleanUp(); + } + + @Test + public void testWithAesCtrNoPad(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.CTR, KMType.PADDING_NONE,false); + cleanUp(); + } + + @Test + public void testWithAesEcbNoPadWithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PADDING_NONE,true); + cleanUp(); + } + @Test + public void testWithDesEcbPkcs7WithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PKCS7,true); + cleanUp(); + } + @Test + public void testWithDesEcbNoPadWithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PADDING_NONE,true); + cleanUp(); + } + @Test + public void testWithAesCbcPkcs7WithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PKCS7,true); + cleanUp(); + } + @Test + public void testWithAesCbcNoPadWithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PADDING_NONE,true); + cleanUp(); + } + @Test + public void testWithDesCbcPkcs7WithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PKCS7,true); + cleanUp(); + } + @Test + public void testWithDesCbcNoPadWithUpdate(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PADDING_NONE,true); + cleanUp(); + } + + @Test + public void testWithAesEcbPkcs7(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PKCS7,false); + cleanUp(); + } + @Test + public void testWithAesCbcPkcs7(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PKCS7,false); + cleanUp(); + } + @Test + public void testWithAesEcbNoPad(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.ECB, KMType.PADDING_NONE,false); + cleanUp(); + } + + @Test + public void testWithAesCbcNoPad(){ + init(); + testEncryptDecryptWithAesDes(KMType.AES, KMType.CBC, KMType.PADDING_NONE,false); + cleanUp(); + } + + @Test + public void testWithDesCbcPkcs7(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PKCS7,false); + cleanUp(); + } + + @Test + public void testWithDesCbcNoPad(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.CBC, KMType.PADDING_NONE,false); + cleanUp(); + } + @Test + public void testWithDesEcbNoPad(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PADDING_NONE,false); + cleanUp(); + } + @Test + public void testWithDesEcbPkcs7(){ + init(); + testEncryptDecryptWithAesDes(KMType.DES, KMType.ECB, KMType.PKCS7,false); + cleanUp(); + } + + @Test + public void testWithRsa256Oaep(){ + init(); + testEncryptDecryptWithRsa(KMType.SHA2_256, KMType.RSA_OAEP); + cleanUp(); + } + @Test + public void testWithRsaSha1Oaep(){ + init(); + testEncryptDecryptWithRsa(KMType.SHA1, KMType.RSA_OAEP); + cleanUp(); + } + + @Test + public void testWithRsaNonePkcs1(){ + init(); + testEncryptDecryptWithRsa(KMType.DIGEST_NONE, KMType.RSA_PKCS1_1_5_ENCRYPT); + cleanUp(); + } + + @Test + public void testWithRsaNoneNoPad(){ + init(); + testEncryptDecryptWithRsa(KMType.DIGEST_NONE, KMType.PADDING_NONE); + cleanUp(); + } + + // TODO Signing with no digest is not supported by crypto provider or javacard + @Test + public void testSignWithRsaNoneNoPad(){ + init(); + testSignVerifyWithRsa(KMType.DIGEST_NONE, KMType.PADDING_NONE,false, false); + cleanUp(); + } + + @Test + public void testSignWithRsaNonePkcs1(){ + init(); + testSignVerifyWithRsa(KMType.DIGEST_NONE, KMType.RSA_PKCS1_1_5_SIGN,false, false); + cleanUp(); + } + + @Test + public void testSignVerifyWithHmacSHA256WithUpdate(){ + init(); + testSignVerifyWithHmac(KMType.SHA2_256, true); + cleanUp(); + } + + @Test + public void testSignVerifyWithHmacSHA256(){ + init(); + testSignVerifyWithHmac(KMType.SHA2_256, false); + cleanUp(); + } + + @Test + public void testSignVerifyWithEcdsaSHA256WithUpdate(){ + init(); + testSignVerifyWithEcdsa(KMType.SHA2_256, true); + cleanUp(); + } + @Test + public void testSignVerifyWithEcdsaSHA256(){ + init(); + testSignVerifyWithEcdsa(KMType.SHA2_256, false); + cleanUp(); + } + @Test + public void testSignVerifyWithRsaSHA256Pkcs1(){ + init(); + testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PKCS1_1_5_SIGN,false, true); + cleanUp(); + } + @Test + public void testSignVerifyWithRsaSHA256Pss(){ + init(); + testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PSS,false, true); + cleanUp(); + } + + @Test + public void testSignVerifyWithRsaSHA256Pkcs1WithUpdate(){ + init(); + testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PKCS1_1_5_SIGN,true, true); + cleanUp(); + } + + @Test + public void testProvisionSuccess(){ + AID appletAID1 = AIDUtil.create("A000000062"); + simulator.installApplet(appletAID1, KMJCardSimApplet.class); + // Select applet + simulator.selectApplet(appletAID1); + // provision attest key + provisionCmd(simulator); + cleanUp(); + } + + @Test + public void testAttestRsaKey(){ + init(); + short key = generateRsaKey(null,null); + short keyBlobPtr = KMArray.cast(key).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic( + KMByteBlob.cast(keyBlobPtr).getBuffer(), + KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + testAttestKey(keyBlob); + cleanUp(); + } + + @Test + public void testAttestEcKey(){ + init(); + short key = generateEcKey(null,null); + short keyBlobPtr = KMArray.cast(key).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic( + KMByteBlob.cast(keyBlobPtr).getBuffer(), + KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + testAttestKey(keyBlob); + cleanUp(); + } + + public void testAttestKey(byte[] keyBlob){ + /* + short key = generateRsaKey(null,null); + short keyBlobPtr = KMArray.cast(key).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic( + KMByteBlob.cast(keyBlobPtr).getBuffer(), + KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + */ + short arrPtr = KMArray.instance((short)2); + KMArray.cast(arrPtr).add((short)0, KMByteTag.instance(KMType.ATTESTATION_APPLICATION_ID, + KMByteBlob.instance(attAppId,(short)0,(short)attAppId.length))); + KMArray.cast(arrPtr).add((short)1, KMByteTag.instance(KMType.ATTESTATION_CHALLENGE, + KMByteBlob.instance(attChallenge,(short)0,(short)attChallenge.length))); + short keyParams = KMKeyParameters.instance(arrPtr); + short args = KMArray.instance((short)2); + KMArray.cast(args).add((short)0, KMByteBlob.instance(keyBlob,(short)0,(short)keyBlob.length)); + KMArray.cast(args).add((short)1, keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_ATTEST_KEY_CMD, args); + //print(apdu.getBytes(),(short)0,(short)apdu.getBytes().length); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 2); + short arrBlobs = KMArray.instance((short)1); + KMArray.cast(arrBlobs).add((short)0, KMByteBlob.exp()); + KMArray.cast(ret).add((short)0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, arrBlobs); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + //(respBuf,(short)0,(short)respBuf.length); + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + arrBlobs = KMArray.cast(ret).get((short)1); + short cert = KMArray.cast(arrBlobs).get((short)0); + //printCert(KMByteBlob.cast(cert).getBuffer(),KMByteBlob.cast(cert).getStartOff(),KMByteBlob.cast(cert).length()); + } + + @Test + public void testUpgradeKey(){ + init(); + short ret = generateHmacKey(null, null); + short keyBlobPtr = KMArray.cast(ret).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + short osVersion = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_VERSION,hwParams); + osVersion = KMIntegerTag.cast(osVersion).getValue(); + short osPatch = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_PATCH_LEVEL,hwParams); + osPatch = KMIntegerTag.cast(osPatch).getValue(); + Assert.assertEquals(KMInteger.cast(osVersion).getShort(), 1); + Assert.assertEquals(KMInteger.cast(osPatch).getShort(), 1); + setBootParams(simulator,(short) 2,(short)2, (short)1, (short)1); + ret = upgradeKey(KMByteBlob.instance(keyBlob, (short)0, (short)keyBlob.length),null, null); + keyBlobPtr = KMArray.cast(ret).get((short)1); + ret = getKeyCharacteristics(keyBlobPtr); + keyCharacteristics = KMArray.cast(ret).get((short)1); + hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + osVersion = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_VERSION,hwParams); + osVersion = KMIntegerTag.cast(osVersion).getValue(); + osPatch = KMKeyParameters.findTag(KMType.UINT_TAG,KMType.OS_PATCH_LEVEL,hwParams); + osPatch = KMIntegerTag.cast(osPatch).getValue(); + Assert.assertEquals(KMInteger.cast(osVersion).getShort(), 2); + Assert.assertEquals(KMInteger.cast(osPatch).getShort(), 2); + cleanUp(); + } + + @Test + public void testDestroyAttIds(){ + init(); + CommandAPDU commandAPDU = new CommandAPDU(0x80, INS_DESTROY_ATT_IDS_CMD, 0x40, 0x00); + ResponseAPDU response = simulator.transmitCommand(commandAPDU); + byte[] respBuf = response.getBytes(); + Assert.assertEquals(respBuf[0], 0); + cleanUp(); + } + + private short upgradeKey(short keyBlobPtr, byte[] clientId, byte[] appData){ + short tagCount = 0; + short clientIdTag = 0; + short appDataTag = 0; + if(clientId != null) tagCount++; + if(appData != null) tagCount++; + short keyParams = KMArray.instance(tagCount); + short tagIndex=0; + if(clientId != null)KMArray.cast(keyBlobPtr).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_ID, KMByteBlob.instance(clientId,(short)0,(short)clientId.length))); + if(appData != null)KMArray.cast(keyParams).add(tagIndex++, + KMByteTag.instance(KMType.APPLICATION_DATA, KMByteBlob.instance(appData,(short)0,(short)appData.length))); + keyParams = KMKeyParameters.instance(keyParams); + short arr = KMArray.instance((short)2); + KMArray.cast(arr).add((short)0,keyBlobPtr); + KMArray.cast(arr).add((short)1,keyParams); + CommandAPDU apdu = encodeApdu((byte)INS_UPGRADE_KEY_CMD, arr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 2); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + return ret; + } + @Test + public void testSignVerifyWithRsaSHA256PssWithUpdate(){ + init(); + testSignVerifyWithRsa(KMType.SHA2_256, KMType.RSA_PSS,true, true); + cleanUp(); + } + @Test + public void testAbortOperation(){ + init(); + short aesDesKeyArr = generateAesDesKey(KMType.AES, (short)128,null, null, false);; + short keyBlobPtr = KMArray.cast(aesDesKeyArr).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + byte[] nonce = new byte[16]; + cryptoProvider.newRandomNumber(nonce,(short)0,(short)16); + short inParams = getAesDesParams(KMType.AES,KMType.ECB, KMType.PKCS7, nonce); + byte[] plainData= "Hello World 123!".getBytes(); + short ret = begin(KMType.ENCRYPT, KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), KMKeyParameters.instance(inParams), (short)0); + short opHandle = KMArray.cast(ret).get((short) 2); + opHandle = KMInteger.cast(opHandle).getShort(); + abort(KMInteger.uint_16(opHandle)); + short dataPtr = KMByteBlob.instance(plainData, (short) 0, (short) plainData.length); + ret = update(KMInteger.uint_16(opHandle), dataPtr, (short) 0, (short) 0, (short) 0); + Assert.assertEquals(KMError.INVALID_OPERATION_HANDLE,ret); + cleanUp(); + } + + public void testEncryptDecryptWithAesDes(byte alg, byte blockMode, byte padding, boolean update){ + short aesDesKeyArr; + boolean aesGcmFlag = false; + if(alg == KMType.AES){ + if(blockMode == KMType.GCM){ + aesDesKeyArr = generateAesGcmKey((short)128,null,null); + aesGcmFlag = true; + } else { + aesDesKeyArr = generateAesDesKey(alg, (short) 128, null, null, false); + } + } else{ + aesDesKeyArr = generateAesDesKey(alg, (short)168,null, null, false); + } + short keyBlobPtr = KMArray.cast(aesDesKeyArr).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + byte[] nonce = new byte[16]; + cryptoProvider.newRandomNumber(nonce,(short)0,(short)16); + short inParams = getAesDesParams(alg,blockMode, padding, nonce); + byte[] plainData= "Hello World 123!".getBytes(); + if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); + //Encrypt + short ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.ENCRYPT, + KMKeyParameters.instance(inParams), + (short)0,null,update, aesGcmFlag + ); + inParams = getAesDesParams(alg,blockMode, padding, nonce); + keyBlobPtr = KMArray.cast(ret).get((short)2); + //print(keyBlobPtr); + byte[] cipherData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + cipherData,(short)0, (short)cipherData.length); + ret = processMessage(cipherData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.DECRYPT, + KMKeyParameters.instance(inParams), + (short)0,null,update, aesGcmFlag + ); + keyBlobPtr = KMArray.cast(ret).get((short)2); + //print(plainData,(short)0,(short)plainData.length); + //print(keyBlobPtr); + short equal = Util.arrayCompare(plainData,(short)0,KMByteBlob.cast(keyBlobPtr).getBuffer(), + KMByteBlob.cast(keyBlobPtr).getStartOff(),(short)plainData.length); + Assert.assertTrue(equal == 0); + } + + public void testEncryptDecryptWithRsa(byte digest, byte padding){ + short rsaKeyArr = generateRsaKey(null, null); + short keyBlobPtr = KMArray.cast(rsaKeyArr).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + short inParams = getRsaParams(digest, padding); + byte[] plainData = "Hello World 123!".getBytes(); + //Encrypt + short ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.ENCRYPT, + KMKeyParameters.instance(inParams), + (short)0,null,false, false + ); + inParams = getRsaParams(digest, padding); + keyBlobPtr = KMArray.cast(ret).get((short)2); + byte[] cipherData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + cipherData,(short)0, (short)cipherData.length); + ret = processMessage(cipherData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.DECRYPT, + KMKeyParameters.instance(inParams), + (short)0,null,false,false + ); + keyBlobPtr = KMArray.cast(ret).get((short)2); + short len = KMByteBlob.cast(keyBlobPtr).length(); + short start = KMByteBlob.cast(keyBlobPtr).getStartOff(); + short equal = Util.arrayCompare(plainData,(short)0,KMByteBlob.cast(keyBlobPtr).getBuffer(), + (short)(start+len-plainData.length),(short)plainData.length); + Assert.assertTrue(equal == 0); + } + + public void testSignVerifyWithRsa(byte digest, byte padding, boolean update, boolean verifyFlag){ + short rsaKeyArr = generateRsaKey(null, null); + short keyBlobPtr = KMArray.cast(rsaKeyArr).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + short inParams = getRsaParams(digest, padding); + byte[] plainData = "Hello World 123!".getBytes(); + if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); + //Sign + short ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.SIGN, + KMKeyParameters.instance(inParams), + (short)0,null,update,false + ); + inParams = getRsaParams(digest, padding); + keyBlobPtr = KMArray.cast(ret).get((short)2); + byte[] signatureData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + signatureData,(short)0, (short)signatureData.length); + if(verifyFlag == false) { + Assert.assertEquals(signatureData.length,256); + return; + } + ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.VERIFY, + KMKeyParameters.instance(inParams), + (short)0,signatureData,update,false + ); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + } + + public void testSignVerifyWithEcdsa(byte digest, boolean update){ + short ecKeyArr = generateEcKey(null, null); + short keyBlobPtr = KMArray.cast(ecKeyArr).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + short inParams = getEcParams(digest); + byte[] plainData = "Hello World 123!".getBytes(); + if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); + //Sign + short ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.SIGN, + KMKeyParameters.instance(inParams), + (short)0,null,update,false + ); + inParams = getEcParams(digest); + keyBlobPtr = KMArray.cast(ret).get((short)2); + byte[] signatureData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + signatureData,(short)0, (short)signatureData.length); + ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.VERIFY, + KMKeyParameters.instance(inParams), + (short)0,signatureData,update,false + ); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + } + public void testSignVerifyWithHmac(byte digest, boolean update){ + short hmacKeyArr = generateHmacKey(null, null); + short keyBlobPtr = KMArray.cast(hmacKeyArr).get((short)1); + byte[] keyBlob= new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + keyBlob,(short)0, (short)keyBlob.length); + short inParams = getHmacParams(digest,true); + byte[] plainData = "Hello World 123!".getBytes(); + if(update) plainData= "Hello World 123! Hip Hip Hoorah!".getBytes(); + //Sign + short ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.SIGN, + KMKeyParameters.instance(inParams), + (short)0,null,update,false + ); + inParams = getHmacParams(digest,false); + keyBlobPtr = KMArray.cast(ret).get((short)2); + byte[] signatureData = new byte[KMByteBlob.cast(keyBlobPtr).length()]; + Util.arrayCopyNonAtomic(KMByteBlob.cast(keyBlobPtr).getBuffer(), KMByteBlob.cast(keyBlobPtr).getStartOff(), + signatureData,(short)0, (short)signatureData.length); + ret = processMessage(plainData, + KMByteBlob.instance(keyBlob,(short)0, (short)keyBlob.length), + KMType.VERIFY, + KMKeyParameters.instance(inParams), + (short)0,signatureData,update,false + ); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + } + + private short getAesDesParams(byte alg, byte blockMode, byte padding, byte[] nonce) { + short inParams; + if(blockMode == KMType.GCM){ + inParams = KMArray.instance((short)5); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, blockMode); + KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob)); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, padding); + KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); + short nonceLen = 12; + byteBlob = KMByteBlob.instance(nonce,(short)0, nonceLen); + KMArray.cast(inParams).add((short)2, KMByteTag.instance(KMType.NONCE, byteBlob)); + short macLen = KMInteger.uint_16((short)128); + macLen = KMIntegerTag.instance(KMType.UINT_TAG,KMType.MAC_LENGTH,macLen); + KMArray.cast(inParams).add((short)3, macLen); + byte[] authData = "AuthData".getBytes(); + short associatedData = KMByteBlob.instance(authData,(short)0,(short)authData.length); + associatedData = KMByteTag.instance(KMType.ASSOCIATED_DATA,associatedData); + KMArray.cast(inParams).add((short)4, associatedData); + }else if(blockMode == KMType.ECB){ + inParams = KMArray.instance((short)2); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, blockMode); + KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob)); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, padding); + KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); + }else{ + inParams = KMArray.instance((short)3); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, blockMode); + KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.BLOCK_MODE, byteBlob)); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, padding); + KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); + short nonceLen = 16; + if(alg == KMType.DES) nonceLen = 8; + byteBlob = KMByteBlob.instance(nonce,(short)0, nonceLen); + KMArray.cast(inParams).add((short)2, KMByteTag.instance(KMType.NONCE, byteBlob)); + } + return inParams; + } + + private short getRsaParams(byte digest, byte padding) { + short inParams = KMArray.instance((short)2); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, digest); + KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.DIGEST, byteBlob)); + byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, padding); + KMArray.cast(inParams).add((short)1, KMEnumArrayTag.instance(KMType.PADDING, byteBlob)); + return inParams; + } + + private short getEcParams(byte digest) { + short inParams = KMArray.instance((short)1); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, digest); + KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.DIGEST, byteBlob)); + return inParams; + } + private short getHmacParams(byte digest, boolean sign) { + short paramsize = (short) (sign ? 2 : 1); + short inParams = KMArray.instance((short)paramsize); + short byteBlob = KMByteBlob.instance((short)1); + KMByteBlob.cast(byteBlob).add((short)0, digest); + KMArray.cast(inParams).add((short)0, KMEnumArrayTag.instance(KMType.DIGEST, byteBlob)); + short macLength = KMIntegerTag.instance(KMType.UINT_TAG,KMType.MAC_LENGTH, KMInteger.uint_16((short)/*256*/160)); + if(sign) + KMArray.cast(inParams).add((short)1, macLength); + return inParams; + } + + public short processMessage( + byte[] data, + short keyBlob, + byte keyPurpose, + short inParams, + short hwToken, + byte[] signature, + boolean updateFlag, + boolean aesGcmFlag) { + short beginResp = begin(keyPurpose, keyBlob, inParams, hwToken); + short opHandle = KMArray.cast(beginResp).get((short) 2); + opHandle = KMInteger.cast(opHandle).getShort(); + short dataPtr = KMByteBlob.instance(data, (short) 0, (short) data.length); + short ret = KMType.INVALID_VALUE; + byte[] outputData = new byte[128]; + short len=0; + inParams = 0; + //Test + short firstDataLen =16; + if (keyPurpose == KMType.DECRYPT) { + firstDataLen = 32; + } + + //Test + + if (updateFlag) { + dataPtr = KMByteBlob.instance(data, (short) 0, (short) /*16*/firstDataLen); + if(aesGcmFlag){ + byte[] authData = "AuthData".getBytes(); + short associatedData = KMByteBlob.instance(authData,(short)0,(short)authData.length); + associatedData = KMByteTag.instance(KMType.ASSOCIATED_DATA,associatedData); + inParams = KMArray.instance((short)1); + KMArray.cast(inParams).add((short)0, associatedData); + inParams = KMKeyParameters.instance(inParams); + } + ret = update(KMInteger.uint_16(opHandle), dataPtr, inParams, (short) 0, (short) 0); + dataPtr = KMArray.cast(ret).get((short) 3); + if (KMByteBlob.cast(dataPtr).length() > 0) { + Util.arrayCopyNonAtomic( + KMByteBlob.cast(dataPtr).getBuffer(), + KMByteBlob.cast(dataPtr).getStartOff(), + outputData, + (short) 0, + KMByteBlob.cast(dataPtr).length()); + len = KMByteBlob.cast(dataPtr).length(); + dataPtr = KMByteBlob.instance(data, len, (short) (data.length - len)); + }else{ + dataPtr = KMByteBlob.instance(data, (short)/*16*/firstDataLen, (short) (data.length - /*16*/firstDataLen)); + } + } + + if (keyPurpose == KMType.VERIFY) { + ret = finish(KMInteger.uint_16(opHandle), dataPtr, signature, (short) 0, (short) 0, (short) 0); + } else { + ret = finish(KMInteger.uint_16(opHandle), dataPtr, null, (short) 0, (short) 0, (short) 0); + } + if(len >0){ + dataPtr = KMArray.cast(ret).get((short)2); + if(KMByteBlob.cast(dataPtr).length() >0){ + Util.arrayCopyNonAtomic( + KMByteBlob.cast(dataPtr).getBuffer(), + KMByteBlob.cast(dataPtr).getStartOff(), + outputData, + len, + KMByteBlob.cast(dataPtr).length()); + len = (short)(len + KMByteBlob.cast(dataPtr).length()); + } + KMArray.cast(ret).add((short)2, KMByteBlob.instance(outputData,(short)0,len)); + } + return ret; + } + + public short begin(byte keyPurpose, short keyBlob, short keyParmas, short hwToken) { + short arrPtr = KMArray.instance((short)4); + KMArray.cast(arrPtr).add((short)0, KMEnum.instance(KMType.PURPOSE, keyPurpose)); + KMArray.cast(arrPtr).add((short)1, keyBlob); + KMArray.cast(arrPtr).add((short)2, keyParmas); + if(hwToken == 0) { + hwToken = KMHardwareAuthToken.instance(); + } + KMArray.cast(arrPtr).add((short)3, hwToken); + CommandAPDU apdu = encodeApdu((byte)INS_BEGIN_OPERATION_CMD, arrPtr); + //print(apdu.getBytes(),(short)0,(short)apdu.getBytes().length); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + short outParams = KMKeyParameters.exp(); + KMArray.cast(ret).add((short)0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, outParams); + KMArray.cast(ret).add((short)2, KMInteger.exp()); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + if(len > 5){ + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + return ret;}else{ + if(len == 3) return respBuf[0]; + if(len == 4) return respBuf[1]; + return Util.getShort(respBuf,(short)0); + } + } + + public short finish(short operationHandle, short data, byte[] signature, short inParams, short hwToken, short verToken) { + if(hwToken == 0) { + hwToken = KMHardwareAuthToken.instance(); + } + if(verToken == 0){ + verToken = KMVerificationToken.instance(); + } + short signatureTag; + if(signature == null){ + signatureTag = KMByteBlob.instance((short)0); + }else{ + signatureTag = KMByteBlob.instance(signature,(short)0,(short)signature.length); + } + if(inParams == 0){ + short arr = KMArray.instance((short)0); + inParams = KMKeyParameters.instance(arr); + } + short arrPtr = KMArray.instance((short)6); + KMArray.cast(arrPtr).add((short)0, operationHandle); + KMArray.cast(arrPtr).add((short)1, inParams); + KMArray.cast(arrPtr).add((short)2, data); + KMArray.cast(arrPtr).add((short)3, signatureTag); + KMArray.cast(arrPtr).add((short)4, hwToken); + KMArray.cast(arrPtr).add((short)5, verToken); + CommandAPDU apdu = encodeApdu((byte)INS_FINISH_OPERATION_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 3); + short outParams = KMKeyParameters.exp(); + KMArray.cast(ret).add((short)0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, outParams); + KMArray.cast(ret).add((short)2, KMByteBlob.exp()); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + Assert.assertEquals(error, KMError.OK); + return ret; + } + public short update(short operationHandle, short data, short inParams, short hwToken, short verToken) { + if(hwToken == 0) { + hwToken = KMHardwareAuthToken.instance(); + } + if(verToken == 0){ + verToken = KMVerificationToken.instance(); + } + if(inParams == 0){ + short arr = KMArray.instance((short)0); + inParams = KMKeyParameters.instance(arr); + } + short arrPtr = KMArray.instance((short)5); + KMArray.cast(arrPtr).add((short)0, operationHandle); + KMArray.cast(arrPtr).add((short)1, inParams); + KMArray.cast(arrPtr).add((short)2, data); + KMArray.cast(arrPtr).add((short)3, hwToken); + KMArray.cast(arrPtr).add((short)4, verToken); + CommandAPDU apdu = encodeApdu((byte)INS_UPDATE_OPERATION_CMD, arrPtr); + // print(commandAPDU.getBytes()); + ResponseAPDU response = simulator.transmitCommand(apdu); + short ret = KMArray.instance((short) 4); + short outParams = KMKeyParameters.exp(); + KMArray.cast(ret).add((short)0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMInteger.exp()); + KMArray.cast(ret).add((short)2, outParams); + KMArray.cast(ret).add((short)3, KMByteBlob.exp()); + byte[] respBuf = response.getBytes(); + short len = (short) respBuf.length; + if (len > 5) { + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short) 0)).getShort(); + Assert.assertEquals(error, KMError.OK); + }else{ + ret = respBuf[1]; + } + return ret; + } + + private void print(short blob){ + print(KMByteBlob.cast(blob).getBuffer(),KMByteBlob.cast(blob).getStartOff(),KMByteBlob.cast(blob).length()); + } + private void print(byte[] buf, short start, short length){ + StringBuilder sb = new StringBuilder(); + for(int i = start; i < (start+length); i++){ + sb.append(String.format(" 0x%02X", buf[i])) ; + } + System.out.println(sb.toString()); + } + private void printCert(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])) ; + } + System.out.println(sb.toString()); + } + + +/* + @Test + public void testApdu(){ + init(); + byte[] cmd = {(byte)0x80,0x11,0x40,0x00,0x00,0x00,0x4C,(byte)0x83,(byte)0xA5,0x1A,0x70,0x00,0x01,(byte)0xF7,0x01,0x1A,0x10, + 0x00,0x00,0x02,0x03,0x1A,0x30,0x00,0x00,0x03,0x19,0x01,0x00,0x1A,0x20,0x00,0x00,0x01,0x42,0x02, + 0x03,0x1A,0x20,0x00,0x00,0x05,0x41,0x04,0x03,0x58,0x24,(byte)0x82,0x58,0x20,0x73,0x7C,0x2E,(byte)0xCD, + 0x7B,(byte)0x8D,0x19,0x40,(byte)0xBF,0x29,0x30,(byte)0xAA,(byte)0x9B,0x4E, + (byte)0xD3,(byte)0xFF,(byte)0x94,0x1E,(byte)0xED,0x09,0x36,0x6B, + (byte)0xC0,0x32,(byte)0x99,(byte)0x98,0x64,(byte)0x81,(byte)0xF3,(byte)0xA4,(byte)0xD8,0x59,0x40}; + CommandAPDU cmdApdu = new CommandAPDU(cmd); + ResponseAPDU resp = simulator.transmitCommand(cmdApdu); + short ret = KMArray.instance((short) 3); + KMArray.cast(ret).add((short) 0, KMInteger.exp()); + KMArray.cast(ret).add((short)1, KMByteBlob.exp()); + short inst = KMKeyCharacteristics.exp(); + KMArray.cast(ret).add((short) 2, inst); + byte[] respBuf = resp.getBytes(); + short len = (short) respBuf.length; + ret = decoder.decode(ret, respBuf, (short) 0, len); + short error = KMInteger.cast(KMArray.cast(ret).get((short)0)).getShort(); + short keyBlobLength = KMByteBlob.cast(KMArray.cast(ret).get((short)1)).length(); + short blobArr = extractKeyBlobArray(KMArray.cast(ret).get((short)1)); + short keyCharacteristics = KMArray.cast(ret).get((short)2); + short hwParams = KMKeyCharacteristics.cast(keyCharacteristics).getHardwareEnforced(); + short swParams = KMKeyCharacteristics.cast(keyCharacteristics).getSoftwareEnforced(); + cleanUp(); + } + */ +} diff --git a/Applet/JavaCardKeymaster.scr b/Applet/JavaCardKeymaster.scr deleted file mode 100644 index 6380faa2..00000000 --- a/Applet/JavaCardKeymaster.scr +++ /dev/null @@ -1,50 +0,0 @@ -output on; - -//create applet instance -0x80 0xB8 0x00 0x00 0x0c 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x00 0x7F; - -// Select JavaCardKeymaster //aid/A000000062/03010C0101 - 0x00 0xa4 0x04 0x00 0x0a 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0xc 0x01 0x01 0x7F; - -// Send provision command - this will change in future - 0x80 0x23 0x40 0x00 0x3B 0x83 0xA1 0x1A 0x10 0x00 0x00 0x02 0x01 0x00 0x58 0x30 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x7F; - -// Send Set Boot Params command - 0x80 0x24 0x40 0x00 0x49 0x86 0x01 0x01 0x58 0x20 0x30 0x30 0x30 0x31 0x31 0x31 0x32 0x32 0x32 0x33 0x33 0x33 0x34 0x34 0x34 0x35 0x35 0x35 0x36 0x36 0x36 0x37 0x37 0x37 0x38 0x38 0x38 0x39 0x39 0x39 0x30 0x30 0x58 0x20 0x30 0x30 0x30 0x31 0x31 0x31 0x32 0x32 0x32 0x33 0x33 0x33 0x34 0x34 0x34 0x35 0x35 0x35 0x36 0x36 0x36 0x37 0x37 0x37 0x38 0x38 0x38 0x39 0x39 0x39 0x30 0x30 0x02 0x00 0x7F; - -// Send getHardwareInfo command - 0x80 0x1E 0x40 0x00 0x00 0x7F; - -// Send AddRngEntropy command - 0x80 0x18 0x40 0x00 0x23 0x81 0x58 0x20 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x7F; - -// Generate Key - RSA Key command - 0x80 0x10 0x40 0x00 0x22 0x81 0xA4 0x1A 0x10 0x00 0x00 0x02 0x01 0x1A 0x30 0x00 0x00 0x03 0x19 0x08 0x00 0x1A 0x50 0x00 0x00 0xC8 0x1A 0x00 0x01 0x00 0x01 0x1A 0x20 0x00 0x00 0x01 0x42 0x02 0x03 0x7F; - -// Generate Key - AES Key command - 0x80 0x10 0x40 0x00 0x23 0x81 0xA4 0x1A 0x10 0x00 0x00 0x02 0x18 0x20 0x1A 0x30 0x00 0x00 0x03 0x19 0x01 0x00 0x1A 0x50 0x00 0x00 0xC8 0x1A 0x00 0x01 0x00 0x01 0x1A 0x20 0x00 0x00 0x01 0x42 0x02 0x03 0x7F; - -// Generate Key - ECC Key command - 0x80 0x10 0x40 0x00 0x22 0x81 0xA4 0x1A 0x10 0x00 0x00 0x02 0x03 0x1A 0x30 0x00 0x00 0x03 0x19 0x01 0x00 0x1A 0x50 0x00 0x00 0xC8 0x1A 0x00 0x01 0x00 0x01 0x1A 0x20 0x00 0x00 0x01 0x42 0x02 0x03 0x7F; - -// Generate Key - DES Key command - 0x80 0x10 0x40 0x00 0x22 0x81 0xA4 0x1A 0x10 0x00 0x00 0x02 0x18 0x21 0x1A 0x30 0x00 0x00 0x03 0x18 0xA8 0x1A 0x50 0x00 0x00 0xC8 0x1A 0x00 0x01 0x00 0x01 0x1A 0x20 0x00 0x00 0x01 0x42 0x02 0x03 0x7F; - -// Generate Key - HMAC Key command - 0x80 0x10 0x40 0x00 0x32 0x81 0xA6 0x1A 0x10 0x00 0x00 0x02 0x18 0x80 0x1A 0x30 0x00 0x01 0xF5 0x1A 0x01 0x02 0x03 0x04 0x1A 0x90 0x00 0x02 0x59 0x44 0x54 0x65 0x73 0x74 0x1A 0x30 0x00 0x00 0x08 0x18 0x80 0x1A 0x30 0x00 0x00 0x03 0x18 0x80 0x1A 0x20 0x00 0x00 0x05 0x41 0x04 0x7F; - -// Import RSA Key - 0x80 0x11 0x40 0x00 0xB4 0x83 0xA5 0x1A 0x10 0x00 0x00 0x02 0x01 0x1A 0x30 0x00 0x01 0xF5 0x1A 0x01 0x02 0x03 0x04 0x1A 0x90 0x00 0x02 0x59 0x44 0x54 0x65 0x73 0x74 0x1A 0x50 0x00 0x00 0xC8 0x1A 0x00 0x01 0x00 0x01 0x1A 0x70 0x00 0x01 0xF7 0x01 0x03 0x58 0x85 0x82 0x58 0x40 0x80 0x9A 0x87 0x4C 0xE1 0xA0 0x71 0x44 0xAE 0x45 0xDD 0x8D 0x1C 0x05 0xB4 0xD0 0x44 0x23 0xDD 0x42 0xA7 0xC9 0x53 0x44 0xAC 0x31 0x4A 0x22 0x4A 0x02 0x65 0xA0 0xAA 0x21 0xA8 0x30 0x94 0x7D 0x13 0xA1 0xBC 0x89 0x81 0xB5 0x54 0xDE 0x75 0x82 0xB9 0x0B 0x1A 0x7A 0x81 0x0C 0x51 0xE0 0x2F 0x91 0x97 0xD4 0xE8 0x33 0x27 0x61 0x58 0x40 0x92 0x6C 0x79 0x17 0xBB 0x36 0x6F 0xB7 0x58 0x25 0x84 0x98 0xA9 0x56 0x07 0xE6 0x07 0xF6 0x26 0x92 0x15 0xF6 0x21 0x9F 0x6C 0xF0 0xB4 0xE7 0x20 0x42 0xAC 0xB6 0xD8 0x30 0x61 0x06 0xC9 0x3B 0x30 0x67 0x1E 0x8D 0x74 0x11 0x8B 0x06 0x98 0xAB 0x8D 0x6A 0x6C 0xCD 0xB7 0x2F 0xC3 0xA8 0x30 0xC7 0x68 0x03 0x4F 0x72 0xC7 0x5B 0x7F; - -// Import EC Key - 0x80 0x11 0x40 0x00 0x7D 0x83 0xA4 0x1A 0x10 0x00 0x00 0x02 0x03 0x1A 0x30 0x00 0x01 0xF5 0x1A 0x01 0x02 0x03 0x04 0x1A 0x90 0x00 0x02 0x59 0x44 0x54 0x65 0x73 0x74 0x1A 0x50 0x00 0x00 0xC8 0x1A 0x00 0x01 0x00 0x01 0x03 0x58 0x54 0x83 0x58 0x18 0xA6 0x68 0xDE 0xEC 0x65 0x6C 0xFB 0xEE 0xAA 0x43 0xEF 0x97 0x9D 0x10 0x82 0xF0 0x99 0x5F 0x10 0xF3 0xEE 0x9C 0x38 0x57 0x58 0x31 0x04 0x3A 0xF8 0xF4 0xFA 0x1F 0xE4 0x4D 0x62 0xA1 0xCD 0x26 0x8E 0x1A 0x5A 0xAA 0xF5 0xA8 0x94 0xE3 0x8B 0x4C 0xCE 0x49 0xA1 0x57 0x25 0x81 0x6D 0xBE 0x5C 0x3B 0x07 0x95 0xB6 0x89 0x24 0x6E 0x9D 0x25 0x22 0xE6 0x5F 0x41 0xCC 0x59 0xCE 0x25 0x0C 0x1A 0x10 0x00 0x00 0x0A 0x01 0x7F; - -// Import AES Key - 0x80 0x11 0x40 0x00 0x3F 0x83 0xA5 0x1A 0x10 0x00 0x00 0x02 0x18 0x20 0x1A 0x30 0x00 0x01 0xF5 0x1A 0x01 0x02 0x03 0x04 0x1A 0x90 0x00 0x02 0x59 0x44 0x54 0x65 0x73 0x74 0x1A 0x30 0x00 0x00 0x03 0x18 0x80 0x1A 0x20 0x00 0x00 0x05 0x41 0x04 0x03 0x52 0x81 0x50 0x95 0xE6 0x79 0x36 0x64 0xA5 0xEC 0x72 0xBF 0x01 0x4C 0x83 0x6C 0xCD 0xCF 0x51 0x7F; - -// Import Hmac Key - 0x80 0x11 0x40 0x00 0x46 0x83 0xA6 0x1A 0x10 0x00 0x00 0x02 0x18 0x80 0x1A 0x30 0x00 0x01 0xF5 0x1A 0x01 0x02 0x03 0x04 0x1A 0x90 0x00 0x02 0x59 0x44 0x54 0x65 0x73 0x74 0x1A 0x30 0x00 0x00 0x03 0x18 0x80 0x1A 0x20 0x00 0x00 0x05 0x41 0x04 0x1A 0x30 0x00 0x00 0x08 0x18 0x80 0x03 0x52 0x81 0x50 0xFC 0xA6 0x8F 0x58 0x68 0x93 0xDE 0xD0 0xC0 0x74 0x1C 0x6F 0x1D 0x39 0x2E 0x4A 0x7F; - -// Import Des Key - 0x80 0x11 0x40 0x00 0x3F 0x83 0xA5 0x1A 0x10 0x00 0x00 0x02 0x18 0x21 0x1A 0x30 0x00 0x01 0xF5 0x1A 0x01 0x02 0x03 0x04 0x1A 0x90 0x00 0x02 0x59 0x44 0x54 0x65 0x73 0x74 0x1A 0x30 0x00 0x00 0x03 0x18 0xA8 0x1A 0x20 0x00 0x00 0x05 0x41 0x04 0x03 0x52 0x81 0x50 0x8B 0xD4 0xD5 0x84 0x37 0x39 0xC0 0x1B 0xDB 0xED 0x3C 0x68 0x99 0x3A 0xDC 0x3D 0x7F; - diff --git a/Applet/README.md b/Applet/README.md index 5cc80048..9d592fd2 100644 --- a/Applet/README.md +++ b/Applet/README.md @@ -1,6 +1,6 @@ -# JavaCardKeymaster Applet - -This directory contains the implementation of the Keymaster 4.1 -interface, in the form of a JavaCard 3.1 applet which runs in a secure -element. It must be deployed in conjuction with the associated HAL, -which serves to intermediate between Android Keystore and this applet. +# JavaCardKeymaster Applet + +This directory contains the implementation of the Keymaster 4.1 +interface, in the form of a JavaCard 3.1 applet which runs in a secure +element. It must be deployed in conjuction with the associated HAL, +which serves to intermediate between Android Keystore and this applet. diff --git a/Applet/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp b/Applet/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp deleted file mode 100644 index ed00a395..00000000 Binary files a/Applet/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp and /dev/null differ diff --git a/Applet/api_export_files_3.1.0/java/io/javacard/io.exp b/Applet/api_export_files_3.1.0/java/io/javacard/io.exp deleted file mode 100644 index 36b9d18b..00000000 Binary files a/Applet/api_export_files_3.1.0/java/io/javacard/io.exp and /dev/null differ diff --git a/Applet/api_export_files_3.1.0/java/lang/javacard/lang.exp b/Applet/api_export_files_3.1.0/java/lang/javacard/lang.exp deleted file mode 100644 index 272eebba..00000000 Binary files a/Applet/api_export_files_3.1.0/java/lang/javacard/lang.exp and /dev/null differ diff --git a/Applet/api_export_files_3.1.0/java/rmi/javacard/rmi.exp b/Applet/api_export_files_3.1.0/java/rmi/javacard/rmi.exp deleted file mode 100644 index 8c695237..00000000 Binary files a/Applet/api_export_files_3.1.0/java/rmi/javacard/rmi.exp and /dev/null differ diff --git a/Applet/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp b/Applet/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp deleted file mode 100644 index ce4ac0c9..00000000 Binary files a/Applet/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp and /dev/null differ diff --git a/Applet/build.xml b/Applet/build.xml index 41181873..c08e095f 100644 --- a/Applet/build.xml +++ b/Applet/build.xml @@ -1,188 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - + + + - - + + + + \ No newline at end of file diff --git a/Applet/default.output b/Applet/default.output deleted file mode 100644 index 6e4f103f..00000000 --- a/Applet/default.output +++ /dev/null @@ -1,20 +0,0 @@ -CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 09, a0, 00, 00, 00, 62, 03, 01, 08, 01, Le: 00, SW1: 90, SW2: 00 -CAP file download section. Output suppressed. -OUTPUT OFF; -OUTPUT ON; -CLA: 80, INS: b8, P1: 00, P2: 00, Lc: 0c, 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, 00, Le: 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, SW1: 90, SW2: 00 -CLA: 00, INS: a4, P1: 04, P2: 00, Lc: 0a, a0, 00, 00, 00, 62, 03, 01, 0c, 01, 01, Le: 00, SW1: 90, SW2: 00 -CLA: 80, INS: 23, P1: 40, P2: 00, Lc: 3b, 83, a1, 1a, 10, 00, 00, 02, 01, 00, 58, 30, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2a, 2b, 2c, 2d, 2e, 2f, Le: 00, SW1: 69, SW2: 85 -CLA: 80, INS: 24, P1: 40, P2: 00, Lc: 49, 86, 01, 01, 58, 20, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 30, 30, 58, 20, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 30, 30, 02, 00, Le: 00, SW1: 90, SW2: 00 -CLA: 80, INS: 1e, P1: 40, P2: 00, Lc: 00, Le: 00, SW1: 69, SW2: 86 -CLA: 80, INS: 18, P1: 40, P2: 00, Lc: 23, 81, 58, 20, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f, Le: 00, SW1: 69, SW2: 86 -CLA: 80, INS: 10, P1: 40, P2: 00, Lc: 22, 81, a4, 1a, 10, 00, 00, 02, 01, 1a, 30, 00, 00, 03, 19, 08, 00, 1a, 50, 00, 00, c8, 1a, 00, 01, 00, 01, 1a, 20, 00, 00, 01, 42, 02, 03, Le: 00, SW1: 69, SW2: 86 -CLA: 80, INS: 10, P1: 40, P2: 00, Lc: 23, 81, a4, 1a, 10, 00, 00, 02, 18, 20, 1a, 30, 00, 00, 03, 19, 01, 00, 1a, 50, 00, 00, c8, 1a, 00, 01, 00, 01, 1a, 20, 00, 00, 01, 42, 02, 03, Le: 00, SW1: 69, SW2: 86 -CLA: 80, INS: 10, P1: 40, P2: 00, Lc: 22, 81, a4, 1a, 10, 00, 00, 02, 03, 1a, 30, 00, 00, 03, 19, 01, 00, 1a, 50, 00, 00, c8, 1a, 00, 01, 00, 01, 1a, 20, 00, 00, 01, 42, 02, 03, Le: 00, SW1: 69, SW2: 86 -CLA: 80, INS: 10, P1: 40, P2: 00, Lc: 22, 81, a4, 1a, 10, 00, 00, 02, 18, 21, 1a, 30, 00, 00, 03, 18, a8, 1a, 50, 00, 00, c8, 1a, 00, 01, 00, 01, 1a, 20, 00, 00, 01, 42, 02, 03, Le: 00, SW1: 69, SW2: 86 -CLA: 80, INS: 10, P1: 40, P2: 00, Lc: 32, 81, a6, 1a, 10, 00, 00, 02, 18, 80, 1a, 30, 00, 01, f5, 1a, 01, 02, 03, 04, 1a, 90, 00, 02, 59, 44, 54, 65, 73, 74, 1a, 30, 00, 00, 08, 18, 80, 1a, 30, 00, 00, 03, 18, 80, 1a, 20, 00, 00, 05, 41, 04, Le: 00, SW1: 69, SW2: 85 -CLA: 80, INS: 11, P1: 40, P2: 00, Lc: b4, 83, a5, 1a, 10, 00, 00, 02, 01, 1a, 30, 00, 01, f5, 1a, 01, 02, 03, 04, 1a, 90, 00, 02, 59, 44, 54, 65, 73, 74, 1a, 50, 00, 00, c8, 1a, 00, 01, 00, 01, 1a, 70, 00, 01, f7, 01, 03, 58, 85, 82, 58, 40, 80, 9a, 87, 4c, e1, a0, 71, 44, ae, 45, dd, 8d, 1c, 05, b4, d0, 44, 23, dd, 42, a7, c9, 53, 44, ac, 31, 4a, 22, 4a, 02, 65, a0, aa, 21, a8, 30, 94, 7d, 13, a1, bc, 89, 81, b5, 54, de, 75, 82, b9, 0b, 1a, 7a, 81, 0c, 51, e0, 2f, 91, 97, d4, e8, 33, 27, 61, 58, 40, 92, 6c, 79, 17, bb, 36, 6f, b7, 58, 25, 84, 98, a9, 56, 07, e6, 07, f6, 26, 92, 15, f6, 21, 9f, 6c, f0, b4, e7, 20, 42, ac, b6, d8, 30, 61, 06, c9, 3b, 30, 67, 1e, 8d, 74, 11, 8b, 06, 98, ab, 8d, 6a, 6c, cd, b7, 2f, c3, a8, 30, c7, 68, 03, 4f, 72, c7, 5b, Le: 00, SW1: 69, SW2: 85 -CLA: 80, INS: 11, P1: 40, P2: 00, Lc: 7d, 83, a4, 1a, 10, 00, 00, 02, 03, 1a, 30, 00, 01, f5, 1a, 01, 02, 03, 04, 1a, 90, 00, 02, 59, 44, 54, 65, 73, 74, 1a, 50, 00, 00, c8, 1a, 00, 01, 00, 01, 03, 58, 54, 83, 58, 18, a6, 68, de, ec, 65, 6c, fb, ee, aa, 43, ef, 97, 9d, 10, 82, f0, 99, 5f, 10, f3, ee, 9c, 38, 57, 58, 31, 04, 3a, f8, f4, fa, 1f, e4, 4d, 62, a1, cd, 26, 8e, 1a, 5a, aa, f5, a8, 94, e3, 8b, 4c, ce, 49, a1, 57, 25, 81, 6d, be, 5c, 3b, 07, 95, b6, 89, 24, 6e, 9d, 25, 22, e6, 5f, 41, cc, 59, ce, 25, 0c, 1a, 10, 00, 00, 0a, 01, Le: 00, SW1: 69, SW2: 85 -CLA: 80, INS: 11, P1: 40, P2: 00, Lc: 3f, 83, a5, 1a, 10, 00, 00, 02, 18, 20, 1a, 30, 00, 01, f5, 1a, 01, 02, 03, 04, 1a, 90, 00, 02, 59, 44, 54, 65, 73, 74, 1a, 30, 00, 00, 03, 18, 80, 1a, 20, 00, 00, 05, 41, 04, 03, 52, 81, 50, 95, e6, 79, 36, 64, a5, ec, 72, bf, 01, 4c, 83, 6c, cd, cf, 51, Le: 00, SW1: 69, SW2: 85 -CLA: 80, INS: 11, P1: 40, P2: 00, Lc: 46, 83, a6, 1a, 10, 00, 00, 02, 18, 80, 1a, 30, 00, 01, f5, 1a, 01, 02, 03, 04, 1a, 90, 00, 02, 59, 44, 54, 65, 73, 74, 1a, 30, 00, 00, 03, 18, 80, 1a, 20, 00, 00, 05, 41, 04, 1a, 30, 00, 00, 08, 18, 80, 03, 52, 81, 50, fc, a6, 8f, 58, 68, 93, de, d0, c0, 74, 1c, 6f, 1d, 39, 2e, 4a, Le: 00, SW1: 69, SW2: 85 -CLA: 80, INS: 11, P1: 40, P2: 00, Lc: 3f, 83, a5, 1a, 10, 00, 00, 02, 18, 21, 1a, 30, 00, 01, f5, 1a, 01, 02, 03, 04, 1a, 90, 00, 02, 59, 44, 54, 65, 73, 74, 1a, 30, 00, 00, 03, 18, a8, 1a, 20, 00, 00, 05, 41, 04, 03, 52, 81, 50, 8b, d4, d5, 84, 37, 39, c0, 1b, db, ed, 3c, 68, 99, 3a, dc, 3d, Le: 00, SW1: 69, SW2: 85 diff --git a/Applet/powerdown.scr b/Applet/powerdown.scr deleted file mode 100644 index 7dca615e..00000000 --- a/Applet/powerdown.scr +++ /dev/null @@ -1,4 +0,0 @@ - -// output on; - -powerdown; \ No newline at end of file diff --git a/Applet/powerup.scr b/Applet/powerup.scr deleted file mode 100644 index 79990dc4..00000000 --- a/Applet/powerup.scr +++ /dev/null @@ -1,9 +0,0 @@ -powerup; - -// Select the installer applet -0x00 0xA4 0x04 0x00 0x09 0xA0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F; - -// Turn output off during CAP file download -echo "CAP file download section. Output suppressed."; - -output off; diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMArray.java b/Applet/src/com/android/javacard/keymaster/KMArray.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMArray.java rename to Applet/src/com/android/javacard/keymaster/KMArray.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java rename to Applet/src/com/android/javacard/keymaster/KMAttestationCert.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java b/Applet/src/com/android/javacard/keymaster/KMBoolTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMBoolTag.java rename to Applet/src/com/android/javacard/keymaster/KMBoolTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java b/Applet/src/com/android/javacard/keymaster/KMByteBlob.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMByteBlob.java rename to Applet/src/com/android/javacard/keymaster/KMByteBlob.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/Applet/src/com/android/javacard/keymaster/KMByteTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMByteTag.java rename to Applet/src/com/android/javacard/keymaster/KMByteTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMDecoder.java b/Applet/src/com/android/javacard/keymaster/KMDecoder.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMDecoder.java rename to Applet/src/com/android/javacard/keymaster/KMDecoder.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEncoder.java b/Applet/src/com/android/javacard/keymaster/KMEncoder.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMEncoder.java rename to Applet/src/com/android/javacard/keymaster/KMEncoder.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEnum.java b/Applet/src/com/android/javacard/keymaster/KMEnum.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMEnum.java rename to Applet/src/com/android/javacard/keymaster/KMEnum.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java rename to Applet/src/com/android/javacard/keymaster/KMEnumArrayTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMEnumTag.java b/Applet/src/com/android/javacard/keymaster/KMEnumTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMEnumTag.java rename to Applet/src/com/android/javacard/keymaster/KMEnumTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMError.java b/Applet/src/com/android/javacard/keymaster/KMError.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMError.java rename to Applet/src/com/android/javacard/keymaster/KMError.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMException.java b/Applet/src/com/android/javacard/keymaster/KMException.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMException.java rename to Applet/src/com/android/javacard/keymaster/KMException.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java b/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java rename to Applet/src/com/android/javacard/keymaster/KMHardwareAuthToken.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java b/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java rename to Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMInteger.java b/Applet/src/com/android/javacard/keymaster/KMInteger.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMInteger.java rename to Applet/src/com/android/javacard/keymaster/KMInteger.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java rename to Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java b/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMIntegerTag.java rename to Applet/src/com/android/javacard/keymaster/KMIntegerTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java b/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java rename to Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java rename to Applet/src/com/android/javacard/keymaster/KMKeyParameters.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java similarity index 99% rename from Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java rename to Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index cde5de0a..76c97b0e 100644 --- a/Applet/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -32,7 +32,7 @@ * objects. It also implements the keymaster state machine and handles javacard applet life cycle * events. */ -public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLength, OnUpgradeListener { +public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLength { // Constants. public static final byte AES_BLOCK_SIZE = 16; public static final byte DES_BLOCK_SIZE = 8; @@ -150,10 +150,10 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe public static final byte OUTPUT_DATA = 25; public static final byte HW_TOKEN = 26; public static final byte VERIFICATION_TOKEN = 27; - private static final byte SIGNATURE = 28; + protected static final byte SIGNATURE = 28; // AddRngEntropy - private static final short MAX_SEED_SIZE = 2048; + protected static final short MAX_SEED_SIZE = 2048; // Keyblob constants public static final byte KEY_BLOB_SECRET = 0; public static final byte KEY_BLOB_NONCE = 1; @@ -167,23 +167,23 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private static final short HMAC_SHARED_PARAM_MAX_SIZE = 64; // Keymaster Applet attributes - private static byte keymasterState = ILLEGAL_STATE; - private static KMEncoder encoder; - private static KMDecoder decoder; - private static KMRepository repository; - private static KMSEProvider seProvider; - private static byte[] buffer; - private static short bufferLength; - private static short bufferStartOffset; - private static short[] tmpVariables; - private static short[] data; - private byte provisionStatus = NOT_PROVISIONED; - private static final short MAX_CERT_SIZE = 2048; + protected static byte keymasterState = ILLEGAL_STATE; + protected static KMEncoder encoder; + protected static KMDecoder decoder; + protected static KMRepository repository; + protected static KMSEProvider seProvider; + protected static byte[] buffer; + protected static short bufferLength; + protected static short bufferStartOffset; + protected static short[] tmpVariables; + protected static short[] data; + protected byte provisionStatus = NOT_PROVISIONED; + protected static final short MAX_CERT_SIZE = 2048; /** Registers this applet. */ - protected KMKeymasterApplet() { + protected KMKeymasterApplet(KMSEProvider seImpl) { boolean isUpgrading = UpgradeManager.isUpgrading(); - seProvider = KMSEProviderImpl.instance(isUpgrading); + seProvider = seImpl; repository = new KMRepository(isUpgrading); byte[] buf = JCSystem.makeTransientByteArray((short) 32, JCSystem.CLEAR_ON_DESELECT); data = JCSystem.makeTransientShortArray((short) DATA_ARRAY_SIZE, JCSystem.CLEAR_ON_RESET); @@ -199,18 +199,6 @@ protected KMKeymasterApplet() { decoder = new KMDecoder(); } - /** - * Installs this applet. - * - * @param bArray the array containing installation parameters - * @param bOffset the starting offset in bArray - * @param bLength the length in bytes of the parameter data in bArray - */ - public static void install(byte[] bArray, short bOffset, byte bLength) { - new KMKeymasterApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]); - //new KMKeymasterApplet().register(); - } - /** * Selects this applet. * @@ -4068,7 +4056,7 @@ private void add(byte[] buf, short op1, short op2, short result) { index--; } } - +/* @Override public void onCleanup() { } @@ -4107,13 +4095,5 @@ public Element onSave() { seProvider.onSave(element); return element; } - - private short computePrimitveDataSize() { - // provisionStatus + keymasterState - return (short) 2; - } - - private short computeObjectCount() { - return (short) 0; - } +*/ } diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMOperation.java b/Applet/src/com/android/javacard/keymaster/KMOperation.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMOperation.java rename to Applet/src/com/android/javacard/keymaster/KMOperation.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/Applet/src/com/android/javacard/keymaster/KMOperationState.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMOperationState.java rename to Applet/src/com/android/javacard/keymaster/KMOperationState.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMRepository.java rename to Applet/src/com/android/javacard/keymaster/KMRepository.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMSEProvider.java b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMSEProvider.java rename to Applet/src/com/android/javacard/keymaster/KMSEProvider.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMTag.java b/Applet/src/com/android/javacard/keymaster/KMTag.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMTag.java rename to Applet/src/com/android/javacard/keymaster/KMTag.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMType.java b/Applet/src/com/android/javacard/keymaster/KMType.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMType.java rename to Applet/src/com/android/javacard/keymaster/KMType.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMUpgradable.java b/Applet/src/com/android/javacard/keymaster/KMUpgradable.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMUpgradable.java rename to Applet/src/com/android/javacard/keymaster/KMUpgradable.java diff --git a/Applet/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java b/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java similarity index 100% rename from Applet/Applet/src/com/android/javacard/keymaster/KMVerificationToken.java rename to Applet/src/com/android/javacard/keymaster/KMVerificationToken.java