├── .gitignore ├── Applet ├── AndroidSEProvider │ ├── AndroidSE_3_0_5.opt │ ├── AndroidSE_3_1_0.opt │ ├── api_export_files_3.0.5 │ │ ├── java │ │ │ ├── io │ │ │ │ └── javacard │ │ │ │ │ └── io.exp │ │ │ ├── lang │ │ │ │ └── javacard │ │ │ │ │ └── lang.exp │ │ │ └── rmi │ │ │ │ └── javacard │ │ │ │ └── rmi.exp │ │ ├── javacard │ │ │ ├── framework │ │ │ │ ├── javacard │ │ │ │ │ └── framework.exp │ │ │ │ └── service │ │ │ │ │ └── javacard │ │ │ │ │ └── service.exp │ │ │ └── security │ │ │ │ └── javacard │ │ │ │ └── security.exp │ │ ├── javacardx │ │ │ ├── apdu │ │ │ │ ├── javacard │ │ │ │ │ └── apdu.exp │ │ │ │ └── util │ │ │ │ │ └── javacard │ │ │ │ │ └── util.exp │ │ │ ├── biometry │ │ │ │ └── javacard │ │ │ │ │ └── biometry.exp │ │ │ ├── biometry1toN │ │ │ │ └── javacard │ │ │ │ │ └── biometry1toN.exp │ │ │ ├── crypto │ │ │ │ └── javacard │ │ │ │ │ └── crypto.exp │ │ │ ├── external │ │ │ │ └── javacard │ │ │ │ │ └── external.exp │ │ │ ├── framework │ │ │ │ ├── math │ │ │ │ │ └── javacard │ │ │ │ │ │ └── math.exp │ │ │ │ ├── string │ │ │ │ │ └── javacard │ │ │ │ │ │ └── string.exp │ │ │ │ ├── tlv │ │ │ │ │ └── javacard │ │ │ │ │ │ └── tlv.exp │ │ │ │ └── util │ │ │ │ │ ├── intx │ │ │ │ │ └── javacard │ │ │ │ │ │ └── intx.exp │ │ │ │ │ └── javacard │ │ │ │ │ └── util.exp │ │ │ └── security │ │ │ │ └── javacard │ │ │ │ └── security.exp │ │ └── org │ │ │ └── globalplatform │ │ │ └── upgrade │ │ │ └── javacard │ │ │ ├── upgrade.exp │ │ │ └── upgrade.jca │ ├── api_export_files_3.1.0 │ │ ├── java │ │ │ ├── io │ │ │ │ └── javacard │ │ │ │ │ └── io.exp │ │ │ ├── lang │ │ │ │ └── javacard │ │ │ │ │ └── lang.exp │ │ │ └── rmi │ │ │ │ └── javacard │ │ │ │ └── rmi.exp │ │ ├── javacard │ │ │ ├── framework │ │ │ │ ├── javacard │ │ │ │ │ └── framework.exp │ │ │ │ └── service │ │ │ │ │ └── javacard │ │ │ │ │ └── service.exp │ │ │ └── security │ │ │ │ └── javacard │ │ │ │ └── security.exp │ │ └── javacardx │ │ │ ├── apdu │ │ │ ├── javacard │ │ │ │ └── apdu.exp │ │ │ └── util │ │ │ │ └── javacard │ │ │ │ └── util.exp │ │ │ ├── biometry │ │ │ └── javacard │ │ │ │ └── biometry.exp │ │ │ ├── biometry1toN │ │ │ └── javacard │ │ │ │ └── biometry1toN.exp │ │ │ ├── crypto │ │ │ └── javacard │ │ │ │ └── crypto.exp │ │ │ ├── external │ │ │ └── javacard │ │ │ │ └── external.exp │ │ │ ├── framework │ │ │ ├── event │ │ │ │ └── javacard │ │ │ │ │ └── event.exp │ │ │ ├── math │ │ │ │ └── javacard │ │ │ │ │ └── math.exp │ │ │ ├── nio │ │ │ │ └── javacard │ │ │ │ │ └── nio.exp │ │ │ ├── string │ │ │ │ └── javacard │ │ │ │ │ └── string.exp │ │ │ ├── time │ │ │ │ └── javacard │ │ │ │ │ └── time.exp │ │ │ ├── tlv │ │ │ │ └── javacard │ │ │ │ │ └── tlv.exp │ │ │ └── util │ │ │ │ ├── intx │ │ │ │ └── javacard │ │ │ │ │ └── intx.exp │ │ │ │ └── javacard │ │ │ │ └── util.exp │ │ │ └── security │ │ │ ├── cert │ │ │ └── javacard │ │ │ │ └── cert.exp │ │ │ ├── derivation │ │ │ └── javacard │ │ │ │ └── derivation.exp │ │ │ ├── javacard │ │ │ └── security.exp │ │ │ └── util │ │ │ └── javacard │ │ │ └── util.exp │ ├── build.xml │ └── src │ │ └── com │ │ └── android │ │ └── javacard │ │ └── keymaster │ │ ├── KMAESKey.java │ │ ├── KMAndroidSEApplet.java │ │ ├── KMAndroidSEProvider.java │ │ ├── KMAttestationCertImpl.java │ │ ├── KMConfigurations.java │ │ ├── KMECPrivateKey.java │ │ ├── KMEcdsa256NoDigestSignature.java │ │ ├── KMHmacKey.java │ │ ├── KMKeyObject.java │ │ ├── KMOperationImpl.java │ │ ├── KMPKCS8DecoderImpl.java │ │ ├── KMRsa2048NoDigestSignature.java │ │ ├── KMRsaOAEPEncoding.java │ │ └── KMUtils.java ├── JCardSimProvider │ ├── build.xml │ ├── lib │ │ ├── hamcrest-core-1.3.jar │ │ ├── jcardsim-3.0.5-SNAPSHOT.jar │ │ └── junit-4.13.jar │ ├── src │ │ └── com │ │ │ └── android │ │ │ └── javacard │ │ │ └── keymaster │ │ │ ├── KMAESKey.java │ │ │ ├── KMAttestationCertImpl.java │ │ │ ├── KMCipher.java │ │ │ ├── KMCipherImpl.java │ │ │ ├── KMConfigurations.java │ │ │ ├── KMECPrivateKey.java │ │ │ ├── KMEcdsa256NoDigestSignature.java │ │ │ ├── KMHmacKey.java │ │ │ ├── KMJCardSimApplet.java │ │ │ ├── KMJCardSimulator.java │ │ │ ├── KMOperationImpl.java │ │ │ ├── KMPKCS8DecoderImpl.java │ │ │ ├── KMRsa2048NoDigestSignature.java │ │ │ └── KMUtils.java │ └── test │ │ └── com │ │ └── android │ │ └── javacard │ │ └── test │ │ └── KMFunctionalTest.java ├── README.md ├── build.xml └── src │ └── com │ └── android │ └── javacard │ └── keymaster │ ├── KMAppletState.java │ ├── KMArray.java │ ├── KMAttestationCert.java │ ├── KMAttestationKey.java │ ├── KMBoolTag.java │ ├── KMByteBlob.java │ ├── KMByteTag.java │ ├── KMComputedHmacKey.java │ ├── KMDecoder.java │ ├── KMEncoder.java │ ├── KMEnum.java │ ├── KMEnumArrayTag.java │ ├── KMEnumTag.java │ ├── KMError.java │ ├── KMException.java │ ├── KMHardwareAuthToken.java │ ├── KMHmacSharingParameters.java │ ├── KMInteger.java │ ├── KMIntegerArrayTag.java │ ├── KMIntegerTag.java │ ├── KMKeyCharacteristics.java │ ├── KMKeyParameters.java │ ├── KMKeymasterApplet.java │ ├── KMMasterKey.java │ ├── KMOperation.java │ ├── KMOperationState.java │ ├── KMPKCS8Decoder.java │ ├── KMPreSharedKey.java │ ├── KMRepository.java │ ├── KMSEProvider.java │ ├── KMTag.java │ ├── KMType.java │ ├── KMUpgradable.java │ └── KMVerificationToken.java ├── HAL ├── README.md └── keymaster │ ├── 4.1 │ ├── CborConverter.cpp │ ├── CommonUtils.cpp │ ├── JavacardKeymaster4Device.cpp │ ├── JavacardOperationContext.cpp │ ├── JavacardSoftKeymasterContext.cpp │ ├── OmapiTransport.cpp │ ├── SocketTransport.cpp │ ├── android.hardware.keymaster@4.1-strongbox.service.rc │ ├── android.hardware.keymaster@4.1-strongbox.service.xml │ ├── android.hardware.strongbox_keystore.xml │ └── service.cpp │ ├── Android.bp │ └── include │ ├── CborConverter.h │ ├── CommonUtils.h │ ├── JavacardKeymaster4Device.h │ ├── JavacardOperationContext.h │ ├── JavacardSoftKeymasterContext.h │ ├── Transport.h │ └── TransportFactory.h ├── LICENSE ├── ProvisioningTool ├── Makefile ├── README.md ├── include │ ├── UniquePtr.h │ ├── constants.h │ ├── cppbor │ │ ├── cppbor.h │ │ └── cppbor_parse.h │ ├── json │ │ ├── assertions.h │ │ ├── autolink.h │ │ ├── config.h │ │ ├── features.h │ │ ├── forwards.h │ │ ├── json.h │ │ ├── reader.h │ │ ├── value.h │ │ ├── version.h │ │ └── writer.h │ ├── socket.h │ └── utils.h ├── lib │ ├── README.md │ ├── libjsoncpp.a │ ├── libjsoncpp.so │ ├── libjsoncpp.so.0 │ └── libjsoncpp.so.0.10.7 ├── sample_json_cf.txt ├── sample_json_gf.txt ├── src │ ├── construct_apdus.cpp │ ├── cppbor.cpp │ ├── cppbor_parse.cpp │ ├── provision.cpp │ ├── socket.cpp │ └── utils.cpp └── test_resources │ ├── batch_cert.der │ ├── batch_key.der │ ├── ca_cert.der │ ├── ca_key.der │ ├── intermediate_cert.der │ ├── intermediate_key.der │ └── oem_root_key.der ├── README.md ├── TestingTools ├── JCProxy │ ├── .project │ ├── lib │ │ ├── apduio-RELEASE71.jar │ │ └── jcardsim-3.0.5-SNAPSHOT.jar │ └── src │ │ └── com │ │ └── android │ │ └── javacard │ │ └── jcproxy │ │ ├── JCProxyMain.java │ │ ├── JCardSimulator.java │ │ ├── Simulator.java │ │ └── Utils.java └── README.md ├── aosp_integration_patches ├── cts_tests_tests_keystore.patch ├── device_google_cuttlefish.patch ├── hardware_interfaces_keymaster.patch ├── omapi_patches │ ├── JavacardKeymaster.patch │ └── packages_apps_secureElement.patch └── system_sepolicy.patch └── aosp_integration_patches_aosp_12_r15 ├── JavacardKeymaster_remove_omapi.patch ├── device_google_cuttlefish.patch ├── hardware_interfaces_keymaster.patch ├── system_security_keystore2.patch └── system_sepolicy.patch /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/AndroidSE_3_0_5.opt: -------------------------------------------------------------------------------- 1 | -out EXP JCA CAP 2 | -exportpath ../../AndroidSEProvider/api_export_files_3.0.5 3 | -applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 com.android.javacard.keymaster.KMAndroidSEApplet 4 | com.android.javacard.keymaster 5 | 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1 1.0 6 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/AndroidSE_3_1_0.opt: -------------------------------------------------------------------------------- 1 | -out EXP JCA CAP 2 | -exportpath ../../AndroidSEProvider/api_export_files_3.1.0 3 | -applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 com.android.javacard.keymaster.KMAndroidSEApplet 4 | com.android.javacard.keymaster 5 | 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1 1.0 6 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/java/io/javacard/io.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/java/io/javacard/io.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/java/lang/javacard/lang.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/java/lang/javacard/lang.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/java/rmi/javacard/rmi.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/java/rmi/javacard/rmi.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/javacard/framework.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/javacard/framework.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/framework/service/javacard/service.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/security/javacard/security.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacard/security/javacard/security.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/javacard/apdu.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/apdu/util/javacard/util.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry/javacard/biometry.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/biometry1toN/javacard/biometry1toN.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/crypto/javacard/crypto.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/external/javacard/external.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/external/javacard/external.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/math/javacard/math.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/string/javacard/string.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/tlv/javacard/tlv.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/intx/javacard/intx.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/framework/util/javacard/util.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/security/javacard/security.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/javacardx/security/javacard/security.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.0.5/org/globalplatform/upgrade/javacard/upgrade.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/java/io/javacard/io.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/java/io/javacard/io.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/java/lang/javacard/lang.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/java/lang/javacard/lang.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/java/rmi/javacard/rmi.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/java/rmi/javacard/rmi.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/javacard/framework.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/javacard/framework.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/service/javacard/service.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/framework/service/javacard/service.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/security/javacard/security.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacard/security/javacard/security.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/javacard/apdu.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/apdu/util/javacard/util.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry/javacard/biometry.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry/javacard/biometry.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry1toN/javacard/biometry1toN.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/biometry1toN/javacard/biometry1toN.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/crypto/javacard/crypto.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/crypto/javacard/crypto.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/external/javacard/external.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/external/javacard/external.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/event/javacard/event.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/event/javacard/event.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/math/javacard/math.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/nio/javacard/nio.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/nio/javacard/nio.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/string/javacard/string.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/string/javacard/string.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/time/javacard/time.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/time/javacard/time.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/tlv/javacard/tlv.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/tlv/javacard/tlv.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/intx/javacard/intx.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/intx/javacard/intx.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/framework/util/javacard/util.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/cert/javacard/cert.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/cert/javacard/cert.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/derivation/javacard/derivation.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/derivation/javacard/derivation.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/javacard/security.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/javacard/security.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/AndroidSEProvider/api_export_files_3.1.0/javacardx/security/util/javacard/util.exp -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 22 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 73 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAESKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import org.globalplatform.upgrade.Element; 19 | 20 | import javacard.security.AESKey; 21 | 22 | public class KMAESKey implements KMMasterKey { 23 | 24 | public AESKey aesKey; 25 | 26 | public KMAESKey(AESKey key) { 27 | aesKey = key; 28 | } 29 | 30 | public static void onSave(Element element, KMAESKey kmKey) { 31 | element.write(kmKey.aesKey); 32 | } 33 | 34 | public static KMAESKey onRestore(Element element) { 35 | AESKey aesKey = (AESKey) element.readObject(); 36 | KMAESKey kmKey = new KMAESKey(aesKey); 37 | return kmKey; 38 | } 39 | 40 | public static short getBackupPrimitiveByteCount() { 41 | return (short) 0; 42 | } 43 | 44 | public static short getBackupObjectCount() { 45 | return (short) 1; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEApplet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import org.globalplatform.upgrade.Element; 19 | import org.globalplatform.upgrade.OnUpgradeListener; 20 | import org.globalplatform.upgrade.UpgradeManager; 21 | 22 | import javacard.framework.ISO7816; 23 | import javacard.framework.ISOException; 24 | 25 | public class KMAndroidSEApplet extends KMKeymasterApplet implements OnUpgradeListener { 26 | // provisionStatus - 1 byte 27 | // keymasterState - 1 byte 28 | // MagicNumber - 1 byte 29 | // Applet package version - 2 bytes. 30 | private static final byte PRIMITIVE_DATA_STORAGE_SIZE = 0x05; 31 | 32 | KMAndroidSEApplet() { 33 | super(new KMAndroidSEProvider()); 34 | } 35 | 36 | /** 37 | * Installs this applet. 38 | * 39 | * @param bArray the array containing installation parameters 40 | * @param bOffset the starting offset in bArray 41 | * @param bLength the length in bytes of the parameter data in bArray 42 | */ 43 | public static void install(byte[] bArray, short bOffset, byte bLength) { 44 | new KMAndroidSEApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]); 45 | } 46 | 47 | @Override 48 | public void onCleanup() { 49 | } 50 | 51 | @Override 52 | public void onConsolidate() { 53 | } 54 | 55 | @Override 56 | public void onRestore(Element element) { 57 | element.initRead(); 58 | byte firstByte = element.readByte(); 59 | short oldPackageVersion = 0; 60 | if (firstByte == KMKeymasterApplet.KM_MAGIC_NUMBER) { 61 | oldPackageVersion = element.readShort(); 62 | provisionStatus = element.readByte(); 63 | } else { 64 | // MAGIC_NUMBER is introduced in version 2.0. Upgrade is 65 | // not allowed for Applets having version less than 2.0 66 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 67 | } 68 | if (!isUpgradeAllowed(oldPackageVersion)) { 69 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 70 | } 71 | keymasterState = element.readByte(); 72 | repository.onRestore(element, oldPackageVersion, KM_APPLET_PACKAGE_VERSION); 73 | seProvider.onRestore(element, oldPackageVersion, KM_APPLET_PACKAGE_VERSION); 74 | handleDataUpgrade(oldPackageVersion); 75 | } 76 | 77 | @Override 78 | public Element onSave() { 79 | // SEProvider count 80 | short primitiveCount = seProvider.getBackupPrimitiveByteCount(); 81 | short objectCount = seProvider.getBackupObjectCount(); 82 | //Repository count 83 | primitiveCount += repository.getBackupPrimitiveByteCount(); 84 | objectCount += repository.getBackupObjectCount(); 85 | //KMKeymasterApplet count 86 | primitiveCount += PRIMITIVE_DATA_STORAGE_SIZE; 87 | // No objects to be stored in KMAndroidSEApplet. 88 | 89 | // Create element. 90 | Element element = UpgradeManager.createElement(Element.TYPE_SIMPLE, 91 | primitiveCount, objectCount); 92 | element.write(KM_MAGIC_NUMBER); 93 | element.write(packageVersion); 94 | element.write(provisionStatus); 95 | element.write(keymasterState); 96 | repository.onSave(element); 97 | seProvider.onSave(element); 98 | return element; 99 | } 100 | 101 | public boolean isUpgradeAllowed(short oldVersion) { 102 | // Downgrade of the Applet is not allowed. 103 | if (oldVersion > KM_APPLET_PACKAGE_VERSION) { 104 | return false; 105 | } 106 | return true; 107 | } 108 | 109 | public void handleDataUpgrade(short oldVersion) { 110 | switch (oldVersion) { 111 | case KM_APPLET_PACKAGE_VERSION_2_0: 112 | // In version 3.0, two new provisionStatus states are introduced 113 | // 1. PROVISION_STATUS_SE_LOCKED - bit 6 of provisionStatus 114 | // 2. PROVISION_STATUS_OEM_PUBLIC_KEY - bit 7 of provisionStatus 115 | // In the process of upgrade from 2.0 to 3.0 OEM PUBLIC Key is provisioned 116 | // in SEProvider.so update the state of the provision status by making 117 | // 7th bit HIGH. 118 | provisionStatus |= PROVISION_STATUS_OEM_ROOT_PUBLIC_KEY; 119 | // Check if the provisioning is already locked. If so update 120 | // the state of the provisionStatus by making 6th bit HIGH. 121 | // Lock the SE Factory provisioning as well. 122 | if (0 != (provisionStatus & PROVISION_STATUS_OEM_PROVISIONING_LOCKED)) { 123 | provisionStatus |= PROVISION_STATUS_SE_FACTORY_PROVISIONING_LOCKED; 124 | } 125 | break; 126 | default: 127 | break; 128 | } 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMConfigurations.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | public class KMConfigurations { 19 | // Machine types 20 | public static final byte LITTLE_ENDIAN = 0x00; 21 | public static final byte BIG_ENDIAN = 0x01; 22 | public static final byte TEE_MACHINE_TYPE = LITTLE_ENDIAN; 23 | 24 | // Maximum cert chain size 25 | public static final short CERT_CHAIN_MAX_SIZE = 2500; 26 | public static final short CERT_ISSUER_MAX_SIZE = 250; 27 | public static final short CERT_EXPIRY_MAX_SIZE = 20; 28 | public static final short TOTAL_ATTEST_IDS_SIZE = 300; 29 | } 30 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import org.globalplatform.upgrade.Element; 19 | 20 | import javacard.security.ECPrivateKey; 21 | import javacard.security.KeyPair; 22 | 23 | public class KMECPrivateKey implements KMAttestationKey { 24 | 25 | public KeyPair ecKeyPair; 26 | 27 | public KMECPrivateKey(KeyPair ecPair) { 28 | ecKeyPair = ecPair; 29 | } 30 | 31 | public ECPrivateKey getPrivateKey() { 32 | return (ECPrivateKey) ecKeyPair.getPrivate(); 33 | } 34 | 35 | public static void onSave(Element element, KMECPrivateKey kmKey) { 36 | element.write(kmKey.ecKeyPair); 37 | } 38 | 39 | public static KMECPrivateKey onRestore(Element element) { 40 | KeyPair ecKey = (KeyPair) element.readObject(); 41 | KMECPrivateKey kmKey = new KMECPrivateKey(ecKey); 42 | return kmKey; 43 | } 44 | 45 | public static short getBackupPrimitiveByteCount() { 46 | return (short) 0; 47 | } 48 | 49 | public static short getBackupObjectCount() { 50 | return (short) 1; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMEcdsa256NoDigestSignature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.security.CryptoException; 19 | import javacard.framework.Util; 20 | import javacard.security.Key; 21 | import javacard.security.MessageDigest; 22 | import javacard.security.Signature; 23 | import javacardx.crypto.Cipher; 24 | 25 | public class KMEcdsa256NoDigestSignature extends Signature { 26 | 27 | public static final byte ALG_ECDSA_NODIGEST = (byte) 0x67; 28 | public static final short MAX_NO_DIGEST_MSG_LEN = 32; 29 | private byte algorithm; 30 | private Signature inst; 31 | 32 | public KMEcdsa256NoDigestSignature(byte alg) { 33 | algorithm = alg; 34 | inst = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false); 35 | } 36 | 37 | @Override 38 | public void init(Key key, byte b) throws CryptoException { 39 | inst.init(key, b); 40 | } 41 | 42 | @Override 43 | public void init(Key key, byte b, byte[] bytes, short i, short i1) 44 | throws CryptoException { 45 | inst.init(key, b, bytes, i, i1); 46 | } 47 | 48 | @Override 49 | public void setInitialDigest(byte[] bytes, short i, short i1, byte[] bytes1, 50 | short i2, short i3) throws CryptoException { 51 | 52 | } 53 | 54 | @Override 55 | public byte getAlgorithm() { 56 | return algorithm; 57 | } 58 | 59 | @Override 60 | public byte getMessageDigestAlgorithm() { 61 | return MessageDigest.ALG_NULL; 62 | } 63 | 64 | @Override 65 | public byte getCipherAlgorithm() { 66 | return 0; 67 | } 68 | 69 | @Override 70 | public byte getPaddingAlgorithm() { 71 | return Cipher.PAD_NULL; 72 | } 73 | 74 | @Override 75 | public short getLength() throws CryptoException { 76 | return inst.getLength(); 77 | } 78 | 79 | @Override 80 | public void update(byte[] message, short msgStart, short messageLength) 81 | throws CryptoException { 82 | // HAL accumulates the data and send it at finish operation. 83 | } 84 | 85 | @Override 86 | public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) 87 | throws CryptoException { 88 | try { 89 | if (i1 > MAX_NO_DIGEST_MSG_LEN) { 90 | CryptoException.throwIt(CryptoException.ILLEGAL_USE); 91 | } 92 | // add zeros to the left 93 | if (i1 < MAX_NO_DIGEST_MSG_LEN) { 94 | Util.arrayFillNonAtomic(KMAndroidSEProvider.getInstance().tmpArray, 95 | (short) 0, (short) MAX_NO_DIGEST_MSG_LEN, (byte) 0); 96 | } 97 | Util.arrayCopyNonAtomic(bytes, i, 98 | KMAndroidSEProvider.getInstance().tmpArray, 99 | (short) (MAX_NO_DIGEST_MSG_LEN - i1), i1); 100 | return inst.signPreComputedHash(KMAndroidSEProvider.getInstance().tmpArray, 101 | (short) 0, (short) MAX_NO_DIGEST_MSG_LEN, bytes1, i2); 102 | } finally { 103 | KMAndroidSEProvider.getInstance().clean(); 104 | } 105 | } 106 | 107 | @Override 108 | public short signPreComputedHash(byte[] bytes, short i, short i1, 109 | byte[] bytes1, short i2) throws CryptoException { 110 | return inst.sign(bytes, i, i1, bytes1, i2); 111 | } 112 | 113 | @Override 114 | public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, 115 | short i2, short i3) throws CryptoException { 116 | //Verification is handled inside HAL 117 | return false; 118 | } 119 | 120 | @Override 121 | public boolean verifyPreComputedHash(byte[] bytes, short i, short i1, 122 | byte[] bytes1, short i2, short i3) throws CryptoException { 123 | //Verification is handled inside HAL 124 | return false; 125 | } 126 | } -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMHmacKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import org.globalplatform.upgrade.Element; 19 | 20 | import javacard.security.HMACKey; 21 | 22 | public class KMHmacKey implements KMPreSharedKey, KMComputedHmacKey { 23 | 24 | public HMACKey hmacKey; 25 | 26 | public KMHmacKey(HMACKey key) { 27 | hmacKey = key; 28 | } 29 | 30 | public static void onSave(Element element, KMHmacKey kmKey) { 31 | element.write(kmKey.hmacKey); 32 | } 33 | 34 | public static KMHmacKey onRestore(Element element) { 35 | HMACKey hmacKey = (HMACKey) element.readObject(); 36 | KMHmacKey kmKey = new KMHmacKey(hmacKey); 37 | return kmKey; 38 | } 39 | 40 | public static short getBackupPrimitiveByteCount() { 41 | return (short) 0; 42 | } 43 | 44 | public static short getBackupObjectCount() { 45 | return (short) 1; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMKeyObject.java: -------------------------------------------------------------------------------- 1 | package com.android.javacard.keymaster; 2 | 3 | public class KMKeyObject { 4 | public byte algorithm; 5 | public Object keyObjectInst; 6 | } 7 | -------------------------------------------------------------------------------- /Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.framework.Util; 19 | import javacard.security.CryptoException; 20 | import javacard.security.Key; 21 | import javacard.security.MessageDigest; 22 | import javacard.security.Signature; 23 | import javacardx.crypto.Cipher; 24 | 25 | public class KMRsa2048NoDigestSignature extends Signature { 26 | 27 | public static final byte ALG_RSA_SIGN_NOPAD = (byte) 0x65; 28 | public static final byte ALG_RSA_PKCS1_NODIGEST = (byte) 0x66; 29 | private byte algorithm; 30 | private Cipher inst; 31 | 32 | public KMRsa2048NoDigestSignature(byte alg) { 33 | algorithm = alg; 34 | inst = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false); 35 | } 36 | 37 | @Override 38 | public void init(Key key, byte b) throws CryptoException { 39 | inst.init(key, b); 40 | } 41 | 42 | @Override 43 | public void init(Key key, byte b, byte[] bytes, short i, short i1) 44 | throws CryptoException { 45 | inst.init(key, b, bytes, i, i1); 46 | } 47 | 48 | @Override 49 | public void setInitialDigest(byte[] bytes, short i, short i1, byte[] bytes1, 50 | short i2, short i3) throws CryptoException { 51 | } 52 | 53 | @Override 54 | public byte getAlgorithm() { 55 | return algorithm; 56 | } 57 | 58 | @Override 59 | public byte getMessageDigestAlgorithm() { 60 | return MessageDigest.ALG_NULL; 61 | } 62 | 63 | @Override 64 | public byte getCipherAlgorithm() { 65 | return algorithm; 66 | } 67 | 68 | @Override 69 | public byte getPaddingAlgorithm() { 70 | return Cipher.PAD_NULL; 71 | } 72 | 73 | @Override 74 | public short getLength() throws CryptoException { 75 | return 0; 76 | } 77 | 78 | @Override 79 | public void update(byte[] bytes, short i, short i1) throws CryptoException { 80 | // HAL accumulates the data and send it at finish operation. 81 | } 82 | 83 | @Override 84 | public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) 85 | throws CryptoException { 86 | padData(bytes, i, i1, KMAndroidSEProvider.getInstance().tmpArray, (short) 0); 87 | return inst.doFinal(KMAndroidSEProvider.getInstance().tmpArray, (short) 0, 88 | (short) 256, bytes1, i2); 89 | } 90 | 91 | @Override 92 | public short signPreComputedHash(byte[] bytes, short i, short i1, 93 | byte[] bytes1, short i2) throws CryptoException { 94 | return 0; 95 | } 96 | 97 | @Override 98 | public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, 99 | short i2, short i3) throws CryptoException { 100 | //Verification is handled inside HAL 101 | return false; 102 | } 103 | 104 | @Override 105 | public boolean verifyPreComputedHash(byte[] bytes, short i, short i1, 106 | byte[] bytes1, short i2, short i3) throws CryptoException { 107 | //Verification is handled inside HAL 108 | return false; 109 | } 110 | 111 | private void padData(byte[] buf, short start, short len, byte[] outBuf, 112 | short outBufStart) { 113 | if (!isValidData(buf, start, len)) { 114 | CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); 115 | } 116 | Util.arrayFillNonAtomic(outBuf, (short) outBufStart, (short) 256, 117 | (byte) 0x00); 118 | if (algorithm == ALG_RSA_SIGN_NOPAD) { // add zero to right 119 | } else if (algorithm == ALG_RSA_PKCS1_NODIGEST) {// 0x00||0x01||PS||0x00 120 | outBuf[0] = 0x00; 121 | outBuf[1] = 0x01; 122 | Util.arrayFillNonAtomic(outBuf, (short) 2, (short) (256 - len - 3), 123 | (byte) 0xFF); 124 | outBuf[(short) (256 - len - 1)] = 0x00; 125 | } else { 126 | CryptoException.throwIt(CryptoException.ILLEGAL_USE); 127 | } 128 | Util.arrayCopyNonAtomic(buf, start, outBuf, (short) (256 - len), len); 129 | } 130 | 131 | private boolean isValidData(byte[] buf, short start, short len) { 132 | if (algorithm == ALG_RSA_SIGN_NOPAD) { 133 | if (len > 256) { 134 | return false; 135 | } 136 | } else { // ALG_RSA_PKCS1_NODIGEST 137 | if (len > 245) { 138 | return false; 139 | } 140 | } 141 | return true; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/lib/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/JCardSimProvider/lib/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /Applet/JCardSimProvider/lib/jcardsim-3.0.5-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/JCardSimProvider/lib/jcardsim-3.0.5-SNAPSHOT.jar -------------------------------------------------------------------------------- /Applet/JCardSimProvider/lib/junit-4.13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/Applet/JCardSimProvider/lib/junit-4.13.jar -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAESKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.security.AESKey; 19 | 20 | public class KMAESKey implements KMMasterKey { 21 | 22 | private AESKey aesKey; 23 | 24 | public KMAESKey(AESKey key) { 25 | aesKey = key; 26 | } 27 | 28 | public void setKey(byte[] keyData, short kOff) { 29 | aesKey.setKey(keyData, kOff); 30 | } 31 | 32 | public byte getKey(byte[] keyData, short kOff) { 33 | return aesKey.getKey(keyData, kOff); 34 | } 35 | 36 | public short getKeySizeBits() { 37 | return aesKey.getSize(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | public abstract class KMCipher { 19 | 20 | public static final short SUN_JCE = 0xE9; 21 | 22 | public abstract short doFinal(byte[] buffer, short startOff, short length, byte[] scratchPad, 23 | short i); 24 | 25 | public abstract short update(byte[] buffer, short startOff, short length, byte[] scratchPad, 26 | short i); 27 | 28 | public abstract void updateAAD(byte[] buffer, short startOff, short length); 29 | 30 | public abstract short getBlockMode(); 31 | 32 | public abstract void setBlockMode(short mode); 33 | 34 | public abstract short getPaddingAlgorithm(); 35 | 36 | public abstract short getCipherAlgorithm(); 37 | 38 | public abstract void setPaddingAlgorithm(short alg); 39 | 40 | public abstract void setCipherAlgorithm(short alg); 41 | 42 | public abstract short getCipherProvider(); 43 | 44 | public abstract short getAesGcmOutputSize(short len, short macLength); 45 | } 46 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMConfigurations.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | public class KMConfigurations { 19 | // Machine types 20 | public static final byte LITTLE_ENDIAN = 0x00; 21 | public static final byte BIG_ENDIAN = 0x01; 22 | public static final byte TEE_MACHINE_TYPE = LITTLE_ENDIAN; 23 | 24 | // Maximum cert chain size 25 | public static final short CERT_CHAIN_MAX_SIZE = 2500; 26 | public static final short CERT_ISSUER_MAX_SIZE = 250; 27 | public static final short CERT_EXPIRY_MAX_SIZE = 20; 28 | public static final short TOTAL_ATTEST_IDS_SIZE = 300; 29 | } 30 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMECPrivateKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.security.ECPrivateKey; 19 | import javacard.security.KeyPair; 20 | 21 | public class KMECPrivateKey implements KMAttestationKey { 22 | 23 | private KeyPair ecKeyPair; 24 | 25 | public KMECPrivateKey(KeyPair ecPair) { 26 | ecKeyPair = ecPair; 27 | } 28 | 29 | public void setS(byte[] buffer, short offset, short length) { 30 | ECPrivateKey ecPriv = (ECPrivateKey) ecKeyPair.getPrivate(); 31 | ecPriv.setS(buffer, offset, length); 32 | } 33 | 34 | public ECPrivateKey getPrivateKey() { 35 | return (ECPrivateKey) ecKeyPair.getPrivate(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMHmacKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.security.HMACKey; 19 | 20 | public class KMHmacKey implements KMPreSharedKey, KMComputedHmacKey { 21 | 22 | private HMACKey hmacKey; 23 | 24 | public KMHmacKey(HMACKey key) { 25 | hmacKey = key; 26 | } 27 | 28 | public void setKey(byte[] keyData, short kOff, short length) { 29 | hmacKey.setKey(keyData, kOff, length); 30 | } 31 | 32 | public byte getKey(byte[] keyData, short kOff) { 33 | return hmacKey.getKey(keyData, kOff); 34 | } 35 | 36 | public HMACKey getKey() { 37 | return hmacKey; 38 | } 39 | 40 | public short getKeySizeBits() { 41 | return hmacKey.getSize(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimApplet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | public class KMJCardSimApplet extends KMKeymasterApplet { 19 | 20 | KMJCardSimApplet() { 21 | super(new KMJCardSimulator()); 22 | } 23 | 24 | /** 25 | * Installs this applet. 26 | * 27 | * @param bArray the array containing installation parameters 28 | * @param bOffset the starting offset in bArray 29 | * @param bLength the length in bytes of the parameter data in bArray 30 | */ 31 | public static void install(byte[] bArray, short bOffset, byte bLength) { 32 | new KMJCardSimApplet().register(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMOperationImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.security.Signature; 19 | 20 | public class KMOperationImpl implements KMOperation { 21 | 22 | private KMCipher cipher; 23 | private Signature signature; 24 | 25 | public KMOperationImpl(KMCipher cipher) { 26 | this.cipher = cipher; 27 | this.signature = null; 28 | } 29 | 30 | public KMOperationImpl(Signature sign) { 31 | this.cipher = null; 32 | this.signature = sign; 33 | } 34 | 35 | @Override 36 | public short update(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 37 | byte[] outputDataBuf, short outputDataStart) { 38 | return cipher 39 | .update(inputDataBuf, inputDataStart, inputDataLength, outputDataBuf, outputDataStart); 40 | } 41 | 42 | @Override 43 | public short update(byte[] inputDataBuf, short inputDataStart, short inputDataLength) { 44 | signature.update(inputDataBuf, inputDataStart, inputDataLength); 45 | return 0; 46 | } 47 | 48 | @Override 49 | public short finish(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 50 | byte[] outputDataBuf, short outputDataStart) { 51 | return cipher 52 | .doFinal(inputDataBuf, inputDataStart, inputDataLength, outputDataBuf, outputDataStart); 53 | } 54 | 55 | @Override 56 | public short sign(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 57 | byte[] signBuf, short signStart) { 58 | return signature.sign(inputDataBuf, inputDataStart, inputDataLength, signBuf, signStart); 59 | } 60 | 61 | @Override 62 | public boolean verify(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 63 | byte[] signBuf, short signStart, short signLength) { 64 | return signature 65 | .verify(inputDataBuf, inputDataStart, inputDataLength, signBuf, signStart, signLength); 66 | } 67 | 68 | @Override 69 | public void abort() { 70 | // do nothing 71 | } 72 | 73 | @Override 74 | public void updateAAD(byte[] dataBuf, short dataStart, short dataLength) { 75 | cipher.updateAAD(dataBuf, dataStart, dataLength); 76 | } 77 | 78 | @Override 79 | public short getAESGCMOutputSize(short dataSize, short macLength) { 80 | return cipher.getAesGcmOutputSize(dataSize, macLength); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMRsa2048NoDigestSignature.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import javacard.framework.Util; 19 | import javacard.security.CryptoException; 20 | import javacard.security.Key; 21 | import javacard.security.Signature; 22 | import javacardx.crypto.Cipher; 23 | 24 | public class KMRsa2048NoDigestSignature extends Signature { 25 | 26 | private Cipher inst; // ALG_RSA_NOPAD. 27 | private byte padding; 28 | private byte[] rsaModulus; // to compare with the data value 29 | 30 | public KMRsa2048NoDigestSignature(Cipher ciph, byte padding, byte[] mod, short start, short len) { 31 | inst = ciph; 32 | this.padding = padding; 33 | if (len != 256) { 34 | CryptoException.throwIt(CryptoException.INVALID_INIT); 35 | } 36 | rsaModulus = new byte[256]; 37 | Util.arrayCopyNonAtomic(mod, start, rsaModulus, (short) 0, len); 38 | } 39 | 40 | @Override 41 | public void init(Key key, byte b) throws CryptoException { 42 | 43 | } 44 | 45 | @Override 46 | public void init(Key key, byte b, byte[] bytes, short i, short i1) throws CryptoException { 47 | } 48 | 49 | @Override 50 | public void setInitialDigest(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) 51 | throws CryptoException { 52 | } 53 | 54 | @Override 55 | public byte getAlgorithm() { 56 | return 0; 57 | } 58 | 59 | @Override 60 | public byte getMessageDigestAlgorithm() { 61 | return 0; 62 | } 63 | 64 | @Override 65 | public byte getCipherAlgorithm() { 66 | return 0; 67 | } 68 | 69 | @Override 70 | public byte getPaddingAlgorithm() { 71 | return 0; 72 | } 73 | 74 | @Override 75 | public short getLength() throws CryptoException { 76 | return 0; 77 | } 78 | 79 | @Override 80 | public void update(byte[] bytes, short i, short i1) throws CryptoException { 81 | } 82 | 83 | @Override 84 | public short sign(byte[] bytes, short i, short i1, byte[] bytes1, short i2) 85 | throws CryptoException { 86 | byte[] inputData = padData(bytes, i, i1); 87 | return inst.doFinal(inputData, (short) 0, (short) 256, bytes1, i2); 88 | } 89 | 90 | @Override 91 | public short signPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1, short i2) 92 | throws CryptoException { 93 | return 0; 94 | } 95 | 96 | @Override 97 | public boolean verify(byte[] bytes, short i, short i1, byte[] bytes1, short i2, short i3) 98 | throws CryptoException { 99 | // Public key operations not handled here. 100 | return false; 101 | } 102 | 103 | @Override 104 | public boolean verifyPreComputedHash(byte[] bytes, short i, short i1, byte[] bytes1, short i2, 105 | short i3) throws CryptoException { 106 | return false; 107 | } 108 | 109 | private byte[] padData(byte[] buf, short start, short len) { 110 | byte[] inputData = new byte[256]; 111 | if (!isValidData(buf, start, len)) { 112 | CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); 113 | } 114 | Util.arrayFillNonAtomic(inputData, (short) 0, (short) 256, (byte) 0x00); 115 | if (padding == KMType.PADDING_NONE) { // add zero to right 116 | } else if (padding == KMType.RSA_PKCS1_1_5_SIGN) {// 0x00||0x01||PS||0x00 117 | inputData[0] = 0x00; 118 | inputData[1] = 0x01; 119 | Util.arrayFillNonAtomic(inputData, (short) 2, (short) (256 - len - 3), (byte) 0xFF); 120 | inputData[(short) (256 - len - 1)] = 0x00; 121 | } else { 122 | CryptoException.throwIt(CryptoException.ILLEGAL_USE); 123 | } 124 | Util.arrayCopyNonAtomic(buf, start, inputData, (short) (256 - len), len); 125 | return inputData; 126 | } 127 | 128 | private boolean isValidData(byte[] buf, short start, short len) { 129 | if (padding == KMType.PADDING_NONE) { 130 | if (len > 256) { 131 | return false; 132 | } else if (len == 256) { 133 | short v = KMInteger.unsignedByteArrayCompare(buf, start, rsaModulus, (short) 0, len); 134 | if (v > 0) { 135 | return false; 136 | } 137 | } 138 | } else {//pkcs1 no digest 139 | if (len > 245) { 140 | return false; 141 | } 142 | } 143 | return true; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Applet/README.md: -------------------------------------------------------------------------------- 1 | # JavaCardKeymaster Applet 2 | 3 | This directory contains the implementation of the Keymaster 4.1 4 | interface, in the form of a JavaCard 3.0.5 applet which runs in a secure 5 | element. It must be deployed in conjuction with the associated HAL, 6 | which serves to intermediate between Android Keystore and this applet. 7 | 8 | # Supported Features! 9 | 10 | - Support for AndroidSEProvider, which is compliant to JavaCard platform, Classic Edition 3.0.5. 11 | - Keymaster 4.1 supported functions for required VTS compliance. 12 | - Support for SE Provisioning and bootup 13 | - Support for Global platoform Amendment H in AndroidSEProvider. 14 | - Unit test using JCardSim. 15 | 16 | #### Building for source 17 | - Install Javacard 3.0.5 classic sdk. 18 | - set JC_HOME_SIMULATOR environment variable to the installed sdk. 19 | - Give ant build from Applet folder. 20 | - Download [gpapi-upgrade.jar](https://globalplatform.wpengine.com/specs-library/globalplatform-card-api-org-globalplatform-upgrade-v1/) and copy inside lib folder of both AndroidSEProvider and JCardSimProvider to resolve the compilation errors. 21 | 22 | -------------------------------------------------------------------------------- /Applet/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMAppletState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | // This class contains the states associated with 18 | // the Keymaster Applet. 19 | public class KMAppletState { 20 | // Possible states of the applet. 21 | public static final byte KM_BEGIN_STATE = 0x00; 22 | //private static final byte ILLEGAL_STATE = KM_BEGIN_STATE + 1; // Unused. 23 | public static final byte INIT_STATE = KM_BEGIN_STATE + 2; 24 | public static final byte IN_PROVISION_STATE = KM_BEGIN_STATE + 3; 25 | public static final byte ACTIVE_STATE = KM_BEGIN_STATE + 4; 26 | } 27 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMArray represents an array of KMTypes. Array is the sequence of elements of one or more sub 25 | * types of KMType. It also acts as a vector of one subtype of KMTypes on the lines of class 26 | * KMArray 27 | * , where subType is subclass of KMType. Vector is the sequence of elements of one sub 28 | * type e.g. KMType.BYTE_BLOB_TYPE. The KMArray instance maps to the CBOR type array. KMArray is a 29 | * KMType and it further extends the value field in TLV_HEADER as ARRAY_HEADER struct{short subType; 30 | * short length;} followed by sequence of short pointers to KMType instances. The subType can be 0 31 | * if this is an array or subType is short KMType value e.g. KMType.BYTE_BLOB_TYPE if this is a 32 | * vector of that sub type. 33 | */ 34 | public class KMArray extends KMType { 35 | 36 | public static final short ANY_ARRAY_LENGTH = 0x1000; 37 | private static final short ARRAY_HEADER_SIZE = 4; 38 | private static KMArray prototype; 39 | 40 | private KMArray() { 41 | } 42 | 43 | private static KMArray proto(short ptr) { 44 | if (prototype == null) { 45 | prototype = new KMArray(); 46 | } 47 | instanceTable[KM_ARRAY_OFFSET] = ptr; 48 | return prototype; 49 | } 50 | 51 | public static short exp() { 52 | short ptr = instance(ARRAY_TYPE, ARRAY_HEADER_SIZE); 53 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), (short) 0); 54 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), ANY_ARRAY_LENGTH); 55 | return ptr; 56 | } 57 | 58 | public static short exp(short type) { 59 | short ptr = instance(ARRAY_TYPE, ARRAY_HEADER_SIZE); 60 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), type); 61 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), ANY_ARRAY_LENGTH); 62 | return ptr; 63 | } 64 | 65 | public static short instance(short length) { 66 | short ptr = KMType.instance(ARRAY_TYPE, (short) (ARRAY_HEADER_SIZE + (length * 2))); 67 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), (short) 0); 68 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), length); 69 | return ptr; 70 | } 71 | 72 | public static short instance(short length, byte type) { 73 | short ptr = instance(length); 74 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), type); 75 | return ptr; 76 | } 77 | 78 | public static KMArray cast(short ptr) { 79 | if (heap[ptr] != ARRAY_TYPE) { 80 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 81 | } 82 | return proto(ptr); 83 | } 84 | 85 | public void add(short index, short objPtr) { 86 | short len = length(); 87 | if (index >= len) { 88 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 89 | } 90 | Util.setShort( 91 | heap, 92 | (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2)), 93 | objPtr); 94 | } 95 | 96 | public short get(short index) { 97 | short len = length(); 98 | if (index >= len) { 99 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 100 | } 101 | return Util.getShort( 102 | heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE + (short) (index * 2))); 103 | } 104 | 105 | public short containedType() { 106 | return Util.getShort(heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE)); 107 | } 108 | 109 | public short getStartOff() { 110 | return (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + ARRAY_HEADER_SIZE); 111 | } 112 | 113 | public short length() { 114 | return Util.getShort(heap, (short) (instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + 2)); 115 | } 116 | 117 | public short setLength(short len) { 118 | return Util.setShort(heap, 119 | (short) (KMType.instanceTable[KM_ARRAY_OFFSET] + TLV_HEADER_SIZE + 2), len); 120 | } 121 | 122 | public byte[] getBuffer() { 123 | return heap; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMAttestationKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | /** 19 | * KMAttestationKey is a marker interface and the SE Provider has to implement this interface. 20 | * Internally attestation key is stored as a Javacard EC key pair object, which will provide 21 | * additional security. The attestation key is maintained by the SEProvider. 22 | */ 23 | public interface KMAttestationKey { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMBoolTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMBoolTag represents BOOL TAG type from the android keymaster hal specifications. If it is 25 | * present in the key parameter list then its value is always true. A KMTag always requires a value 26 | * because it is a key value pair. The bool tag always has 0x01 as its value. struct{byte TAG_TYPE; 27 | * short length; struct{short BOOL_TAG; short tagKey; byte value 1}} 28 | */ 29 | 30 | public class KMBoolTag extends KMTag { 31 | 32 | private static KMBoolTag prototype; 33 | 34 | // The allowed tag keys of type bool tag. 35 | private static final short[] tags = { 36 | CALLER_NONCE, 37 | INCLUDE_UNIQUE_ID, 38 | BOOTLOADER_ONLY, 39 | ROLLBACK_RESISTANCE, 40 | NO_AUTH_REQUIRED, 41 | ALLOW_WHILE_ON_BODY, 42 | TRUSTED_USER_PRESENCE_REQUIRED, 43 | TRUSTED_CONFIRMATION_REQUIRED, 44 | UNLOCKED_DEVICE_REQUIRED, 45 | RESET_SINCE_ID_ROTATION, 46 | EARLY_BOOT_ONLY, 47 | DEVICE_UNIQUE_ATTESTATION 48 | }; 49 | 50 | private KMBoolTag() { 51 | } 52 | 53 | private static KMBoolTag proto(short ptr) { 54 | if (prototype == null) { 55 | prototype = new KMBoolTag(); 56 | } 57 | instanceTable[KM_BOOL_TAG_OFFSET] = ptr; 58 | return prototype; 59 | } 60 | 61 | // pointer to an empty instance used as expression 62 | public static short exp() { 63 | short ptr = instance(TAG_TYPE, (short) 2); 64 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), BOOL_TAG); 65 | return ptr; 66 | } 67 | 68 | public static short instance(short key) { 69 | if (!validateKey(key)) { 70 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 71 | } 72 | short ptr = KMType.instance(TAG_TYPE, (short) 5); 73 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), BOOL_TAG); 74 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), key); 75 | // Value is always 1. 76 | heap[(short) (ptr + TLV_HEADER_SIZE + 4)] = 0x01; 77 | return ptr; 78 | } 79 | 80 | public static KMBoolTag cast(short ptr) { 81 | if (heap[ptr] != TAG_TYPE) { 82 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 83 | } 84 | if (Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)) != BOOL_TAG) { 85 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 86 | } 87 | return proto(ptr); 88 | } 89 | 90 | public short getKey() { 91 | return Util.getShort(heap, (short) (instanceTable[KM_BOOL_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); 92 | } 93 | 94 | public short getTagType() { 95 | return KMType.BOOL_TAG; 96 | } 97 | 98 | public byte getVal() { 99 | return heap[(short) (instanceTable[KM_BOOL_TAG_OFFSET] + TLV_HEADER_SIZE + 4)]; 100 | } 101 | 102 | // validate the tag key. 103 | private static boolean validateKey(short key) { 104 | short index = (short) tags.length; 105 | while (--index >= 0) { 106 | if (tags[index] == key) { 107 | return true; 108 | } 109 | } 110 | return false; 111 | } 112 | 113 | public static short[] getTags() { 114 | return tags; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMByteBlob.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMByteBlob represents contiguous block of bytes. It corresponds to CBOR type of Byte String. It 25 | * extends KMType by specifying value field as zero or more sequence of bytes. struct{byte 26 | * BYTE_BLOB_TYPE; short length; sequence of bytes} 27 | */ 28 | public class KMByteBlob extends KMType { 29 | 30 | private static KMByteBlob prototype; 31 | 32 | private KMByteBlob() { 33 | } 34 | 35 | private static KMByteBlob proto(short ptr) { 36 | if (prototype == null) { 37 | prototype = new KMByteBlob(); 38 | } 39 | instanceTable[KM_BYTE_BLOB_OFFSET] = ptr; 40 | return prototype; 41 | } 42 | 43 | // pointer to an empty instance used as expression 44 | public static short exp() { 45 | return KMType.exp(BYTE_BLOB_TYPE); 46 | } 47 | 48 | // return an empty byte blob instance 49 | public static short instance(short length) { 50 | return KMType.instance(BYTE_BLOB_TYPE, length); 51 | } 52 | 53 | // byte blob from existing buf 54 | public static short instance(byte[] buf, short startOff, short length) { 55 | short ptr = instance(length); 56 | Util.arrayCopyNonAtomic(buf, startOff, heap, (short) (ptr + TLV_HEADER_SIZE), length); 57 | return ptr; 58 | } 59 | 60 | // cast the ptr to KMByteBlob 61 | public static KMByteBlob cast(short ptr) { 62 | if (heap[ptr] != BYTE_BLOB_TYPE) { 63 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 64 | } 65 | if (Util.getShort(heap, (short) (ptr + 1)) == INVALID_VALUE) { 66 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 67 | } 68 | return proto(ptr); 69 | } 70 | 71 | // Add the byte 72 | public void add(short index, byte val) { 73 | short len = length(); 74 | if (index >= len) { 75 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 76 | } 77 | heap[(short) (instanceTable[KM_BYTE_BLOB_OFFSET] + TLV_HEADER_SIZE + index)] = val; 78 | } 79 | 80 | // Get the byte 81 | public byte get(short index) { 82 | short len = length(); 83 | if (index >= len) { 84 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 85 | } 86 | return heap[(short) (instanceTable[KM_BYTE_BLOB_OFFSET] + TLV_HEADER_SIZE + index)]; 87 | } 88 | 89 | // Get the start of blob 90 | public short getStartOff() { 91 | return (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + TLV_HEADER_SIZE); 92 | } 93 | 94 | // Get the length of the blob 95 | public short length() { 96 | return Util.getShort(heap, (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + 1)); 97 | } 98 | 99 | // Get the buffer pointer in which blob is contained. 100 | public byte[] getBuffer() { 101 | return heap; 102 | } 103 | 104 | public void getValue(byte[] destBuf, short destStart, short destLength) { 105 | Util.arrayCopyNonAtomic(heap, getStartOff(), destBuf, destStart, destLength); 106 | } 107 | 108 | public short getValues(byte[] destBuf, short destStart) { 109 | short destLength = length(); 110 | Util.arrayCopyNonAtomic(heap, getStartOff(), destBuf, destStart, destLength); 111 | return destLength; 112 | } 113 | 114 | public void setValue(byte[] srcBuf, short srcStart, short srcLength) { 115 | if (length() > srcLength) { 116 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 117 | } 118 | Util.arrayCopyNonAtomic(srcBuf, srcStart, heap, getStartOff(), length()); 119 | } 120 | 121 | public boolean isValid() { 122 | if (length() == 0) { 123 | return false; 124 | } 125 | return true; 126 | } 127 | 128 | public void decrementLength(short len) { 129 | short length = Util.getShort(heap, (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + 1)); 130 | length = (short) (length - len); 131 | Util.setShort(heap, (short) (instanceTable[KM_BYTE_BLOB_OFFSET] + 1), length); 132 | } 133 | 134 | public void setLength(short len) { 135 | Util.setShort(heap, (short)(instanceTable[KM_BYTE_BLOB_OFFSET] + 1), len); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMByteTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMByteTag represents BYTES Tag Type from android keymaster hal specifications. The tag value of 25 | * this tag is the KMByteBlob pointer i.e. offset of KMByteBlob in memory heap. struct{byte 26 | * TAG_TYPE; short length; struct{short BYTES_TAG; short tagKey; short blobPtr}} 27 | */ 28 | 29 | public class KMByteTag extends KMTag { 30 | 31 | private static KMByteTag prototype; 32 | 33 | private KMByteTag() { 34 | } 35 | 36 | private static KMByteTag proto(short ptr) { 37 | if (prototype == null) { 38 | prototype = new KMByteTag(); 39 | } 40 | instanceTable[KM_BYTE_TAG_OFFSET] = ptr; 41 | return prototype; 42 | } 43 | 44 | // pointer to an empty instance used as expression 45 | public static short exp() { 46 | short blobPtr = KMByteBlob.exp(); 47 | short ptr = instance(TAG_TYPE, (short) 6); 48 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), BYTES_TAG); 49 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), INVALID_TAG); 50 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 4), blobPtr); 51 | return ptr; 52 | } 53 | 54 | public static short instance(short key, short byteBlob) { 55 | if (!validateKey(key, byteBlob)) { 56 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 57 | } 58 | if (heap[byteBlob] != BYTE_BLOB_TYPE) { 59 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 60 | } 61 | short ptr = instance(TAG_TYPE, (short) 6); 62 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), BYTES_TAG); 63 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), key); 64 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 4), byteBlob); 65 | return ptr; 66 | } 67 | 68 | public static KMByteTag cast(short ptr) { 69 | if (heap[ptr] != TAG_TYPE) { 70 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 71 | } 72 | if (Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)) != BYTES_TAG) { 73 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 74 | } 75 | return proto(ptr); 76 | } 77 | 78 | public short getKey() { 79 | return Util.getShort(heap, (short) (instanceTable[KM_BYTE_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); 80 | } 81 | 82 | public short getTagType() { 83 | return KMType.BYTES_TAG; 84 | } 85 | 86 | public short getValue() { 87 | return Util.getShort(heap, (short) (instanceTable[KM_BYTE_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); 88 | } 89 | 90 | public short length() { 91 | short blobPtr = Util.getShort(heap, (short) (instanceTable[KM_BYTE_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); 92 | return KMByteBlob.cast(blobPtr).length(); 93 | } 94 | 95 | private static boolean validateKey(short key, short byteBlob) { 96 | short valueLen = KMByteBlob.cast(byteBlob).length(); 97 | switch (key) { 98 | case APPLICATION_ID: 99 | case APPLICATION_DATA: 100 | if (valueLen > MAX_APP_ID_APP_DATA_SIZE) { 101 | KMException.throwIt(KMError.INVALID_INPUT_LENGTH); 102 | } 103 | break; 104 | case ROOT_OF_TRUST: 105 | case UNIQUE_ID: 106 | break; 107 | case ATTESTATION_CHALLENGE: 108 | if (valueLen > MAX_ATTESTATION_CHALLENGE_SIZE) { 109 | KMException.throwIt(KMError.INVALID_INPUT_LENGTH); 110 | } 111 | break; 112 | case ATTESTATION_APPLICATION_ID: 113 | if (valueLen > MAX_ATTESTATION_APP_ID_SIZE) { 114 | KMException.throwIt(KMError.INVALID_INPUT_LENGTH); 115 | } 116 | break; 117 | case ATTESTATION_ID_BRAND: 118 | case ATTESTATION_ID_DEVICE: 119 | case ATTESTATION_ID_PRODUCT: 120 | case ATTESTATION_ID_SERIAL: 121 | case ATTESTATION_ID_IMEI: 122 | case ATTESTATION_ID_MEID: 123 | case ATTESTATION_ID_MANUFACTURER: 124 | case ATTESTATION_ID_MODEL: 125 | case ASSOCIATED_DATA: 126 | case NONCE: 127 | case CONFIRMATION_TOKEN: 128 | case VERIFIED_BOOT_KEY: 129 | case VERIFIED_BOOT_HASH: 130 | break; 131 | default: 132 | return false; 133 | } 134 | return true; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMComputedHmacKey.java: -------------------------------------------------------------------------------- 1 | package com.android.javacard.keymaster; 2 | 3 | 4 | public interface KMComputedHmacKey { 5 | } 6 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMEnum represents an enumeration specified in android keymaster hal specifications. It 25 | * corresponds to uint CBOR type and it is a byte value. struct{byte ENUM_TYPE; short length; 26 | * struct{short enumType; byte val}} 27 | */ 28 | public class KMEnum extends KMType { 29 | 30 | private static KMEnum prototype; 31 | 32 | // The allowed enum types. 33 | private static final short[] types = { 34 | HARDWARE_TYPE, 35 | KEY_FORMAT, 36 | KEY_DERIVATION_FUNCTION, 37 | VERIFIED_BOOT_STATE, 38 | DEVICE_LOCKED, 39 | USER_AUTH_TYPE, 40 | PURPOSE, 41 | ECCURVE 42 | }; 43 | 44 | private static Object[] enums = null; 45 | 46 | private KMEnum() { 47 | } 48 | 49 | private static KMEnum proto(short ptr) { 50 | if (prototype == null) { 51 | prototype = new KMEnum(); 52 | } 53 | instanceTable[KM_ENUM_OFFSET] = ptr; 54 | return prototype; 55 | } 56 | 57 | // pointer to an empty instance used as expression 58 | public static short exp() { 59 | return KMType.exp(ENUM_TYPE); 60 | } 61 | 62 | public short length() { 63 | return Util.getShort(heap, (short) (instanceTable[KM_ENUM_OFFSET] + 1)); 64 | } 65 | 66 | public static KMEnum cast(short ptr) { 67 | if (heap[ptr] != ENUM_TYPE) { 68 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 69 | } 70 | if (Util.getShort(heap, (short) (ptr + 1)) == INVALID_VALUE) { 71 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 72 | } 73 | return proto(ptr); 74 | } 75 | 76 | public static short instance(short enumType) { 77 | if (!validateEnum(enumType, NO_VALUE)) { 78 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 79 | } 80 | short ptr = KMType.instance(ENUM_TYPE, (short) 2); 81 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), enumType); 82 | return ptr; 83 | } 84 | 85 | public static short instance(short enumType, byte val) { 86 | if (!validateEnum(enumType, val)) { 87 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 88 | } 89 | short ptr = KMType.instance(ENUM_TYPE, (short) 3); 90 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), enumType); 91 | heap[(short) (ptr + TLV_HEADER_SIZE + 2)] = val; 92 | return ptr; 93 | } 94 | 95 | private static void create() { 96 | // The allowed enum values to corresponding enum types in the types array. 97 | if (enums == null) { 98 | enums = 99 | new Object[]{ 100 | new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX}, 101 | new byte[]{X509, PKCS8, RAW}, 102 | new byte[]{ 103 | DERIVATION_NONE, 104 | RFC5869_SHA256, 105 | ISO18033_2_KDF1_SHA1, 106 | ISO18033_2_KDF1_SHA256, 107 | ISO18033_2_KDF2_SHA1, 108 | ISO18033_2_KDF2_SHA256 109 | }, 110 | new byte[]{SELF_SIGNED_BOOT, VERIFIED_BOOT, UNVERIFIED_BOOT, FAILED_BOOT}, 111 | new byte[]{DEVICE_LOCKED_TRUE, DEVICE_LOCKED_FALSE}, 112 | new byte[]{USER_AUTH_NONE, PASSWORD, FINGERPRINT, BOTH}, 113 | new byte[]{ENCRYPT, DECRYPT, SIGN, VERIFY, WRAP_KEY, ATTEST_KEY}, 114 | new byte[]{P_224, P_256, P_384, P_521} 115 | }; 116 | } 117 | } 118 | 119 | public void setVal(byte val) { 120 | heap[(short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)] = val; 121 | } 122 | 123 | public byte getVal() { 124 | return heap[(short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)]; 125 | } 126 | 127 | public void setEnumType(short type) { 128 | Util.setShort(heap, (short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE), type); 129 | } 130 | 131 | public short getEnumType() { 132 | return Util.getShort(heap, (short) (instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE)); 133 | } 134 | 135 | // isValidTag enumeration keys and values. 136 | private static boolean validateEnum(short key, byte value) { 137 | create(); 138 | byte[] vals; 139 | short enumInd; 140 | // check if key exists 141 | short index = (short) types.length; 142 | while (--index >= 0) { 143 | if (types[index] == key) { 144 | // check if value given 145 | if (value != NO_VALUE) { 146 | // check if the value exist 147 | vals = (byte[]) enums[index]; 148 | enumInd = (short) vals.length; 149 | while (--enumInd >= 0) { 150 | if (vals[enumInd] == value) { 151 | // return true if value exist 152 | return true; 153 | } 154 | } 155 | // return false if value does not exist 156 | return false; 157 | } 158 | // return true if key exist and value not given 159 | return true; 160 | } 161 | } 162 | // return false if key does not exist 163 | return false; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMEnumTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMEnumTag represents ENUM Tag type specified in android keymaster hal specifications. struct{byte 25 | * TAG_TYPE; short length; struct{short ENUM_TAG; short tagKey; byte value}} 26 | */ 27 | 28 | public class KMEnumTag extends KMTag { 29 | 30 | private static KMEnumTag prototype; 31 | 32 | 33 | // The allowed tag keys of type enum tag. 34 | private static final short[] tags = { 35 | ALGORITHM, ECCURVE, BLOB_USAGE_REQ, USER_AUTH_TYPE, ORIGIN, HARDWARE_TYPE 36 | }; 37 | 38 | private static Object[] enums = null; 39 | 40 | private KMEnumTag() { 41 | } 42 | 43 | private static KMEnumTag proto(short ptr) { 44 | if (prototype == null) { 45 | prototype = new KMEnumTag(); 46 | } 47 | instanceTable[KM_ENUM_TAG_OFFSET] = ptr; 48 | return prototype; 49 | } 50 | 51 | // pointer to an empty instance used as expression 52 | public static short exp() { 53 | short ptr = instance(TAG_TYPE, (short) 2); 54 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), ENUM_TAG); 55 | return ptr; 56 | } 57 | 58 | public static short instance(short key) { 59 | if (!validateEnum(key, NO_VALUE)) { 60 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 61 | } 62 | short ptr = KMType.instance(TAG_TYPE, (short) 4); 63 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), ENUM_TAG); 64 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), key); 65 | return ptr; 66 | } 67 | 68 | public static short instance(short key, byte val) { 69 | if (!validateEnum(key, val)) { 70 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 71 | } 72 | short ptr = instance(TAG_TYPE, (short) 5); 73 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), ENUM_TAG); 74 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), key); 75 | heap[(short) (ptr + TLV_HEADER_SIZE + 4)] = val; 76 | return ptr; 77 | } 78 | 79 | public static KMEnumTag cast(short ptr) { 80 | if (heap[ptr] != TAG_TYPE) { 81 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 82 | } 83 | if (Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)) != ENUM_TAG) { 84 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 85 | } 86 | return proto(ptr); 87 | } 88 | 89 | public short getKey() { 90 | return Util.getShort(heap, (short) (instanceTable[KM_ENUM_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); 91 | } 92 | 93 | public short getTagType() { 94 | return KMType.ENUM_TAG; 95 | } 96 | 97 | public byte getValue() { 98 | return heap[(short) (instanceTable[KM_ENUM_TAG_OFFSET] + TLV_HEADER_SIZE + 4)]; 99 | } 100 | 101 | public static void create() { 102 | if (enums == null) { 103 | // enum tag values. 104 | enums = 105 | new Object[]{ 106 | new byte[]{RSA, DES, EC, AES, HMAC}, 107 | new byte[]{P_224, P_256, P_384, P_521}, 108 | new byte[]{STANDALONE, REQUIRES_FILE_SYSTEM}, 109 | new byte[]{USER_AUTH_NONE, PASSWORD, FINGERPRINT, BOTH, ANY}, 110 | new byte[]{GENERATED, DERIVED, IMPORTED, UNKNOWN, SECURELY_IMPORTED}, 111 | new byte[]{SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX} 112 | }; 113 | } 114 | } 115 | 116 | // isValidTag enumeration keys and values. 117 | private static boolean validateEnum(short key, byte value) { 118 | create(); 119 | byte[] vals; 120 | short enumInd; 121 | // check if key exists 122 | short index = (short) tags.length; 123 | while (--index >= 0) { 124 | if (tags[index] == key) { 125 | // check if value given 126 | if (value != NO_VALUE) { 127 | // check if the value exist 128 | vals = (byte[]) enums[index]; 129 | enumInd = (short) vals.length; 130 | while (--enumInd >= 0) { 131 | if (vals[enumInd] == value) { 132 | // return true if value exist 133 | return true; 134 | } 135 | } 136 | // return false if value does not exist 137 | return false; 138 | } 139 | // return true if key exist and value not given 140 | return true; 141 | } 142 | } 143 | // return false if key does not exist 144 | return false; 145 | } 146 | 147 | public static short getValue(short tagType, short keyParameters) { 148 | short tagPtr = KMKeyParameters.findTag(KMType.ENUM_TAG, tagType, keyParameters); 149 | if (tagPtr != KMType.INVALID_VALUE) { 150 | return heap[(short) (tagPtr + TLV_HEADER_SIZE + 4)]; 151 | } 152 | return KMType.INVALID_VALUE; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | /** 19 | * KMError includes all the error codes from android keymaster hal specifications. The values are 20 | * positive unlike negative values in keymaster hal. 21 | */ 22 | public class KMError { 23 | 24 | public static final short OK = 0; 25 | public static final short UNSUPPORTED_PURPOSE = 2; 26 | public static final short INCOMPATIBLE_PURPOSE = 3; 27 | public static final short UNSUPPORTED_ALGORITHM = 4; 28 | public static final short INCOMPATIBLE_ALGORITHM = 5; 29 | public static final short UNSUPPORTED_KEY_SIZE = 6; 30 | public static final short UNSUPPORTED_BLOCK_MODE = 7; 31 | public static final short INCOMPATIBLE_BLOCK_MODE = 8; 32 | public static final short UNSUPPORTED_MAC_LENGTH = 9; 33 | public static final short UNSUPPORTED_PADDING_MODE = 10; 34 | public static final short INCOMPATIBLE_PADDING_MODE = 11; 35 | public static final short UNSUPPORTED_DIGEST = 12; 36 | public static final short INCOMPATIBLE_DIGEST = 13; 37 | 38 | public static final short UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = 19; 39 | 40 | /** 41 | * For PKCS8 & PKCS12 42 | */ 43 | public static final short INVALID_INPUT_LENGTH = 21; 44 | 45 | 46 | public static final short KEY_USER_NOT_AUTHENTICATED = 26; 47 | public static final short INVALID_OPERATION_HANDLE = 28; 48 | public static final short VERIFICATION_FAILED = 30; 49 | public static final short TOO_MANY_OPERATIONS = 31; 50 | public static final short INVALID_KEY_BLOB = 33; 51 | 52 | public static final short INVALID_ARGUMENT = 38; 53 | public static final short UNSUPPORTED_TAG = 39; 54 | public static final short INVALID_TAG = 40; 55 | public static final short IMPORT_PARAMETER_MISMATCH = 44; 56 | public static final short OPERATION_CANCELLED = 46; 57 | 58 | public static final short MISSING_NONCE = 51; 59 | public static final short INVALID_NONCE = 52; 60 | public static final short MISSING_MAC_LENGTH = 53; 61 | public static final short CALLER_NONCE_PROHIBITED = 55; 62 | public static final short KEY_MAX_OPS_EXCEEDED = 56; 63 | public static final short INVALID_MAC_LENGTH = 57; 64 | public static final short MISSING_MIN_MAC_LENGTH = 58; 65 | public static final short UNSUPPORTED_MIN_MAC_LENGTH = 59; 66 | public static final short UNSUPPORTED_EC_CURVE = 61; 67 | public static final short KEY_REQUIRES_UPGRADE = 62; 68 | 69 | public static final short ATTESTATION_APPLICATION_ID_MISSING = 65; 70 | public static final short CANNOT_ATTEST_IDS = 66; 71 | public static final short ROLLBACK_RESISTANCE_UNAVAILABLE = 67; 72 | public static final short NO_USER_CONFIRMATION = 71; 73 | public static final short DEVICE_LOCKED = 72; 74 | public static final short EARLY_BOOT_ENDED = 73; 75 | public static final short UNIMPLEMENTED = 100; 76 | public static final short UNKNOWN_ERROR = 1000; 77 | 78 | //Extended errors 79 | public static final short SW_CONDITIONS_NOT_SATISFIED = 10001; 80 | public static final short UNSUPPORTED_CLA = 10002; 81 | public static final short INVALID_P1P2 = 10003; 82 | public static final short UNSUPPORTED_INSTRUCTION = 10004; 83 | public static final short CMD_NOT_ALLOWED = 10005; 84 | public static final short SW_WRONG_LENGTH = 10006; 85 | public static final short INVALID_DATA = 10007; 86 | //Crypto errors 87 | public static final short CRYPTO_ILLEGAL_USE = 10008; 88 | public static final short CRYPTO_ILLEGAL_VALUE = 10009; 89 | public static final short CRYPTO_INVALID_INIT = 10010; 90 | public static final short CRYPTO_NO_SUCH_ALGORITHM = 10011; 91 | public static final short CRYPTO_UNINITIALIZED_KEY = 10012; 92 | //Generic Unknown error. 93 | public static final short GENERIC_UNKNOWN_ERROR = 10013; 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.JCSystem; 20 | 21 | /** 22 | * KMException is shared instance of exception used for all exceptions in the applet. It is used to 23 | * throw EMError errors. 24 | */ 25 | public class KMException extends RuntimeException { 26 | 27 | public short[] reason; 28 | public static KMException exception; 29 | 30 | private KMException() { 31 | reason = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); 32 | } 33 | 34 | public static void throwIt(short reason) { 35 | instance(); 36 | exception.reason[(short) 0] = reason; 37 | throw exception; 38 | } 39 | 40 | public static KMException instance() { 41 | if (exception == null) { 42 | exception = new KMException(); 43 | } 44 | return exception; 45 | } 46 | 47 | public void clear() { 48 | exception.reason[(short) 0] = KMError.UNKNOWN_ERROR; 49 | } 50 | 51 | public static short getReason() { 52 | return exception.reason[0]; 53 | } 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMHmacSharingParameters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMHmacSharingParameters represents HmacSharingParameters structure from android keymaster hal 25 | * specifications. It corresponds to CBOR array type. struct{byte HMAC_SHARING_PARAM_TYPE; short 26 | * length=2; short arrayPtr} where arrayPtr is a pointer to ordered array with following elements: 27 | * {KMByteBlob Seed; KMByteBlob Nonce} 28 | */ 29 | public class KMHmacSharingParameters extends KMType { 30 | 31 | public static final byte SEED = 0x00; 32 | public static final byte NONCE = 0x01; 33 | 34 | private static KMHmacSharingParameters prototype; 35 | 36 | private KMHmacSharingParameters() { 37 | } 38 | 39 | public static short exp() { 40 | short arrPtr = KMArray.instance((short) 2); 41 | KMArray arr = KMArray.cast(arrPtr); 42 | arr.add(SEED, KMByteBlob.exp()); 43 | arr.add(NONCE, KMByteBlob.exp()); 44 | return instance(arrPtr); 45 | } 46 | 47 | private static KMHmacSharingParameters proto(short ptr) { 48 | if (prototype == null) { 49 | prototype = new KMHmacSharingParameters(); 50 | } 51 | instanceTable[KM_HMAC_SHARING_PARAMETERS_OFFSET] = ptr; 52 | return prototype; 53 | } 54 | 55 | public static short instance() { 56 | short arrPtr = KMArray.instance((short) 2); 57 | return instance(arrPtr); 58 | } 59 | 60 | public static short instance(short vals) { 61 | short ptr = KMType.instance(HMAC_SHARING_PARAM_TYPE, (short) 2); 62 | if (KMArray.cast(vals).length() != 2) { 63 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 64 | } 65 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), vals); 66 | return ptr; 67 | } 68 | 69 | public static KMHmacSharingParameters cast(short ptr) { 70 | if (heap[ptr] != HMAC_SHARING_PARAM_TYPE) { 71 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 72 | } 73 | short arrPtr = Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)); 74 | if (heap[arrPtr] != ARRAY_TYPE) { 75 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 76 | } 77 | return proto(ptr); 78 | } 79 | 80 | public short getVals() { 81 | return Util.getShort(heap, (short) (instanceTable[KM_HMAC_SHARING_PARAMETERS_OFFSET] + TLV_HEADER_SIZE)); 82 | } 83 | 84 | public short length() { 85 | short arrPtr = getVals(); 86 | return KMArray.cast(arrPtr).length(); 87 | } 88 | 89 | public void setSeed(short vals) { 90 | KMByteBlob.cast(vals); 91 | short arrPtr = getVals(); 92 | KMArray.cast(arrPtr).add(SEED, vals); 93 | } 94 | 95 | public void setNonce(short vals) { 96 | KMByteBlob.cast(vals); 97 | short arrPtr = getVals(); 98 | KMArray.cast(arrPtr).add(NONCE, vals); 99 | } 100 | 101 | public short getNonce() { 102 | short arrPtr = getVals(); 103 | return KMArray.cast(arrPtr).get(NONCE); 104 | } 105 | 106 | public short getSeed() { 107 | short arrPtr = getVals(); 108 | return KMArray.cast(arrPtr).get(SEED); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMIntegerArrayTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMIntegerArrayTag represents UINT_REP and ULONG_REP tags specified in keymaster hal specs. 25 | * struct{byte TAG_TYPE; short length; struct{short UINT_TAG/ULONG_TAG; short tagKey; short arrPtr}, 26 | * where arrPtr is the pointer to KMArray of KMInteger instances. 27 | */ 28 | public class KMIntegerArrayTag extends KMTag { 29 | 30 | private static KMIntegerArrayTag prototype; 31 | 32 | private static final short[] tags = {USER_SECURE_ID}; 33 | 34 | private KMIntegerArrayTag() { 35 | } 36 | 37 | private static KMIntegerArrayTag proto(short ptr) { 38 | if (prototype == null) { 39 | prototype = new KMIntegerArrayTag(); 40 | } 41 | instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] = ptr; 42 | return prototype; 43 | } 44 | 45 | public static short exp(short tagType) { 46 | if (!validateTagType(tagType)) { 47 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 48 | } 49 | short arrPtr = KMArray.exp(KMInteger.exp()); 50 | short ptr = instance(TAG_TYPE, (short) 6); 51 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), tagType); 52 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), INVALID_TAG); 53 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 4), arrPtr); 54 | return ptr; 55 | } 56 | 57 | public static short instance(short tagType, short key) { 58 | if (!validateTagType(tagType)) { 59 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 60 | } 61 | if (!validateKey(key)) { 62 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 63 | } 64 | short arrPtr = KMArray.exp(); 65 | return instance(tagType, key, arrPtr); 66 | } 67 | 68 | public static short instance(short tagType, short key, short arrObj) { 69 | if (!validateTagType(tagType)) { 70 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 71 | } 72 | if (!validateKey(key)) { 73 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 74 | } 75 | if (heap[arrObj] != ARRAY_TYPE) { 76 | ISOException.throwIt(ISO7816.SW_DATA_INVALID); 77 | } 78 | short ptr = instance(TAG_TYPE, (short) 6); 79 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), tagType); 80 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2), key); 81 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE + 4), arrObj); 82 | return ptr; 83 | } 84 | 85 | public static KMIntegerArrayTag cast(short ptr) { 86 | if (heap[ptr] != TAG_TYPE) { 87 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 88 | } 89 | short tagType = Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)); 90 | if (!validateTagType(tagType)) { 91 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 92 | } 93 | return proto(ptr); 94 | } 95 | 96 | public short getTagType() { 97 | return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE)); 98 | } 99 | 100 | public short getKey() { 101 | return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 2)); 102 | } 103 | 104 | public short getValues() { 105 | return Util.getShort(heap, (short) (instanceTable[KM_INTEGER_ARRAY_TAG_OFFSET] + TLV_HEADER_SIZE + 4)); 106 | } 107 | 108 | public short length() { 109 | short ptr = getValues(); 110 | return KMArray.cast(ptr).length(); 111 | } 112 | 113 | public void add(short index, short val) { 114 | KMArray arr = KMArray.cast(getValues()); 115 | arr.add(index, val); 116 | } 117 | 118 | public short get(short index) { 119 | KMArray arr = KMArray.cast(getValues()); 120 | return arr.get(index); 121 | } 122 | 123 | private static boolean validateKey(short key) { 124 | short index = (short) tags.length; 125 | while (--index >= 0) { 126 | if (tags[index] == key) { 127 | return true; 128 | } 129 | } 130 | return false; 131 | } 132 | 133 | private static boolean validateTagType(short tagType) { 134 | return (tagType == ULONG_ARRAY_TAG) || (tagType == UINT_ARRAY_TAG); 135 | } 136 | 137 | public boolean contains(short tagValue) { 138 | short index = 0; 139 | while (index < length()) { 140 | if (KMInteger.compare(tagValue, get(index)) == 0) { 141 | return true; 142 | } 143 | index++; 144 | } 145 | return false; 146 | } 147 | 148 | public static boolean contains(short tagId, short tagValue, short params) { 149 | short tag = 150 | KMKeyParameters.findTag(KMType.UINT_ARRAY_TAG, tagId, params); 151 | if (tag != KMType.INVALID_VALUE) { 152 | short index = 0; 153 | tag = KMIntegerArrayTag.cast(tag).getValues(); 154 | while (index < KMArray.cast(tag).length()) { 155 | if (KMInteger.compare(tagValue, KMArray.cast(tag).get(index)) == 0) { 156 | return true; 157 | } 158 | index++; 159 | } 160 | } 161 | return false; 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMKeyCharacteristics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMKeyCharacteristics represents KeyCharacteristics structure from android keymaster hal 25 | * specifications. It corresponds to CBOR array type. struct{byte KEY_CHAR_TYPE; short length=2; 26 | * short arrayPtr} where arrayPtr is a pointer to ordered array with following elements: 27 | * {KMKeyParameters sofEnf; KMKeyParameters hwEnf} 28 | */ 29 | public class KMKeyCharacteristics extends KMType { 30 | 31 | public static final byte SOFTWARE_ENFORCED = 0x00; 32 | public static final byte HARDWARE_ENFORCED = 0x01; 33 | private static KMKeyCharacteristics prototype; 34 | 35 | private KMKeyCharacteristics() { 36 | } 37 | 38 | public static short exp() { 39 | short softEnf = KMKeyParameters.exp(); 40 | short hwEnf = KMKeyParameters.exp(); 41 | short arrPtr = KMArray.instance((short) 2); 42 | KMArray arr = KMArray.cast(arrPtr); 43 | arr.add(SOFTWARE_ENFORCED, softEnf); 44 | arr.add(HARDWARE_ENFORCED, hwEnf); 45 | return instance(arrPtr); 46 | } 47 | 48 | private static KMKeyCharacteristics proto(short ptr) { 49 | if (prototype == null) { 50 | prototype = new KMKeyCharacteristics(); 51 | } 52 | instanceTable[KM_KEY_CHARACTERISTICS_OFFSET] = ptr; 53 | return prototype; 54 | } 55 | 56 | public static short instance() { 57 | short arrPtr = KMArray.instance((short) 2); 58 | return instance(arrPtr); 59 | } 60 | 61 | public static short instance(short vals) { 62 | short ptr = KMType.instance(KEY_CHAR_TYPE, (short) 2); 63 | if (KMArray.cast(vals).length() != 2) { 64 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 65 | } 66 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), vals); 67 | return ptr; 68 | } 69 | 70 | public static KMKeyCharacteristics cast(short ptr) { 71 | if (heap[ptr] != KEY_CHAR_TYPE) { 72 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 73 | } 74 | short arrPtr = Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)); 75 | if (heap[arrPtr] != ARRAY_TYPE) { 76 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 77 | } 78 | return proto(ptr); 79 | } 80 | 81 | public short getVals() { 82 | return Util.getShort(heap, (short) (instanceTable[KM_KEY_CHARACTERISTICS_OFFSET] + TLV_HEADER_SIZE)); 83 | } 84 | 85 | public short length() { 86 | short arrPtr = getVals(); 87 | return KMArray.cast(arrPtr).length(); 88 | } 89 | 90 | public short getSoftwareEnforced() { 91 | short arrPtr = getVals(); 92 | return KMArray.cast(arrPtr).get(SOFTWARE_ENFORCED); 93 | } 94 | 95 | public short getHardwareEnforced() { 96 | short arrPtr = getVals(); 97 | return KMArray.cast(arrPtr).get(HARDWARE_ENFORCED); 98 | } 99 | 100 | public void setSoftwareEnforced(short ptr) { 101 | KMKeyParameters.cast(ptr); 102 | short arrPtr = getVals(); 103 | KMArray.cast(arrPtr).add(SOFTWARE_ENFORCED, ptr); 104 | } 105 | 106 | public void setHardwareEnforced(short ptr) { 107 | KMKeyParameters.cast(ptr); 108 | short arrPtr = getVals(); 109 | KMArray.cast(arrPtr).add(HARDWARE_ENFORCED, ptr); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMMasterKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | /** 19 | * KMMasterKey is a marker interface and the SE Provider has to implement this interface. Internally 20 | * Masterkey is stored as a Javacard AES key object, which will provide additional security. The 21 | * master key is maintained by the SEProvider. 22 | */ 23 | public interface KMMasterKey { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMOperation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | /** 19 | * KMOperation represents a persistent operation started by keymaster hal's beginOperation function. 20 | * This operation is persistent i.e. it will be stored in non volatile memory of se card. It will be 21 | * returned back to KMSEProvider for the reuse when the operation is finished. 22 | */ 23 | public interface KMOperation { 24 | 25 | // Used for cipher operations 26 | short update(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 27 | byte[] outputDataBuf, short outputDataStart); 28 | 29 | // Used for signature operations 30 | short update(byte[] inputDataBuf, short inputDataStart, short inputDataLength); 31 | 32 | // Used for finishing cipher operations. 33 | short finish(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 34 | byte[] outputDataBuf, short outputDataStart); 35 | 36 | // Used for finishing signing operations. 37 | short sign(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 38 | byte[] signBuf, short signStart); 39 | 40 | // Used for finishing verifying operations. 41 | boolean verify(byte[] inputDataBuf, short inputDataStart, short inputDataLength, 42 | byte[] signBuf, short signStart, short signLength); 43 | 44 | // Used for aborting the ongoing operations. 45 | void abort(); 46 | 47 | // Used for AES GCM cipher operation. 48 | void updateAAD(byte[] dataBuf, short dataStart, short dataLength); 49 | 50 | // Used for getting output size before finishing a AES GCM cipher operation. For encryption this will 51 | // include the auth tag which is appended at the end of the encrypted data. For decryption this will be 52 | // size of the decrypted data only. 53 | short getAESGCMOutputSize(short dataSize, short macLength); 54 | } 55 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMPKCS8Decoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | public interface KMPKCS8Decoder { 19 | 20 | /** 21 | * Decodes the PKCS8 encoded RSA Key and extracts the private and public key 22 | * 23 | * @param Instance of the PKCS8 encoded data 24 | * @return Instance of KMArray holding RSA public key, RSA private key and modulus. 25 | */ 26 | short decodeRsa(short blob); 27 | 28 | /** 29 | * Decodes the PKCS8 encoded EC Key and extracts the private and public key 30 | * 31 | * @param Instance of the PKCS8 encoded data. 32 | * @return Instance of KMArray holding EC public key and EC private key. 33 | */ 34 | short decodeEc(short blob); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMPreSharedKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | /** 19 | * KMPreSharedKey is a marker interface and the SE Provider has to implement this interface. 20 | * Internally Preshared key is stored as a Javacard HMac key object, which will provide additional 21 | * security. The pre-shared key is maintained by the SEProvider. 22 | */ 23 | public interface KMPreSharedKey { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.Util; 20 | 21 | /** 22 | * This class represents a tag as defined by keymaster hal specifications. It is composed of key 23 | * value pair. The key consists of short tag type e.g. KMType.ENUM and short tag key e.g. 24 | * KMType.ALGORITHM. The key is encoded as uint CBOR type with 4 bytes. This is followed by value 25 | * which can be any CBOR type based on key. struct{byte tag=KMType.TAG_TYPE, short length, value) 26 | * where value is subtype of KMTag i.e. struct{short tagType=one of tag types declared in KMType , 27 | * short tagKey=one of the tag keys declared in KMType, value} where value is one of the sub-types 28 | * of KMType. 29 | */ 30 | public class KMTag extends KMType { 31 | 32 | public static short getTagType(short ptr) { 33 | return Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)); 34 | } 35 | 36 | public static short getKey(short ptr) { 37 | return Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMUpgradable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" (short)0IS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.android.javacard.keymaster; 17 | 18 | import org.globalplatform.upgrade.Element; 19 | 20 | public interface KMUpgradable { 21 | 22 | void onSave(Element ele); 23 | 24 | void onRestore(Element ele, short oldVersion, short currentVersion); 25 | 26 | short getBackupPrimitiveByteCount(); 27 | 28 | short getBackupObjectCount(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Applet/src/com/android/javacard/keymaster/KMVerificationToken.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright(C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.javacard.keymaster; 18 | 19 | import javacard.framework.ISO7816; 20 | import javacard.framework.ISOException; 21 | import javacard.framework.Util; 22 | 23 | /** 24 | * KMVerificationToken represents VerificationToken structure from android keymaster hal 25 | * specifications. It corresponds to CBOR array type. struct{byte type=VERIFICATION_TOKEN_TYPE; 26 | * short length=2; short arrayPtr} where arrayPtr is a pointer to ordered array with following 27 | * elements: {KMInteger Challenge; KMInteger Timestamp; KMByteBlob PARAMETERS_VERIFIED; 28 | * SecurityLevel level; KMByteBlob Mac}. 29 | */ 30 | public class KMVerificationToken extends KMType { 31 | 32 | public static final byte CHALLENGE = 0x00; 33 | public static final byte TIMESTAMP = 0x01; 34 | public static final byte PARAMETERS_VERIFIED = 0x02; 35 | public static final byte SECURITY_LEVEL = 0x03; 36 | public static final byte MAC = 0x04; 37 | 38 | private static KMVerificationToken prototype; 39 | 40 | private KMVerificationToken() { 41 | } 42 | 43 | public static short exp() { 44 | short arrPtr = KMArray.instance((short) 5); 45 | KMArray arr = KMArray.cast(arrPtr); 46 | arr.add(CHALLENGE, KMInteger.exp()); 47 | arr.add(TIMESTAMP, KMInteger.exp()); 48 | //arr.add(PARAMETERS_VERIFIED, KMKeyParameters.exp()); 49 | arr.add(PARAMETERS_VERIFIED, KMByteBlob.exp()); 50 | arr.add(SECURITY_LEVEL, KMEnum.instance(KMType.HARDWARE_TYPE)); 51 | arr.add(MAC, KMByteBlob.exp()); 52 | return instance(arrPtr); 53 | } 54 | 55 | private static KMVerificationToken proto(short ptr) { 56 | if (prototype == null) { 57 | prototype = new KMVerificationToken(); 58 | } 59 | instanceTable[KM_VERIFICATION_TOKEN_OFFSET] = ptr; 60 | return prototype; 61 | } 62 | 63 | public static short instance() { 64 | short arrPtr = KMArray.instance((short) 5); 65 | KMArray arr = KMArray.cast(arrPtr); 66 | arr.add(CHALLENGE, KMInteger.uint_16((short) 0)); 67 | arr.add(TIMESTAMP, KMInteger.uint_16((short) 0)); 68 | arr.add(PARAMETERS_VERIFIED, KMByteBlob.instance((short) 0)); 69 | arr.add(SECURITY_LEVEL, KMEnum.instance(KMType.HARDWARE_TYPE, KMType.STRONGBOX)); 70 | arr.add(MAC, KMByteBlob.instance((short) 0)); 71 | return instance(arrPtr); 72 | } 73 | 74 | public static short instance(short vals) { 75 | KMArray arr = KMArray.cast(vals); 76 | if (arr.length() != 5) { 77 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); 78 | } 79 | short ptr = KMType.instance(VERIFICATION_TOKEN_TYPE, (short) 2); 80 | Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), vals); 81 | return ptr; 82 | } 83 | 84 | public static KMVerificationToken cast(short ptr) { 85 | if (heap[ptr] != VERIFICATION_TOKEN_TYPE) { 86 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 87 | } 88 | short arrPtr = Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE)); 89 | if (heap[arrPtr] != ARRAY_TYPE) { 90 | ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); 91 | } 92 | return proto(ptr); 93 | } 94 | 95 | public short getVals() { 96 | return Util.getShort(heap, (short) (instanceTable[KM_VERIFICATION_TOKEN_OFFSET] + TLV_HEADER_SIZE)); 97 | } 98 | 99 | public short length() { 100 | short arrPtr = getVals(); 101 | return KMArray.cast(arrPtr).length(); 102 | } 103 | 104 | public short getChallenge() { 105 | short arrPtr = getVals(); 106 | return KMArray.cast(arrPtr).get(CHALLENGE); 107 | } 108 | 109 | public void setChallenge(short vals) { 110 | KMInteger.cast(vals); 111 | short arrPtr = getVals(); 112 | KMArray.cast(arrPtr).add(CHALLENGE, vals); 113 | } 114 | 115 | public short getTimestamp() { 116 | short arrPtr = getVals(); 117 | return KMArray.cast(arrPtr).get(TIMESTAMP); 118 | } 119 | 120 | public void setTimestamp(short vals) { 121 | KMInteger.cast(vals); 122 | short arrPtr = getVals(); 123 | KMArray.cast(arrPtr).add(TIMESTAMP, vals); 124 | } 125 | 126 | public short getMac() { 127 | short arrPtr = getVals(); 128 | return KMArray.cast(arrPtr).get(MAC); 129 | } 130 | 131 | public void setMac(short vals) { 132 | KMByteBlob.cast(vals); 133 | short arrPtr = getVals(); 134 | KMArray.cast(arrPtr).add(MAC, vals); 135 | } 136 | 137 | public short getParametersVerified() { 138 | short arrPtr = getVals(); 139 | return KMArray.cast(arrPtr).get(PARAMETERS_VERIFIED); 140 | } 141 | 142 | public void setParametersVerified(short vals) { 143 | // KMKeyParameters.cast(vals); 144 | KMByteBlob.cast(vals); 145 | short arrPtr = getVals(); 146 | KMArray.cast(arrPtr).add(PARAMETERS_VERIFIED, vals); 147 | } 148 | 149 | public short getSecurityLevel() { 150 | short arrPtr = getVals(); 151 | return KMArray.cast(arrPtr).get(SECURITY_LEVEL); 152 | } 153 | 154 | public void setSecurityLevel(short vals) { 155 | KMEnum.cast(vals); 156 | short arrPtr = getVals(); 157 | KMArray.cast(arrPtr).add(SECURITY_LEVEL, vals); 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /HAL/README.md: -------------------------------------------------------------------------------- 1 | # JavaCardKeymaster HAL 2 | 3 | This directory contains the implementation of the Keymaster 4.1 4 | Hardware Abstraction Layer (HAL) interface, implemented as a Linux 5 | binary which runs as a standalone process mediating between Keystore 6 | (the Keymaster client) and the Applet running on a JavaCard secure 7 | element. 8 | -------------------------------------------------------------------------------- /HAL/keymaster/4.1/SocketTransport.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2020, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | #include "Transport.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | #define PORT 8080 29 | #define IPADDR "192.168.0.5" 30 | #define MAX_RECV_BUFFER_SIZE 2500 31 | 32 | namespace se_transport { 33 | 34 | bool SocketTransport::openConnection() { 35 | struct sockaddr_in serv_addr; 36 | 37 | if(mSocketStatus){ 38 | closeConnection(); 39 | } 40 | 41 | if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) 42 | { 43 | LOG(ERROR) << "Socket creation failed" << " Error: "<& output) { 69 | uint8_t buffer[MAX_RECV_BUFFER_SIZE]; 70 | int count = 1; 71 | bool sendStatus = false; 72 | while(!mSocketStatus && count++ < 5 ) { 73 | sleep(1); 74 | LOG(ERROR) << "Trying to open socket connection... count: " << count; 75 | openConnection(); 76 | } 77 | 78 | if(count >= 5) { 79 | LOG(ERROR) << "Failed to open socket connection"; 80 | closeConnection(); 81 | return false; 82 | } 83 | 84 | if (send(mSocket, inData, inLen , 0)< 0) { 85 | static int connectionResetCnt = 0; /* To avoid loop */ 86 | if (ECONNRESET == errno && connectionResetCnt == 0) { 87 | //Connection reset. Try open socket and then sendData. 88 | closeConnection(); 89 | connectionResetCnt++; 90 | sendStatus = sendData(inData, inLen, output); 91 | return sendStatus; 92 | } 93 | LOG(ERROR) << "Failed to send data over socket err: " << errno; 94 | connectionResetCnt = 0; 95 | return false; 96 | } 97 | ssize_t valRead = read( mSocket , buffer, MAX_RECV_BUFFER_SIZE); 98 | if(0 > valRead) { 99 | LOG(ERROR) << "Failed to read data from socket."; 100 | } 101 | for(size_t i = 0; i < valRead; i++) { 102 | output.push_back(buffer[i]); 103 | } 104 | return true; 105 | } 106 | 107 | bool SocketTransport::closeConnection() { 108 | if(mSocketStatus) 109 | close(mSocket); 110 | mSocketStatus = false; 111 | return true; 112 | } 113 | 114 | bool SocketTransport::isConnected() { 115 | return mSocketStatus; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /HAL/keymaster/4.1/android.hardware.keymaster@4.1-strongbox.service.rc: -------------------------------------------------------------------------------- 1 | service android.hardware.keymaster@4.1-strongbox.service /vendor/bin/hw/android.hardware.keymaster@4.1-strongbox.service 2 | interface android.hardware.keymaster@4.0::IKeymasterDevice strongbox 3 | interface android.hardware.keymaster@4.1::IKeymasterDevice strongbox 4 | class early_hal 5 | user system 6 | group system drmrpc 7 | -------------------------------------------------------------------------------- /HAL/keymaster/4.1/android.hardware.keymaster@4.1-strongbox.service.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.keymaster 4 | hwbinder 5 | @4.1::IKeymasterDevice/strongbox 6 | 7 | 8 | -------------------------------------------------------------------------------- /HAL/keymaster/4.1/android.hardware.strongbox_keystore.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /HAL/keymaster/4.1/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2020, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include "JavacardKeymaster4Device.h" 24 | 25 | int main() { 26 | ::android::hardware::configureRpcThreadpool(1, true); 27 | auto keymaster = new ::keymaster::V4_1::javacard::JavacardKeymaster4Device(); 28 | auto status = keymaster->registerAsService("strongbox"); 29 | if (status != android::OK) { 30 | LOG(FATAL) << "Could not register service for Javacard Keymaster 4.1 (" << status << ")"; 31 | return -1; 32 | } 33 | 34 | android::hardware::joinRpcThreadpool(); 35 | return -1; // Should never get here. 36 | } 37 | -------------------------------------------------------------------------------- /HAL/keymaster/Android.bp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020 The Android Open Source Project 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | 16 | 17 | cc_binary { 18 | name: "android.hardware.keymaster@4.1-strongbox.service", 19 | relative_install_path: "hw", 20 | vendor: true, 21 | init_rc: ["4.1/android.hardware.keymaster@4.1-strongbox.service.rc"], 22 | vintf_fragments: ["4.1/android.hardware.keymaster@4.1-strongbox.service.xml"], 23 | srcs: [ 24 | "4.1/service.cpp", 25 | "4.1/JavacardKeymaster4Device.cpp", 26 | "4.1/JavacardSoftKeymasterContext.cpp", 27 | "4.1/JavacardOperationContext.cpp", 28 | ], 29 | local_include_dirs: [ 30 | "include", 31 | ], 32 | shared_libs: [ 33 | "liblog", 34 | "libcutils", 35 | "libdl", 36 | "libbase", 37 | "libutils", 38 | "libhardware", 39 | "libhidlbase", 40 | "libsoftkeymasterdevice", 41 | "libsoft_attestation_cert", 42 | "libkeymaster_messages", 43 | "libkeymaster_portable", 44 | "libcppbor_external", 45 | "android.hardware.keymaster@4.1", 46 | "android.hardware.keymaster@4.0", 47 | "libjc_transport", 48 | "libjc_common", 49 | "libcrypto", 50 | "libbinder_ndk", 51 | "android.se.omapi-V1-ndk", 52 | ], 53 | required: [ 54 | "android.hardware.strongbox_keystore.xml", 55 | ], 56 | } 57 | 58 | cc_library { 59 | name: "libJavacardKeymaster41", 60 | srcs: [ 61 | "4.1/JavacardKeymaster4Device.cpp", 62 | "4.1/CborConverter.cpp", 63 | "4.1/JavacardSoftKeymasterContext.cpp", 64 | "4.1/JavacardOperationContext.cpp", 65 | "4.1/CommonUtils.cpp", 66 | ], 67 | local_include_dirs: [ 68 | "include", 69 | ], 70 | shared_libs: [ 71 | "liblog", 72 | "libcutils", 73 | "libdl", 74 | "libbase", 75 | "libutils", 76 | "libhardware", 77 | "libhidlbase", 78 | "libsoftkeymasterdevice", 79 | "libsoft_attestation_cert", 80 | "libkeymaster_messages", 81 | "libkeymaster_portable", 82 | "libcppbor_external", 83 | "android.hardware.keymaster@4.1", 84 | "android.hardware.keymaster@4.0", 85 | "libjc_transport", 86 | "libcrypto", 87 | "libbinder_ndk", 88 | "android.se.omapi-V1-ndk", 89 | ], 90 | } 91 | 92 | cc_library { 93 | name: "libjc_transport", 94 | vendor_available: true, 95 | 96 | srcs: [ 97 | "4.1/SocketTransport.cpp", 98 | "4.1/OmapiTransport.cpp" 99 | ], 100 | export_include_dirs: [ 101 | "include" 102 | ], 103 | shared_libs: [ 104 | "libbinder", 105 | "libbase", 106 | "liblog", 107 | "libbinder_ndk", 108 | "android.se.omapi-V1-ndk", 109 | ], 110 | } 111 | 112 | cc_library { 113 | name: "libjc_common", 114 | vendor_available: true, 115 | srcs: [ 116 | "4.1/CommonUtils.cpp", 117 | "4.1/CborConverter.cpp", 118 | ], 119 | local_include_dirs: [ 120 | "include", 121 | ], 122 | export_include_dirs: [ 123 | "include" 124 | ], 125 | shared_libs: [ 126 | "liblog", 127 | "libcutils", 128 | "libdl", 129 | "libbase", 130 | "libutils", 131 | "libhardware", 132 | "libhidlbase", 133 | "libsoftkeymasterdevice", 134 | "libsoft_attestation_cert", 135 | "libkeymaster_messages", 136 | "libkeymaster_portable", 137 | "libcppbor_external", 138 | "android.hardware.keymaster@4.1", 139 | "android.hardware.keymaster@4.0", 140 | "libcrypto", 141 | ], 142 | } 143 | 144 | prebuilt_etc { 145 | name: "android.hardware.strongbox_keystore.xml", 146 | sub_dir: "permissions", 147 | vendor: true, 148 | src: "4.1/android.hardware.strongbox_keystore.xml", 149 | } 150 | -------------------------------------------------------------------------------- /HAL/keymaster/include/CommonUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2020, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace keymaster::V4_1::javacard { 25 | using ::android::hardware::hidl_vec; 26 | using ::android::hardware::keymaster::V4_0::ErrorCode; 27 | using ::android::hardware::keymaster::V4_0::Tag; 28 | using ::android::hardware::keymaster::V4_0::KeyFormat; 29 | using ::android::hardware::keymaster::V4_0::KeyParameter; 30 | using ::android::hardware::keymaster::V4_0::KeyPurpose; 31 | using ::android::hardware::keymaster::V4_0::EcCurve; 32 | 33 | inline ErrorCode legacy_enum_conversion(const keymaster_error_t value) { 34 | return static_cast(value); 35 | } 36 | 37 | inline keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { 38 | return static_cast(value); 39 | } 40 | 41 | inline keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { 42 | return static_cast(value); 43 | } 44 | 45 | inline keymaster_tag_t legacy_enum_conversion(const Tag value) { 46 | return keymaster_tag_t(value); 47 | } 48 | 49 | inline Tag legacy_enum_conversion(const keymaster_tag_t value) { 50 | return Tag(value); 51 | } 52 | 53 | inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { 54 | return keymaster_tag_get_type(tag); 55 | } 56 | 57 | inline hidl_vec kmBuffer2hidlVec(const ::keymaster::Buffer& buf) { 58 | return hidl_vec(buf.begin(), buf.end()); 59 | } 60 | 61 | inline void blob2Vec(const uint8_t *from, size_t size, std::vector& to) { 62 | for(int i = 0; i < size; ++i) { 63 | to.push_back(from[i]); 64 | } 65 | } 66 | 67 | inline hidl_vec kmBlob2hidlVec(const keymaster_blob_t& blob) { 68 | return hidl_vec(blob.data, blob.data+blob.data_length); 69 | } 70 | 71 | keymaster_key_param_set_t hidlKeyParams2Km(const hidl_vec& keyParams); 72 | 73 | hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set); 74 | 75 | ErrorCode rsaRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& privateExp, std::vector& 76 | pubModulus); 77 | 78 | ErrorCode ecRawKeyFromPKCS8(const std::vector& pkcs8Blob, std::vector& secret, std::vector& 79 | publicKey, EcCurve& eccurve); 80 | 81 | ErrorCode getCertificateChain(std::vector& chainBuffer, std::vector>& certChain); 82 | 83 | uint32_t GetVendorPatchlevel(); 84 | 85 | class KmParamSet : public keymaster_key_param_set_t { 86 | public: 87 | explicit KmParamSet(const hidl_vec& keyParams) 88 | : keymaster_key_param_set_t(hidlKeyParams2Km(keyParams)) {} 89 | KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { 90 | other.length = 0; 91 | other.params = nullptr; 92 | } 93 | KmParamSet(const KmParamSet&) = delete; 94 | ~KmParamSet() { delete[] params; } 95 | }; 96 | 97 | } // namespace javacard::V4_1::keymaster 98 | -------------------------------------------------------------------------------- /HAL/keymaster/include/JavacardSoftKeymasterContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace keymaster { 23 | 24 | class SoftKeymasterKeyRegistrations; 25 | class Keymaster0Engine; 26 | class Keymaster1Engine; 27 | class Key; 28 | 29 | /** 30 | * SoftKeymasterContext provides the context for a non-secure implementation of AndroidKeymaster. 31 | */ 32 | class JavaCardSoftKeymasterContext : public keymaster::PureSoftKeymasterContext { 33 | keymaster_error_t LoadKey(const keymaster_algorithm_t algorithm, KeymasterKeyBlob&& key_material, 34 | AuthorizationSet&& hw_enforced, 35 | AuthorizationSet&& sw_enforced, 36 | UniquePtr* key) const; 37 | public: 38 | // Security level must only be used for testing. 39 | explicit JavaCardSoftKeymasterContext( 40 | keymaster_security_level_t security_level = KM_SECURITY_LEVEL_SOFTWARE); 41 | ~JavaCardSoftKeymasterContext() override; 42 | 43 | keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob, 44 | const AuthorizationSet& additional_params, 45 | UniquePtr* key) const override; 46 | 47 | }; 48 | 49 | } // namespace keymaster 50 | 51 | -------------------------------------------------------------------------------- /HAL/keymaster/include/Transport.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2020, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | 31 | namespace se_transport { 32 | 33 | /** 34 | * ITransport is an abstract interface with a set of virtual methods that allow communication between the keymaster 35 | * HAL and the secure element. 36 | */ 37 | class ITransport { 38 | public: 39 | virtual ~ITransport(){} 40 | 41 | /** 42 | * Opens connection. 43 | */ 44 | virtual bool openConnection() = 0; 45 | /** 46 | * Send data over communication channel and receives data back from the remote end. 47 | */ 48 | virtual bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) = 0; 49 | /** 50 | * Closes the connection. 51 | */ 52 | virtual bool closeConnection() = 0; 53 | /** 54 | * Returns the state of the connection status. Returns true if the connection is active, false if connection is 55 | * broken. 56 | */ 57 | virtual bool isConnected() = 0; 58 | 59 | }; 60 | 61 | /** 62 | * OmapiTransport is derived from ITransport. This class gets the OMAPI service binder instance and uses IPC to 63 | * communicate with OMAPI service. OMAPI inturn communicates with hardware via ISecureElement. 64 | */ 65 | class OmapiTransport : public ITransport { 66 | 67 | public: 68 | OmapiTransport() : omapiSeService(nullptr), eSEReader(nullptr), session(nullptr), 69 | channel(nullptr) { 70 | } 71 | /** 72 | * Gets the binder instance of ISEService, gets the reader corresponding to secure element, establishes a session 73 | * and opens a basic channel. 74 | */ 75 | bool openConnection() override; 76 | /** 77 | * Transmists the data over the opened basic channel and receives the data back. 78 | */ 79 | bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; 80 | 81 | /** 82 | * Closes the connection. 83 | */ 84 | bool closeConnection() override; 85 | /** 86 | * Returns the state of the connection status. Returns true if the connection is active, false if connection is 87 | * broken. 88 | */ 89 | bool isConnected() override; 90 | 91 | private: 92 | std::shared_ptr omapiSeService; 93 | std::shared_ptr eSEReader; 94 | std::shared_ptr session; 95 | std::shared_ptr channel; 96 | std::map> 97 | mVSReaders; 98 | // Private functions 99 | bool initialize(); 100 | bool internalTransmitApdu(std::vector apdu, std::vector& transmitResponse); 101 | }; 102 | 103 | class SocketTransport : public ITransport { 104 | 105 | public: 106 | SocketTransport() : mSocket(-1), mSocketStatus(false){ 107 | } 108 | /** 109 | * Creates a socket instance and connects to the provided server IP and port. 110 | */ 111 | bool openConnection() override; 112 | /** 113 | * Sends data over socket and receives data back. 114 | */ 115 | bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) override; 116 | 117 | /** 118 | * Closes the connection. 119 | */ 120 | bool closeConnection() override; 121 | /** 122 | * Returns the state of the connection status. Returns true if the connection is active, false if connection is 123 | * broken. 124 | */ 125 | bool isConnected() override; 126 | private: 127 | /** 128 | * Socket instance. 129 | */ 130 | int mSocket; 131 | bool mSocketStatus; 132 | }; 133 | 134 | } 135 | -------------------------------------------------------------------------------- /HAL/keymaster/include/TransportFactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2020, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include "Transport.h" 20 | 21 | namespace se_transport { 22 | 23 | /** 24 | * TransportFactory class decides which transport mechanism to be used to send data to secure element. In case of 25 | * emulator the communication channel is socket and in case of device the communication channel is via OMAPI. 26 | */ 27 | class TransportFactory { 28 | public: 29 | TransportFactory(bool isEmulator) { 30 | if (!isEmulator) 31 | mTransport = std::unique_ptr(new OmapiTransport()); 32 | else 33 | mTransport = std::unique_ptr(new SocketTransport()); 34 | } 35 | 36 | ~TransportFactory() {} 37 | 38 | /** 39 | * Establishes a communication channel with the secure element. 40 | */ 41 | inline bool openConnection() { 42 | return mTransport->openConnection(); 43 | } 44 | 45 | /** 46 | * Sends the data to the secure element and also receives back the data. 47 | * This is a blocking call. 48 | */ 49 | inline bool sendData(const uint8_t* inData, const size_t inLen, std::vector& output) { 50 | return mTransport->sendData(inData, inLen, output); 51 | } 52 | 53 | /** 54 | * Close the connection. 55 | */ 56 | inline bool closeConnection() { 57 | return mTransport->closeConnection(); 58 | } 59 | 60 | /** 61 | * Returns the connection status of the communication channel. 62 | */ 63 | inline bool isConnected() { 64 | return mTransport->isConnected(); 65 | } 66 | 67 | private: 68 | /** 69 | * Holds the instance of either OmapiTransport class or SocketTransport class. 70 | */ 71 | std::unique_ptr mTransport; 72 | 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /ProvisioningTool/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | SRC_DIR = src 3 | # source files for construct_apdus 4 | CONSTRUCT_APDUS_SRC = $(SRC_DIR)/construct_apdus.cpp \ 5 | $(SRC_DIR)/cppbor.cpp \ 6 | $(SRC_DIR)/cppbor_parse.cpp \ 7 | $(SRC_DIR)/utils.cpp \ 8 | 9 | CONSTRUCT_APDUS_OBJFILES = $(CONSTRUCT_APDUS_SRC:.cpp=.o) 10 | CONSTRUCT_APDUS_BIN = construct_apdus 11 | 12 | # source files for provision 13 | PROVISION_SRC = $(SRC_DIR)/provision.cpp \ 14 | $(SRC_DIR)/socket.cpp \ 15 | $(SRC_DIR)/cppbor.cpp \ 16 | $(SRC_DIR)/cppbor_parse.cpp \ 17 | $(SRC_DIR)/utils.cpp \ 18 | 19 | PROVISION_OBJFILES = $(PROVISION_SRC:.cpp=.o) 20 | PROVISION_BIN = provision 21 | 22 | 23 | ifeq ($(OS),Windows_NT) 24 | uname_S := Windows 25 | else 26 | uname_S := $(shell uname -s) 27 | endif 28 | 29 | ifeq ($(uname_S), Windows) 30 | PLATFORM = -D__WIN32__ 31 | endif 32 | ifeq ($(uname_S), Linux) 33 | PLATFORM = -D__LINUX__ 34 | endif 35 | 36 | DEBUG = -g 37 | CXXFLAGS = $(DEBUG) $(PLATFORM) -Wall -std=c++2a 38 | CFLAGS = $(CXXFLAGS) -Iinclude 39 | LDFLAGS = -Llib/ 40 | LIB_JSON = -ljsoncpp 41 | LIB_CRYPTO = -lcrypto 42 | LDLIBS = $(LIB_JSON) $(LIB_CRYPTO) 43 | 44 | all: $(CONSTRUCT_APDUS_BIN) $(PROVISION_BIN) 45 | 46 | $(CONSTRUCT_APDUS_BIN): $(CONSTRUCT_APDUS_OBJFILES) 47 | $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) 48 | 49 | $(PROVISION_BIN): $(PROVISION_OBJFILES) 50 | $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) 51 | 52 | %.o: %.cpp 53 | $(CC) $(CFLAGS) -c -o $@ $^ 54 | 55 | 56 | .PHONY: clean 57 | clean: 58 | rm -f $(CONSTRUCT_APDUS_OBJFILES) $(CONSTRUCT_APDUS_BIN) $(PROVISION_OBJFILES) $(PROVISION_BIN) 59 | -------------------------------------------------------------------------------- /ProvisioningTool/README.md: -------------------------------------------------------------------------------- 1 | # Provisioning tool 2 | This directory contains two tools. One which constructs the apdus and dumps them to a json file, Other which gets the apuds from the json file and provision them into a secure element simulator. Both the tools can be compiled and executed from a Linux machine. 3 | 4 | #### Build instruction 5 | The default target generates both the executables. One construct_apdus and the other provision. 6 | $ make 7 | Individual targets can also be selected as shown below 8 | $ make construct_apdus 9 | $ make provision 10 | Make clean will remove all the object files and binaries 11 | $ make clean 12 | 13 | #### Environment setup 14 | Before executing the binaries make sure LD_LIBRARY_PATH is set 15 | export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH 16 | 17 | #### Sample resources for quick testing 18 | Two sample json files are located in this directory with names 19 | [sample_json_cf.txt](sample_json_cf.txt) and and [sample_json_gf.txt](sample_json_gf.txt) 20 | for your reference. Use sample_json_cf.txt for cuttlefish target and use 21 | sample_json_gf.txt for goldfish target. Also the required certificates and 22 | keys can be found in [test_resources](test_resources) directory. Copy the 23 | certificates and the key into the emulator/device filesystem in their respective 24 | paths mentioned in the sample json file. 25 | 26 | #### Usage for construct_apdus 27 |
28 | Usage: construct_apdus options
29 | Valid options are:
30 | -h, --help                        show the help message and exit.
31 | -v, --km_version version Version of the keymaster ((4.0 or 4.1 for respective keymaster version))
32 | -i, --input  jsonFile	 Input json file
33 | -o, --output jsonFile 	 Output json file
34 | 
35 | 36 | #### Usage for provision 37 |
38 | Usage: provision options
39 | Valid options are:
40 | -h, --help                      show the help message and exit.
41 | -v, --km_version version  Version of the keymaster ((4.0 or 4.1 for respective keymaster version))
42 | -i, --input  jsonFile 	  Input json file 
43 | -s, --provision_stautus   Prints the current provision status.
44 | -l, --lock_provision      Locks the provision state.
45 | 
46 | -------------------------------------------------------------------------------- /ProvisioningTool/include/UniquePtr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include // for size_t 20 | 21 | #include 22 | 23 | // Default deleter for pointer types. 24 | template struct DefaultDelete { 25 | enum { type_must_be_complete = sizeof(T) }; 26 | DefaultDelete() {} 27 | void operator()(T* p) const { delete p; } 28 | }; 29 | 30 | // Default deleter for array types. 31 | template struct DefaultDelete { 32 | enum { type_must_be_complete = sizeof(T) }; 33 | void operator()(T* p) const { delete[] p; } 34 | }; 35 | 36 | template > 37 | using UniquePtr = std::unique_ptr; 38 | 39 | 40 | -------------------------------------------------------------------------------- /ProvisioningTool/include/constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2021, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "UniquePtr.h" 25 | 26 | #define SUCCESS 0 27 | #define FAILURE 1 28 | #define KEYMASTER_VERSION_4_1 4.1 29 | #define KEYMASTER_VERSION_4_0 4 30 | #define P1_40 0x40 31 | #define P1_50 0x50 32 | #define APDU_CLS 0x80 33 | #define APDU_P1 P1_40 34 | #define APDU_P2 0x00 35 | #define INS_BEGIN_KM_CMD 0x00 36 | #define APDU_RESP_STATUS_OK 0x9000 37 | #define SE_POWER_RESET_STATUS_FLAG ( 1 << 30) 38 | 39 | 40 | 41 | template 42 | struct OpenSslObjectDeleter { 43 | void operator()(T* p) { FreeFunc(p); } 44 | }; 45 | 46 | #define DEFINE_OPENSSL_OBJECT_POINTER(name) \ 47 | typedef OpenSslObjectDeleter name##_Delete; \ 48 | typedef UniquePtr name##_Ptr; 49 | 50 | DEFINE_OPENSSL_OBJECT_POINTER(EC_KEY) 51 | DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY) 52 | DEFINE_OPENSSL_OBJECT_POINTER(X509) 53 | 54 | // OEM Lock / Unlock Verification message 55 | constexpr char kOemProvisioningLock[] = "OEM Provisioning Lock"; 56 | constexpr char kEnableRma[] = "Enable RMA"; 57 | 58 | // Tags 59 | constexpr uint64_t kTagAlgorithm = 268435458u; 60 | constexpr uint64_t kTagDigest = 536870917u; 61 | constexpr uint64_t kTagCurve = 268435466u; 62 | constexpr uint64_t kTagPurpose = 536870913u; 63 | constexpr uint64_t kTagAttestationIdBrand = 2415919814u; 64 | constexpr uint64_t kTagAttestationIdDevice = 2415919815u; 65 | constexpr uint64_t kTagAttestationIdProduct = 2415919816u; 66 | constexpr uint64_t kTagAttestationIdSerial = 2415919817u; 67 | constexpr uint64_t kTagAttestationIdImei = 2415919818u; 68 | constexpr uint64_t kTagAttestationIdMeid = 2415919819u; 69 | constexpr uint64_t kTagAttestationIdManufacturer = 2415919820u; 70 | constexpr uint64_t kTagAttestationIdModel = 2415919821u; 71 | 72 | // Values 73 | constexpr uint64_t kCurveP256 = 1; 74 | constexpr uint64_t kAlgorithmEc = 3; 75 | constexpr uint64_t kDigestSha256 = 4; 76 | constexpr uint64_t kPurposeAttest = 0x7F; 77 | constexpr uint64_t kPurposeVerify = 3; 78 | constexpr uint64_t kKeyFormatRaw = 3; 79 | 80 | // json keys 81 | constexpr char kAttestKey[] = "attest_key"; 82 | constexpr char kAttestCertChain[] = "attest_cert_chain"; 83 | constexpr char kSharedSecret[] = "shared_secret"; 84 | constexpr char kBootParams[] = "boot_params"; 85 | constexpr char kAttestationIds[] = "attestation_ids"; 86 | constexpr char kDeviceUniqueKey[] = "device_unique_key"; 87 | constexpr char kAdditionalCertChain[] = "additional_cert_chain"; 88 | constexpr char kProvisionStatus[] = "provision_status"; 89 | constexpr char kLockProvision[] = "lock_provision"; 90 | constexpr char kOEMRootKey[] = "oem_root_key"; 91 | constexpr char kSeFactoryProvisionLock[] = "se_factory_lock"; 92 | constexpr char kUnLockProvision[] = "unlock_provision"; 93 | 94 | // Instruction constatnts 95 | constexpr int kAttestationKeyCmd = INS_BEGIN_KM_CMD + 1; 96 | constexpr int kAttestCertDataCmd = INS_BEGIN_KM_CMD + 2; 97 | constexpr int kAttestationIdsCmd = INS_BEGIN_KM_CMD + 3; 98 | constexpr int kPresharedSecretCmd = INS_BEGIN_KM_CMD + 4; 99 | constexpr int kBootParamsCmd = INS_BEGIN_KM_CMD + 5; 100 | constexpr int kOemLockProvisionCmd = INS_BEGIN_KM_CMD + 6; 101 | constexpr int kGetProvisionStatusCmd = INS_BEGIN_KM_CMD + 7; 102 | constexpr int kSetVersionPatchLevelCmd = INS_BEGIN_KM_CMD + 8; 103 | constexpr int kSeFactoryLockCmd = INS_BEGIN_KM_CMD + 10; 104 | constexpr int kOemRootPublicKeyCmd = INS_BEGIN_KM_CMD + 11; 105 | constexpr int kOemUnLockProvisionCmd = INS_BEGIN_KM_CMD + 12; 106 | 107 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/assertions.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2010 Baptiste Lepilleur 2 | // Distributed under MIT license, or public domain if desired and 3 | // recognized in your jurisdiction. 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 | 6 | #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED 7 | #define CPPTL_JSON_ASSERTIONS_H_INCLUDED 8 | 9 | #include 10 | #include 11 | 12 | #if !defined(JSON_IS_AMALGAMATION) 13 | #include "config.h" 14 | #endif // if !defined(JSON_IS_AMALGAMATION) 15 | 16 | /** It should not be possible for a maliciously designed file to 17 | * cause an abort() or seg-fault, so these macros are used only 18 | * for pre-condition violations and internal logic errors. 19 | */ 20 | #if JSON_USE_EXCEPTION 21 | 22 | // @todo <= add detail about condition in exception 23 | # define JSON_ASSERT(condition) \ 24 | {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} 25 | 26 | # define JSON_FAIL_MESSAGE(message) \ 27 | { \ 28 | std::ostringstream oss; oss << message; \ 29 | Json::throwLogicError(oss.str()); \ 30 | abort(); \ 31 | } 32 | 33 | #else // JSON_USE_EXCEPTION 34 | 35 | # define JSON_ASSERT(condition) assert(condition) 36 | 37 | // The call to assert() will show the failure message in debug builds. In 38 | // release builds we abort, for a core-dump or debugger. 39 | # define JSON_FAIL_MESSAGE(message) \ 40 | { \ 41 | std::ostringstream oss; oss << message; \ 42 | assert(false && oss.str().c_str()); \ 43 | abort(); \ 44 | } 45 | 46 | 47 | #endif 48 | 49 | #define JSON_ASSERT_MESSAGE(condition, message) \ 50 | if (!(condition)) { \ 51 | JSON_FAIL_MESSAGE(message); \ 52 | } 53 | 54 | #endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED 55 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/autolink.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2010 Baptiste Lepilleur 2 | // Distributed under MIT license, or public domain if desired and 3 | // recognized in your jurisdiction. 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 | 6 | #ifndef JSON_AUTOLINK_H_INCLUDED 7 | #define JSON_AUTOLINK_H_INCLUDED 8 | 9 | #include "config.h" 10 | 11 | #ifdef JSON_IN_CPPTL 12 | #include 13 | #endif 14 | 15 | #if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && \ 16 | !defined(JSON_IN_CPPTL) 17 | #define CPPTL_AUTOLINK_NAME "json" 18 | #undef CPPTL_AUTOLINK_DLL 19 | #ifdef JSON_DLL 20 | #define CPPTL_AUTOLINK_DLL 21 | #endif 22 | #include "autolink.h" 23 | #endif 24 | 25 | #endif // JSON_AUTOLINK_H_INCLUDED 26 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/config.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2010 Baptiste Lepilleur 2 | // Distributed under MIT license, or public domain if desired and 3 | // recognized in your jurisdiction. 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 | 6 | #ifndef JSON_CONFIG_H_INCLUDED 7 | #define JSON_CONFIG_H_INCLUDED 8 | 9 | /// If defined, indicates that json library is embedded in CppTL library. 10 | //# define JSON_IN_CPPTL 1 11 | 12 | /// If defined, indicates that json may leverage CppTL library 13 | //# define JSON_USE_CPPTL 1 14 | /// If defined, indicates that cpptl vector based map should be used instead of 15 | /// std::map 16 | /// as Value container. 17 | //# define JSON_USE_CPPTL_SMALLMAP 1 18 | 19 | // If non-zero, the library uses exceptions to report bad input instead of C 20 | // assertion macros. The default is to use exceptions. 21 | #ifndef JSON_USE_EXCEPTION 22 | #define JSON_USE_EXCEPTION 1 23 | #endif 24 | 25 | /// If defined, indicates that the source file is amalgated 26 | /// to prevent private header inclusion. 27 | /// Remarks: it is automatically defined in the generated amalgated header. 28 | // #define JSON_IS_AMALGAMATION 29 | 30 | #ifdef JSON_IN_CPPTL 31 | #include 32 | #ifndef JSON_USE_CPPTL 33 | #define JSON_USE_CPPTL 1 34 | #endif 35 | #endif 36 | 37 | #ifdef JSON_IN_CPPTL 38 | #define JSON_API CPPTL_API 39 | #elif defined(JSON_DLL_BUILD) 40 | #if defined(_MSC_VER) 41 | #define JSON_API __declspec(dllexport) 42 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 43 | #endif // if defined(_MSC_VER) 44 | #elif defined(JSON_DLL) 45 | #if defined(_MSC_VER) 46 | #define JSON_API __declspec(dllimport) 47 | #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING 48 | #endif // if defined(_MSC_VER) 49 | #endif // ifdef JSON_IN_CPPTL 50 | #if !defined(JSON_API) 51 | #define JSON_API 52 | #endif 53 | 54 | #if !defined(JSON_HAS_UNIQUE_PTR) 55 | #if __cplusplus >= 201103L 56 | #define JSON_HAS_UNIQUE_PTR (1) 57 | #elif _MSC_VER >= 1600 58 | #define JSON_HAS_UNIQUE_PTR (1) 59 | #else 60 | #define JSON_HAS_UNIQUE_PTR (0) 61 | #endif 62 | #endif 63 | 64 | // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for 65 | // integer 66 | // Storages, and 64 bits integer support is disabled. 67 | // #define JSON_NO_INT64 1 68 | 69 | #if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6 70 | // Microsoft Visual Studio 6 only support conversion from __int64 to double 71 | // (no conversion from unsigned __int64). 72 | #define JSON_USE_INT64_DOUBLE_CONVERSION 1 73 | // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' 74 | // characters in the debug information) 75 | // All projects I've ever seen with VS6 were using this globally (not bothering 76 | // with pragma push/pop). 77 | #pragma warning(disable : 4786) 78 | #endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 79 | 80 | #if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 81 | /// Indicates that the following function is deprecated. 82 | #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) 83 | #elif defined(__clang__) && defined(__has_feature) 84 | #if __has_feature(attribute_deprecated_with_message) 85 | #define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 86 | #endif 87 | #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) 88 | #define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) 89 | #elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 90 | #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) 91 | #endif 92 | 93 | #if !defined(JSONCPP_DEPRECATED) 94 | #define JSONCPP_DEPRECATED(message) 95 | #endif // if !defined(JSONCPP_DEPRECATED) 96 | 97 | namespace Json { 98 | typedef int Int; 99 | typedef unsigned int UInt; 100 | #if defined(JSON_NO_INT64) 101 | typedef int LargestInt; 102 | typedef unsigned int LargestUInt; 103 | #undef JSON_HAS_INT64 104 | #else // if defined(JSON_NO_INT64) 105 | // For Microsoft Visual use specific types as long long is not supported 106 | #if defined(_MSC_VER) // Microsoft Visual Studio 107 | typedef __int64 Int64; 108 | typedef unsigned __int64 UInt64; 109 | #else // if defined(_MSC_VER) // Other platforms, use long long 110 | typedef long long int Int64; 111 | typedef unsigned long long int UInt64; 112 | #endif // if defined(_MSC_VER) 113 | typedef Int64 LargestInt; 114 | typedef UInt64 LargestUInt; 115 | #define JSON_HAS_INT64 116 | #endif // if defined(JSON_NO_INT64) 117 | } // end namespace Json 118 | 119 | #endif // JSON_CONFIG_H_INCLUDED 120 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/features.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2010 Baptiste Lepilleur 2 | // Distributed under MIT license, or public domain if desired and 3 | // recognized in your jurisdiction. 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 | 6 | #ifndef CPPTL_JSON_FEATURES_H_INCLUDED 7 | #define CPPTL_JSON_FEATURES_H_INCLUDED 8 | 9 | #if !defined(JSON_IS_AMALGAMATION) 10 | #include "forwards.h" 11 | #endif // if !defined(JSON_IS_AMALGAMATION) 12 | 13 | namespace Json { 14 | 15 | /** \brief Configuration passed to reader and writer. 16 | * This configuration object can be used to force the Reader or Writer 17 | * to behave in a standard conforming way. 18 | */ 19 | class JSON_API Features { 20 | public: 21 | /** \brief A configuration that allows all features and assumes all strings 22 | * are UTF-8. 23 | * - C & C++ comments are allowed 24 | * - Root object can be any JSON value 25 | * - Assumes Value strings are encoded in UTF-8 26 | */ 27 | static Features all(); 28 | 29 | /** \brief A configuration that is strictly compatible with the JSON 30 | * specification. 31 | * - Comments are forbidden. 32 | * - Root object must be either an array or an object value. 33 | * - Assumes Value strings are encoded in UTF-8 34 | */ 35 | static Features strictMode(); 36 | 37 | /** \brief Initialize the configuration like JsonConfig::allFeatures; 38 | */ 39 | Features(); 40 | 41 | /// \c true if comments are allowed. Default: \c true. 42 | bool allowComments_; 43 | 44 | /// \c true if root must be either an array or an object value. Default: \c 45 | /// false. 46 | bool strictRoot_; 47 | }; 48 | 49 | } // namespace Json 50 | 51 | #endif // CPPTL_JSON_FEATURES_H_INCLUDED 52 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/forwards.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2010 Baptiste Lepilleur 2 | // Distributed under MIT license, or public domain if desired and 3 | // recognized in your jurisdiction. 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 | 6 | #ifndef JSON_FORWARDS_H_INCLUDED 7 | #define JSON_FORWARDS_H_INCLUDED 8 | 9 | #if !defined(JSON_IS_AMALGAMATION) 10 | #include "config.h" 11 | #endif // if !defined(JSON_IS_AMALGAMATION) 12 | 13 | namespace Json { 14 | 15 | // writer.h 16 | class FastWriter; 17 | class StyledWriter; 18 | 19 | // reader.h 20 | class Reader; 21 | 22 | // features.h 23 | class Features; 24 | 25 | // value.h 26 | typedef unsigned int ArrayIndex; 27 | class StaticString; 28 | class Path; 29 | class PathArgument; 30 | class Value; 31 | class ValueIteratorBase; 32 | class ValueIterator; 33 | class ValueConstIterator; 34 | 35 | } // namespace Json 36 | 37 | #endif // JSON_FORWARDS_H_INCLUDED 38 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/json.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2010 Baptiste Lepilleur 2 | // Distributed under MIT license, or public domain if desired and 3 | // recognized in your jurisdiction. 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 | 6 | #ifndef JSON_JSON_H_INCLUDED 7 | #define JSON_JSON_H_INCLUDED 8 | 9 | #include "autolink.h" 10 | #include "value.h" 11 | #include "reader.h" 12 | #include "writer.h" 13 | #include "features.h" 14 | 15 | #endif // JSON_JSON_H_INCLUDED 16 | -------------------------------------------------------------------------------- /ProvisioningTool/include/json/version.h: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This file (and "version") is generated by CMake. 2 | // Run CMake configure step to update it. 3 | #ifndef JSON_VERSION_H_INCLUDED 4 | # define JSON_VERSION_H_INCLUDED 5 | 6 | # define JSONCPP_VERSION_STRING "0.10.7" 7 | # define JSONCPP_VERSION_MAJOR 0 8 | # define JSONCPP_VERSION_MINOR 10 9 | # define JSONCPP_VERSION_PATCH 7 10 | # define JSONCPP_VERSION_QUALIFIER 11 | # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) 12 | 13 | #endif // JSON_VERSION_H_INCLUDED 14 | -------------------------------------------------------------------------------- /ProvisioningTool/include/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2021, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | class SocketTransport 20 | { 21 | public: 22 | static inline std::shared_ptr getInstance() { 23 | static std::shared_ptr socket = std::shared_ptr(new SocketTransport()); 24 | return socket; 25 | } 26 | 27 | ~SocketTransport(); 28 | /** 29 | * Creates a socket instance and connects to the provided server IP and port. 30 | */ 31 | bool openConnection(); 32 | /** 33 | * Sends data over socket and receives data back. 34 | */ 35 | bool sendData(const std::vector &inData, std::vector &output); 36 | /** 37 | * Closes the connection. 38 | */ 39 | bool closeConnection(); 40 | /** 41 | * Returns the state of the connection status. Returns true if the connection is active, 42 | * false if connection is broken. 43 | */ 44 | bool isConnected(); 45 | 46 | private: 47 | SocketTransport() : mSocket(-1), socketStatus(false) {} 48 | /** 49 | * Socket instance. 50 | */ 51 | int mSocket; 52 | bool socketStatus; 53 | }; -------------------------------------------------------------------------------- /ProvisioningTool/include/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2021, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #pragma once 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | std::string getHexString(std::vector& input); 25 | 26 | std::string hex2str(std::string a); 27 | 28 | int readJsonFile(Json::Value& root, std::string& inputFileName); 29 | 30 | int writeJsonFile(Json::Value& writerRoot, std::string& outputFileName); -------------------------------------------------------------------------------- /ProvisioningTool/lib/README.md: -------------------------------------------------------------------------------- 1 | # Instructions to build jsoncpp 2 | Download the code from below opensource link: 3 | https://github.com/open-source-parsers/jsoncpp/tree/0.y.z 4 | 5 | #### Unzip it 6 |
 7 | unzip jsoncpp-0.y.z.zip
 8 | cd jsoncpp-0.y.z
 9 | 
10 | 11 | #### Build 12 |
13 | $ mkdir -p build/debug
14 | $ cd build/debug
15 | $ cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=ON -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
16 | $ make
17 | 
18 | 19 | #### Check the generated static and dynamic link library 20 |
21 | $ find . -name *.a
22 | ./src/lib_json/libjsoncpp.a
23 | $ find . -name *.so
24 | ./src/lib_json/libjsoncpp.so
25 | 
26 | -------------------------------------------------------------------------------- /ProvisioningTool/lib/libjsoncpp.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/lib/libjsoncpp.a -------------------------------------------------------------------------------- /ProvisioningTool/lib/libjsoncpp.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/lib/libjsoncpp.so -------------------------------------------------------------------------------- /ProvisioningTool/lib/libjsoncpp.so.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/lib/libjsoncpp.so.0 -------------------------------------------------------------------------------- /ProvisioningTool/lib/libjsoncpp.so.0.10.7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/lib/libjsoncpp.so.0.10.7 -------------------------------------------------------------------------------- /ProvisioningTool/sample_json_cf.txt: -------------------------------------------------------------------------------- 1 | { 2 | "attest_ids": { 3 | "brand": "generic", 4 | "device": "vsoc_x86_64", 5 | "product": "aosp_cf_x86_64_phone", 6 | "serial": "", 7 | "imei": "000000000000000", 8 | "meid": "000000000000000", 9 | "manufacturer": "Google", 10 | "model": "Cuttlefish x86_64 phone" 11 | }, 12 | "shared_secret": "0000000000000000000000000000000000000000000000000000000000000000", 13 | "set_boot_params": { 14 | "boot_patch_level": 0, 15 | "verified_boot_key": "268CCCE87338C993759F96124A232710E4ECFF38A83E96DC74765CB2DA89A787", 16 | "verified_boot_key_hash": "0000000000000000000000000000000000000000000000000000000000000000", 17 | "boot_state": 0, 18 | "device_locked": 1 19 | }, 20 | "attest_key": "test_resources/batch_key.der", 21 | "attest_cert_chain": [ 22 | "test_resources/batch_cert.der", 23 | "test_resources/intermediate_cert.der", 24 | "test_resources/ca_cert.der" 25 | ], 26 | "oem_root_key": "test_resources/oem_root_key.der" 27 | } 28 | -------------------------------------------------------------------------------- /ProvisioningTool/sample_json_gf.txt: -------------------------------------------------------------------------------- 1 | { 2 | "attest_ids": { 3 | "brand": "Android", 4 | "device": "generic_x86_64", 5 | "product": "aosp_x86_64", 6 | "serial": "", 7 | "imei": "000000000000000", 8 | "meid": "000000000000000", 9 | "manufacturer": "unknown", 10 | "model": "AOSP on x86_64" 11 | }, 12 | "shared_secret": "0000000000000000000000000000000000000000000000000000000000000000", 13 | "set_boot_params": { 14 | "boot_patch_level": 0, 15 | "verified_boot_key": "268CCCE87338C993759F96124A232710E4ECFF38A83E96DC74765CB2DA89A787", 16 | "verified_boot_key_hash": "0000000000000000000000000000000000000000000000000000000000000000", 17 | "boot_state": 0, 18 | "device_locked": 1 19 | }, 20 | "attest_key": "test_resources/batch_key.der", 21 | "attest_cert_chain": [ 22 | "test_resources/batch_cert.der", 23 | "test_resources/intermediate_cert.der", 24 | "test_resources/ca_cert.der" 25 | ], 26 | "oem_root_key": "test_resources/oem_root_key.der" 27 | } 28 | -------------------------------------------------------------------------------- /ProvisioningTool/src/socket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2021, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "socket.h" 26 | 27 | #define PORT 8080 28 | #define IPADDR "127.0.0.1" 29 | //#define IPADDR "192.168.0.5" 30 | #define MAX_RECV_BUFFER_SIZE 2500 31 | 32 | using namespace std; 33 | 34 | SocketTransport::~SocketTransport() { 35 | if (closeConnection()) 36 | std::cout << "Socket is closed"; 37 | } 38 | 39 | bool SocketTransport::openConnection() { 40 | struct sockaddr_in serv_addr; 41 | if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 42 | perror("Socket "); 43 | return false; 44 | } 45 | 46 | serv_addr.sin_family = AF_INET; 47 | serv_addr.sin_port = htons(PORT); 48 | 49 | // Convert IPv4 and IPv6 addresses from text to binary form 50 | if (inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr) <= 0) { 51 | std::cout << "Invalid address/ Address not supported."; 52 | return false; 53 | } 54 | 55 | if (connect(mSocket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { 56 | close(mSocket); 57 | perror("Socket "); 58 | return false; 59 | } 60 | socketStatus = true; 61 | return true; 62 | } 63 | 64 | bool SocketTransport::sendData(const std::vector& inData, std::vector& output) { 65 | uint8_t buffer[MAX_RECV_BUFFER_SIZE]; 66 | int count = 1; 67 | while (!socketStatus && count++ < 5) { 68 | sleep(1); 69 | std::cout << "Trying to open socket connection... count: " << count; 70 | openConnection(); 71 | } 72 | 73 | if (count >= 5) { 74 | std::cout << "Failed to open socket connection"; 75 | return false; 76 | } 77 | 78 | if (0 > send(mSocket, inData.data(), inData.size(), 0)) { 79 | static int connectionResetCnt = 0; /* To avoid loop */ 80 | if (ECONNRESET == errno && connectionResetCnt == 0) { 81 | // Connection reset. Try open socket and then sendData. 82 | socketStatus = false; 83 | connectionResetCnt++; 84 | return sendData(inData, output); 85 | } 86 | std::cout << "Failed to send data over socket err: " << errno; 87 | connectionResetCnt = 0; 88 | return false; 89 | } 90 | 91 | ssize_t valRead = read(mSocket, buffer, MAX_RECV_BUFFER_SIZE); 92 | if (0 > valRead) { 93 | std::cout << "Failed to read data from socket."; 94 | } 95 | for (ssize_t i = 0; i < valRead; i++) { 96 | output.push_back(buffer[i]); 97 | } 98 | return true; 99 | } 100 | 101 | bool SocketTransport::closeConnection() { 102 | close(mSocket); 103 | socketStatus = false; 104 | return true; 105 | } 106 | 107 | bool SocketTransport::isConnected() { 108 | return socketStatus; 109 | } 110 | 111 | -------------------------------------------------------------------------------- /ProvisioningTool/src/utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Copyright 2021, The Android Open Source Project 4 | ** 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); 6 | ** you may not use this file except in compliance with the License. 7 | ** You may obtain a copy of the License at 8 | ** 9 | ** http://www.apache.org/licenses/LICENSE-2.0 10 | ** 11 | ** Unless required by applicable law or agreed to in writing, software 12 | ** distributed under the License is distributed on an "AS IS" BASIS, 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | ** See the License for the specific language governing permissions and 15 | ** limitations under the License. 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | constexpr char hex_value[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 26 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'..'9' 27 | 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'..'F' 28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 29 | 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f' 30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 39 | 40 | std::string getHexString(std::vector& input) { 41 | std::stringstream ss; 42 | for (auto b : input) { 43 | ss << std::setw(2) << std::setfill('0') << std::hex << (int) (b & 0xFF); 44 | } 45 | return ss.str(); 46 | } 47 | 48 | 49 | std::string hex2str(std::string a) { 50 | std::string b; 51 | size_t num = a.size() / 2; 52 | b.resize(num); 53 | for (size_t i = 0; i < num; i++) { 54 | b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]); 55 | } 56 | return b; 57 | } 58 | 59 | 60 | // Parses the json file and returns 0 if success; otherwise 1. 61 | int readJsonFile(Json::Value& root, std::string& inputFileName) { 62 | Json::CharReaderBuilder builder; 63 | std::string errorMessage; 64 | 65 | if(!root.empty()) { 66 | // Already parsed. 67 | return 0; 68 | } 69 | std::ifstream stream(inputFileName); 70 | if (Json::parseFromStream(builder, stream, &root, &errorMessage)) { 71 | printf("\n Parsed json file successfully.\n"); 72 | return 0; 73 | } else { 74 | printf("\n Failed to parse json file error:%s\n", errorMessage.c_str()); 75 | return 1; 76 | } 77 | } 78 | 79 | // Write the json data to the output file. 80 | int writeJsonFile(Json::Value& writerRoot, std::string& outputFileName) { 81 | 82 | std::ofstream ofs; 83 | // Delete file if already exists. 84 | std::remove(outputFileName.data()); 85 | ofs.open(outputFileName, std::ofstream::out | std::ios_base::app); 86 | if (ofs.fail()) { 87 | printf("\n Fail to open the output file:%s", outputFileName.c_str()); 88 | return FAILURE; 89 | } 90 | 91 | Json::StyledWriter styledWriter; 92 | ofs << styledWriter.write(writerRoot); 93 | 94 | ofs.close(); 95 | return SUCCESS; 96 | } -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/batch_cert.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/batch_cert.der -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/batch_key.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/batch_key.der -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/ca_cert.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/ca_cert.der -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/ca_key.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/ca_key.der -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/intermediate_cert.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/intermediate_cert.der -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/intermediate_key.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/intermediate_key.der -------------------------------------------------------------------------------- /ProvisioningTool/test_resources/oem_root_key.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/ProvisioningTool/test_resources/oem_root_key.der -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaCardKeymaster 2 | JavaCard implementation of the [Android Keymaster 4.1 HAL](https://android.googlesource.com/platform/hardware/interfaces/+/master/keymaster/4.1/IKeymasterDevice.hal) (most of the specification is in the [Android Keymaster 4.0 HAL](https://android.googlesource.com/platform/hardware/interfaces/+/master/keymaster/4.0/IKeymasterDevice.hal)), intended for creation of StrongBox Keymaster instances to support the [Android Hardware-backed Keystore](https://source.android.com/security/keystore). 3 | 4 | Here is the [JavaCard Applet design doc](https://docs.google.com/document/d/1bTAmhDqCNq1HYzChNDv8kLJEi64cwTIZ2PfdMMz3o8U/edit#heading=h.gjdgxs) and the [HAL design doc](https://docs.google.com/document/d/1-1MLJ781wAPJ2YxCdCtHMepld8F8KVAxpPtCw9J3b3o/edit#heading=h.gjdgxs) (the content will move here when it stablizes, for now these are a limited-access links). 5 | -------------------------------------------------------------------------------- /TestingTools/JCProxy/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | JCProxy 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /TestingTools/JCProxy/lib/apduio-RELEASE71.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/TestingTools/JCProxy/lib/apduio-RELEASE71.jar -------------------------------------------------------------------------------- /TestingTools/JCProxy/lib/jcardsim-3.0.5-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/divegeek/JavaCardKeymaster/8ee369f1f7a77d548930023e64ba36a3d79e5ae5/TestingTools/JCProxy/lib/jcardsim-3.0.5-SNAPSHOT.jar -------------------------------------------------------------------------------- /TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCProxyMain.java: -------------------------------------------------------------------------------- 1 | package com.android.javacard.jcproxy; 2 | 3 | import java.io.*; 4 | import java.net.*; 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Date; 8 | 9 | import com.sun.javacard.apduio.CadTransportException; 10 | 11 | /** 12 | * This program demonstrates a simple TCP/IP socket server. 13 | * 14 | * @author www.codejava.net 15 | */ 16 | public class JCProxyMain { 17 | 18 | public static void main(String[] args) { 19 | if (args.length < 1) { 20 | System.out.println("Port no is expected as argument."); 21 | return; 22 | } 23 | 24 | int port = Integer.parseInt(args[0]); 25 | Simulator simulator = new JCardSimulator(); 26 | 27 | try (ServerSocket serverSocket = new ServerSocket(port)) { 28 | simulator.initaliseSimulator(); 29 | if (!simulator.setupKeymasterOnSimulator()) { 30 | System.out.println("Failed to setup Java card keymaster simulator."); 31 | System.exit(-1); 32 | } 33 | byte[] outData; 34 | 35 | while (true) { 36 | try { 37 | Socket socket = serverSocket.accept(); 38 | System.out.println("\n\n\n\n\n"); 39 | System.out.println("------------------------New client connected on " 40 | + socket.getPort() + "--------------------"); 41 | OutputStream output = null; 42 | InputStream isReader = null; 43 | try { 44 | socket.setReceiveBufferSize(1024 * 5); 45 | output = socket.getOutputStream(); 46 | isReader = socket.getInputStream(); 47 | 48 | byte[] inBytes = new byte[65536]; 49 | int readLen = 0, index = 0; 50 | System.out.println("Socket input buffer size: " 51 | + socket.getReceiveBufferSize()); 52 | while ((readLen = isReader.read(inBytes, index, 1024 * 5)) > 0) { 53 | if (readLen > 0) { 54 | System.out.println("Bytes read from index (" + index 55 | + ") socket: " + readLen + " Estimate read: " 56 | + isReader.available()); 57 | byte[] outBytes; 58 | 59 | try { 60 | outBytes = simulator.executeApdu( 61 | Arrays.copyOfRange(inBytes, 0, index + readLen)); 62 | outData = simulator.decodeDataOut(); 63 | System.out.println( 64 | "Return Data " + Utils.byteArrayToHexString(outData)); 65 | byte[] finalOutData = new byte[outData.length 66 | + outBytes.length]; 67 | System.arraycopy(outData, 0, finalOutData, 0, outData.length); 68 | System.arraycopy(outBytes, 0, finalOutData, outData.length, 69 | outBytes.length); 70 | output.write(finalOutData); 71 | output.flush(); 72 | index = 0; 73 | } catch (IllegalArgumentException e) { 74 | e.printStackTrace(); 75 | index = readLen; 76 | } 77 | } 78 | } 79 | } catch (IOException e) { 80 | e.printStackTrace(); 81 | } catch (Exception e) { 82 | e.printStackTrace(); 83 | } finally { 84 | if (output != null) 85 | output.close(); 86 | if (isReader != null) 87 | isReader.close(); 88 | socket.close(); 89 | } 90 | } catch (IOException e) { 91 | break; 92 | } catch (Exception e) { 93 | break; 94 | } 95 | System.out.println("Client disconnected."); 96 | } 97 | simulator.disconnectSimulator(); 98 | } catch (IOException ex) { 99 | System.out.println("Server exception: " + ex.getMessage()); 100 | ex.printStackTrace(); 101 | } catch (CadTransportException e1) { 102 | e1.printStackTrace(); 103 | } catch (Exception e1) { 104 | e1.printStackTrace(); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCardSimulator.java: -------------------------------------------------------------------------------- 1 | package com.android.javacard.jcproxy; 2 | 3 | import javax.smartcardio.CommandAPDU; 4 | import javax.smartcardio.ResponseAPDU; 5 | 6 | import com.android.javacard.keymaster.KMJCardSimApplet; 7 | import com.licel.jcardsim.smartcardio.CardSimulator; 8 | import com.licel.jcardsim.utils.AIDUtil; 9 | 10 | import javacard.framework.AID; 11 | 12 | public class JCardSimulator implements Simulator { 13 | 14 | private CardSimulator simulator; 15 | ResponseAPDU response; 16 | 17 | public JCardSimulator() { 18 | simulator = new CardSimulator(); 19 | } 20 | 21 | @Override 22 | public void initaliseSimulator() throws Exception { 23 | } 24 | 25 | @Override 26 | public void disconnectSimulator() throws Exception { 27 | AID appletAID1 = AIDUtil.create("A000000062"); 28 | // Delete i.e. uninstall applet 29 | simulator.deleteApplet(appletAID1); 30 | } 31 | 32 | @Override 33 | public boolean setupKeymasterOnSimulator() throws Exception { 34 | AID appletAID1 = AIDUtil.create("A000000062"); 35 | simulator.installApplet(appletAID1, KMJCardSimApplet.class); 36 | // Select applet 37 | simulator.selectApplet(appletAID1); 38 | return true; 39 | } 40 | 41 | private final byte[] intToByteArray(int value) { 42 | return new byte[] { 43 | (byte) (value >>> 8), (byte) value }; 44 | } 45 | 46 | @Override 47 | public byte[] executeApdu(byte[] apdu) throws Exception { 48 | System.out.println("Executing APDU = " + Utils.byteArrayToHexString(apdu)); 49 | CommandAPDU apduCmd = new CommandAPDU(apdu); 50 | response = simulator.transmitCommand(apduCmd); 51 | System.out.println("Status = " 52 | + Utils.byteArrayToHexString(intToByteArray(response.getSW()))); 53 | return intToByteArray(response.getSW()); 54 | } 55 | 56 | @Override 57 | public byte[] decodeDataOut() { 58 | return response.getData(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /TestingTools/JCProxy/src/com/android/javacard/jcproxy/Simulator.java: -------------------------------------------------------------------------------- 1 | package com.android.javacard.jcproxy; 2 | 3 | public interface Simulator { 4 | byte[] STATUS_OK = Utils.hexStringToByteArray("9000"); 5 | 6 | void initaliseSimulator() throws Exception; 7 | 8 | void disconnectSimulator() throws Exception; 9 | 10 | public boolean setupKeymasterOnSimulator() throws Exception; 11 | 12 | byte[] executeApdu(byte[] apdu) throws Exception; 13 | 14 | byte[] decodeDataOut(); 15 | } 16 | -------------------------------------------------------------------------------- /TestingTools/JCProxy/src/com/android/javacard/jcproxy/Utils.java: -------------------------------------------------------------------------------- 1 | package com.android.javacard.jcproxy; 2 | 3 | public class Utils { 4 | 5 | public static byte[] hexStringToByteArray(String s) { 6 | int len = s.length(); 7 | if (len % 2 != 0) 8 | throw new IllegalArgumentException("Expecting each byte of 2 char."); 9 | byte[] data = new byte[len / 2]; 10 | for (int i = 0; i < len; i += 2) { 11 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 12 | + Character.digit(s.charAt(i + 1), 16)); 13 | } 14 | return data; 15 | } 16 | 17 | private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); 18 | 19 | public static String byteArrayToHexString(byte[] bytes) { 20 | char[] hexChars = new char[bytes.length * 2]; 21 | for (int j = 0; j < bytes.length; j++) { 22 | int v = bytes[j] & 0xFF; 23 | hexChars[j * 2] = HEX_ARRAY[v >>> 4]; 24 | hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; 25 | } 26 | return new String(hexChars); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TestingTools/README.md: -------------------------------------------------------------------------------- 1 | # TestingTools 2 | [JCProxy](JCProxy) is a testing tool, which provides a way to communicate with 3 | JCardSimulator from android emulator/device. 4 | It basically opens a socket connection on the port (port mentioned in program arguments) 5 | and listens for the incomming data on this port. This tool uses apduio and JCarsim jars 6 | to validate and transmit the APDUs to the Keymaster Applet. 7 | 8 | ###Build 9 | Import JCProxy server application either in Eclipse or IntelliJ. Add the provided jars inside 10 | [lib](JCProxy/lib) directory to the project and also add [Keymaster Applet](../Applet) as 11 | dependent project. Add port number (Ex: 8080) as program arguments. 12 | -------------------------------------------------------------------------------- /aosp_integration_patches/device_google_cuttlefish.patch: -------------------------------------------------------------------------------- 1 | diff --git a/shared/device.mk b/shared/device.mk 2 | index c9221ec36..eeae0a965 100644 3 | --- a/shared/device.mk 4 | +++ b/shared/device.mk 5 | @@ -621,6 +621,9 @@ endif 6 | PRODUCT_PACKAGES += \ 7 | $(LOCAL_KEYMINT_PRODUCT_PACKAGE) 8 | 9 | +PRODUCT_PACKAGES += \ 10 | + android.hardware.keymaster@4.1-strongbox.service \ 11 | + 12 | # Keymint configuration 13 | ifneq ($(LOCAL_PREFER_VENDOR_APEX),true) 14 | PRODUCT_COPY_FILES += \ 15 | diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts 16 | index 6c471b8b8..5baf83c4c 100644 17 | --- a/shared/sepolicy/vendor/file_contexts 18 | +++ b/shared/sepolicy/vendor/file_contexts 19 | @@ -94,6 +94,7 @@ 20 | /vendor/bin/hw/android\.hardware\.identity-service\.remote u:object_r:hal_identity_remote_exec:s0 21 | /vendor/bin/hw/android\.hardware\.security\.keymint-service\.remote u:object_r:hal_keymint_remote_exec:s0 22 | /vendor/bin/hw/android\.hardware\.keymaster@4\.1-service.remote u:object_r:hal_keymaster_remote_exec:s0 23 | +/vendor/bin/hw/android\.hardware\.keymaster@4\.1-strongbox\.service u:object_r:hal_keymaster_strongbox_exec:s0 24 | /vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service.remote u:object_r:hal_gatekeeper_remote_exec:s0 25 | /vendor/bin/hw/android\.hardware\.confirmationui@1\.0-service.cuttlefish u:object_r:hal_confirmationui_cuttlefish_exec:s0 26 | /vendor/bin/hw/android\.hardware\.oemlock-service.example u:object_r:hal_oemlock_default_exec:s0 27 | diff --git a/shared/sepolicy/vendor/hal_keymaster_strongbox.te b/shared/sepolicy/vendor/hal_keymaster_strongbox.te 28 | new file mode 100644 29 | index 000000000..40cb82c3f 30 | --- /dev/null 31 | +++ b/shared/sepolicy/vendor/hal_keymaster_strongbox.te 32 | @@ -0,0 +1,14 @@ 33 | +type hal_keymaster_strongbox, domain; 34 | +hal_server_domain(hal_keymaster_strongbox, hal_keymaster) 35 | + 36 | +type hal_keymaster_strongbox_exec, exec_type, vendor_file_type, file_type; 37 | +init_daemon_domain(hal_keymaster_strongbox) 38 | + 39 | +vndbinder_use(hal_keymaster_strongbox) 40 | +get_prop(hal_keymaster_strongbox, vendor_security_patch_level_prop); 41 | + 42 | +# Allow access to sockets 43 | +allow hal_keymaster_strongbox self:tcp_socket { connect create write read getattr getopt setopt }; 44 | +allow hal_keymaster_strongbox port_type:tcp_socket name_connect; 45 | +allow hal_keymaster_strongbox port:tcp_socket { name_connect }; 46 | +allow hal_keymaster_strongbox vendor_data_file:file { open read getattr }; 47 | -------------------------------------------------------------------------------- /aosp_integration_patches/hardware_interfaces_keymaster.patch: -------------------------------------------------------------------------------- 1 | diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp 2 | index a7be660c4..dd91e9089 100644 3 | --- a/keymaster/4.0/vts/functional/Android.bp 4 | +++ b/keymaster/4.0/vts/functional/Android.bp 5 | @@ -31,9 +31,11 @@ cc_test { 6 | "VerificationTokenTest.cpp", 7 | "keymaster_hidl_hal_test.cpp", 8 | ], 9 | + shared_libs: [ 10 | + "libcrypto", 11 | + ], 12 | static_libs: [ 13 | "android.hardware.keymaster@4.0", 14 | - "libcrypto_static", 15 | "libkeymaster4support", 16 | "libkeymaster4vtstest", 17 | ], 18 | diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp 19 | index 476eed8b1..823683d75 100644 20 | --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp 21 | +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp 22 | @@ -1079,9 +1079,12 @@ TEST_P(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) { 23 | * presented. 24 | */ 25 | TEST_P(SigningOperationsTest, NoUserConfirmation) { 26 | - if (SecLevel() == SecurityLevel::STRONGBOX) return; 27 | + size_t key_size = 1024; 28 | + if (SecLevel() == SecurityLevel::STRONGBOX){ 29 | + key_size = 2048; 30 | + } 31 | ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() 32 | - .RsaSigningKey(1024, 65537) 33 | + .RsaSigningKey(key_size, 65537) 34 | .Digest(Digest::NONE) 35 | .Padding(PaddingMode::NONE) 36 | .Authorization(TAG_NO_AUTH_REQUIRED) 37 | -------------------------------------------------------------------------------- /aosp_integration_patches/omapi_patches/packages_apps_secureElement.patch: -------------------------------------------------------------------------------- 1 | diff --git a/Android.bp b/Android.bp 2 | index f86ad26..afea5c6 100644 3 | --- a/Android.bp 4 | +++ b/Android.bp 5 | @@ -42,6 +42,9 @@ android_app { 6 | "src/**/*.java", 7 | ":statslog-secure-element-java-gen", 8 | ], 9 | + vintf_fragments: [ 10 | + "secure_element-service.xml", 11 | + ], 12 | platform_apis: true, 13 | certificate: "platform", 14 | static_libs: ["android.hardware.secure_element-V1.0-java", 15 | diff --git a/res/values/config.xml b/res/values/config.xml 16 | index 5811b10..da6e50e 100644 17 | --- a/res/values/config.xml 18 | +++ b/res/values/config.xml 19 | @@ -6,5 +6,5 @@ 20 | 21 | 23 | - false 24 | + true 25 | 26 | -------------------------------------------------------------------------------- /aosp_integration_patches/system_sepolicy.patch: -------------------------------------------------------------------------------- 1 | diff --git a/public/hal_neverallows.te b/public/hal_neverallows.te 2 | index cd1591009..56f3ad1c4 100644 3 | --- a/public/hal_neverallows.te 4 | +++ b/public/hal_neverallows.te 5 | @@ -2,6 +2,7 @@ 6 | # network capabilities 7 | neverallow { 8 | halserverdomain 9 | + -hal_keymaster_server 10 | -hal_bluetooth_server 11 | -hal_can_controller_server 12 | -hal_wifi_server 13 | @@ -21,6 +22,7 @@ neverallow { 14 | # will result in CTS failure. 15 | neverallow { 16 | halserverdomain 17 | + -hal_keymaster_server 18 | -hal_automotive_socket_exemption 19 | -hal_can_controller_server 20 | -hal_tetheroffload_server 21 | @@ -35,6 +37,7 @@ neverallow { 22 | 23 | neverallow { 24 | halserverdomain 25 | + -hal_keymaster_server 26 | -hal_automotive_socket_exemption 27 | -hal_can_controller_server 28 | -hal_tetheroffload_server 29 | -------------------------------------------------------------------------------- /aosp_integration_patches_aosp_12_r15/device_google_cuttlefish.patch: -------------------------------------------------------------------------------- 1 | diff --git a/shared/device.mk b/shared/device.mk 2 | index 8647d0175..6fc99ff94 100644 3 | --- a/shared/device.mk 4 | +++ b/shared/device.mk 5 | @@ -538,6 +538,10 @@ endif 6 | PRODUCT_PACKAGES += \ 7 | $(LOCAL_KEYMINT_PRODUCT_PACKAGE) 8 | 9 | +PRODUCT_PACKAGES += \ 10 | + android.hardware.keymaster@4.1-strongbox.service \ 11 | + 12 | + 13 | # Keymint configuration 14 | PRODUCT_COPY_FILES += \ 15 | frameworks/native/data/etc/android.software.device_id_attestation.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.device_id_attestation.xml 16 | diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts 17 | index 20538a50f..553232889 100644 18 | --- a/shared/sepolicy/vendor/file_contexts 19 | +++ b/shared/sepolicy/vendor/file_contexts 20 | @@ -88,6 +88,7 @@ 21 | /vendor/bin/hw/android\.hardware\.thermal@2\.0-service\.mock u:object_r:hal_thermal_default_exec:s0 22 | /vendor/bin/hw/android\.hardware\.security\.keymint-service\.remote u:object_r:hal_keymint_remote_exec:s0 23 | /vendor/bin/hw/android\.hardware\.keymaster@4\.1-service.remote u:object_r:hal_keymaster_remote_exec:s0 24 | +/vendor/bin/hw/android\.hardware\.keymaster@4\.1-strongbox\.service u:object_r:hal_keymaster_strongbox_exec:s0 25 | /vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service.remote u:object_r:hal_gatekeeper_remote_exec:s0 26 | /vendor/bin/hw/android\.hardware\.oemlock-service.example u:object_r:hal_oemlock_default_exec:s0 27 | /vendor/bin/hw/android\.hardware\.weaver-service.example u:object_r:hal_weaver_default_exec:s0 28 | diff --git a/shared/sepolicy/vendor/hal_keymaster_strongbox.te b/shared/sepolicy/vendor/hal_keymaster_strongbox.te 29 | new file mode 100644 30 | index 000000000..1412e07fd 31 | --- /dev/null 32 | +++ b/shared/sepolicy/vendor/hal_keymaster_strongbox.te 33 | @@ -0,0 +1,15 @@ 34 | +type hal_keymaster_strongbox, domain; 35 | +hal_server_domain(hal_keymaster_strongbox, hal_keymaster) 36 | + 37 | +type hal_keymaster_strongbox_exec, exec_type, vendor_file_type, file_type; 38 | +init_daemon_domain(hal_keymaster_strongbox) 39 | + 40 | +vndbinder_use(hal_keymaster_strongbox) 41 | +get_prop(hal_keymaster_strongbox, vendor_security_patch_level_prop); 42 | + 43 | +# Allow access to sockets 44 | +allow hal_keymaster_strongbox self:tcp_socket { connect create write read getattr getopt setopt }; 45 | +allow hal_keymaster_strongbox port_type:tcp_socket name_connect; 46 | +allow hal_keymaster_strongbox port:tcp_socket { name_connect }; 47 | +allow hal_keymaster_strongbox vendor_data_file:file { open read getattr }; 48 | + 49 | diff --git a/shared/sepolicy/vendor/service_contexts b/shared/sepolicy/vendor/service_contexts 50 | index d20d026cf..214576e3e 100644 51 | --- a/shared/sepolicy/vendor/service_contexts 52 | +++ b/shared/sepolicy/vendor/service_contexts 53 | @@ -4,6 +4,7 @@ android.hardware.neuralnetworks.IDevice/nnapi-sample_float_slow u:object_r:hal_n 54 | android.hardware.neuralnetworks.IDevice/nnapi-sample_minimal u:object_r:hal_neuralnetworks_service:s0 55 | android.hardware.neuralnetworks.IDevice/nnapi-sample_quant u:object_r:hal_neuralnetworks_service:s0 56 | android.hardware.neuralnetworks.IDevice/nnapi-sample_sl_shim u:object_r:hal_neuralnetworks_service:s0 57 | +android.hardware.keymaster@4.1::IKeymasterDevice/strongbox u:object_r:hal_keymaster_service:s0 58 | 59 | # Binder service mappings 60 | gce u:object_r:gce_service:s0 61 | -------------------------------------------------------------------------------- /aosp_integration_patches_aosp_12_r15/hardware_interfaces_keymaster.patch: -------------------------------------------------------------------------------- 1 | diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp 2 | index a7be660c4..dd91e9089 100644 3 | --- a/keymaster/4.0/vts/functional/Android.bp 4 | +++ b/keymaster/4.0/vts/functional/Android.bp 5 | @@ -31,9 +31,11 @@ cc_test { 6 | "VerificationTokenTest.cpp", 7 | "keymaster_hidl_hal_test.cpp", 8 | ], 9 | + shared_libs: [ 10 | + "libcrypto", 11 | + ], 12 | static_libs: [ 13 | "android.hardware.keymaster@4.0", 14 | - "libcrypto_static", 15 | "libkeymaster4support", 16 | "libkeymaster4vtstest", 17 | ], 18 | diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp 19 | index 476eed8b1..823683d75 100644 20 | --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp 21 | +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp 22 | @@ -1079,9 +1079,12 @@ TEST_P(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) { 23 | * presented. 24 | */ 25 | TEST_P(SigningOperationsTest, NoUserConfirmation) { 26 | - if (SecLevel() == SecurityLevel::STRONGBOX) return; 27 | + size_t key_size = 1024; 28 | + if (SecLevel() == SecurityLevel::STRONGBOX){ 29 | + key_size = 2048; 30 | + } 31 | ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() 32 | - .RsaSigningKey(1024, 65537) 33 | + .RsaSigningKey(key_size, 65537) 34 | .Digest(Digest::NONE) 35 | .Padding(PaddingMode::NONE) 36 | .Authorization(TAG_NO_AUTH_REQUIRED) 37 | -------------------------------------------------------------------------------- /aosp_integration_patches_aosp_12_r15/system_security_keystore2.patch: -------------------------------------------------------------------------------- 1 | diff --git a/keystore2/src/km_compat/km_compat.cpp b/keystore2/src/km_compat/km_compat.cpp 2 | index 64849c1..40ca554 100644 3 | --- a/keystore2/src/km_compat/km_compat.cpp 4 | +++ b/keystore2/src/km_compat/km_compat.cpp 5 | @@ -1314,7 +1314,7 @@ KeymasterDevices initializeKeymasters() { 6 | CHECK(serviceManager.get()) << "Failed to get ServiceManager"; 7 | auto result = enumerateKeymasterDevices(serviceManager.get()); 8 | auto softKeymaster = result[SecurityLevel::SOFTWARE]; 9 | - if (!result[SecurityLevel::TRUSTED_ENVIRONMENT]) { 10 | + if ((!result[SecurityLevel::TRUSTED_ENVIRONMENT]) && (!result[SecurityLevel::STRONGBOX])) { 11 | result = enumerateKeymasterDevices(serviceManager.get()); 12 | } 13 | if (softKeymaster) result[SecurityLevel::SOFTWARE] = softKeymaster; 14 | -------------------------------------------------------------------------------- /aosp_integration_patches_aosp_12_r15/system_sepolicy.patch: -------------------------------------------------------------------------------- 1 | diff --git a/prebuilts/api/31.0/public/hal_neverallows.te b/prebuilts/api/31.0/public/hal_neverallows.te 2 | index 105689b8a..d7dc6baaf 100644 3 | --- a/prebuilts/api/31.0/public/hal_neverallows.te 4 | +++ b/prebuilts/api/31.0/public/hal_neverallows.te 5 | @@ -2,6 +2,7 @@ 6 | # network capabilities 7 | neverallow { 8 | halserverdomain 9 | + -hal_keymaster_server 10 | -hal_bluetooth_server 11 | -hal_can_controller_server 12 | -hal_wifi_server 13 | @@ -19,6 +20,7 @@ neverallow { 14 | # will result in CTS failure. 15 | neverallow { 16 | halserverdomain 17 | + -hal_keymaster_server 18 | -hal_automotive_socket_exemption 19 | -hal_can_controller_server 20 | -hal_tetheroffload_server 21 | diff --git a/public/hal_neverallows.te b/public/hal_neverallows.te 22 | index 105689b8a..d7dc6baaf 100644 23 | --- a/public/hal_neverallows.te 24 | +++ b/public/hal_neverallows.te 25 | @@ -2,6 +2,7 @@ 26 | # network capabilities 27 | neverallow { 28 | halserverdomain 29 | + -hal_keymaster_server 30 | -hal_bluetooth_server 31 | -hal_can_controller_server 32 | -hal_wifi_server 33 | @@ -19,6 +20,7 @@ neverallow { 34 | # will result in CTS failure. 35 | neverallow { 36 | halserverdomain 37 | + -hal_keymaster_server 38 | -hal_automotive_socket_exemption 39 | -hal_can_controller_server 40 | -hal_tetheroffload_server 41 | --------------------------------------------------------------------------------