From ad16c47b876dc4042e3ca1899fd2f7635c0a8715 Mon Sep 17 00:00:00 2001 From: "avinash.hedage" Date: Thu, 23 Dec 2021 13:57:48 +0000 Subject: [PATCH] Computed Hmac changes for Jcard --- .../seprovider/KMComputedHmacKey.java | 5 ++ .../javacard/seprovider/KMHmacKey.java | 4 ++ .../javacard/seprovider/KMJCardSimulator.java | 68 ++++++++++++++++--- .../javacard/seprovider/KMSEProvider.java | 50 ++++++++++++-- .../javacard/keymaster/KMKeymasterApplet.java | 1 - 5 files changed, 110 insertions(+), 18 deletions(-) create mode 100644 Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java diff --git a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java new file mode 100644 index 00000000..3b0aa405 --- /dev/null +++ b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMComputedHmacKey.java @@ -0,0 +1,5 @@ +package com.android.javacard.seprovider; + + +public interface KMComputedHmacKey { +} diff --git a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java index 8473f1bf..735789b6 100644 --- a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java +++ b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMHmacKey.java @@ -36,4 +36,8 @@ public byte getKey(byte[] keyData, short kOff) { public short getKeySizeBits() { return hmacKey.getSize(); } + + public HMACKey getKey() { + return hmacKey; + } } diff --git a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMJCardSimulator.java b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMJCardSimulator.java index 7579e0af..d27fe0a8 100644 --- a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMJCardSimulator.java +++ b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMJCardSimulator.java @@ -40,6 +40,7 @@ import javacard.security.Key; import javacard.security.KeyBuilder; import javacard.security.KeyPair; +import javacard.security.MessageDigest; import javacard.security.RSAPrivateKey; import javacard.security.KeyAgreement; import javacard.security.RandomData; @@ -81,6 +82,7 @@ public class KMJCardSimulator implements KMSEProvider { private static final short CERT_EXPIRY_OFFSET = (short) (CERT_ISSUER_OFFSET + KMConfigurations.CERT_ISSUER_MAX_SIZE); private static final short COMPUTED_HMAC_KEY_SIZE = 32; + public static byte[] resetFlag; public static boolean jcardSim = false; private static Signature kdf; @@ -100,6 +102,7 @@ public class KMJCardSimulator implements KMSEProvider { private KMECDeviceUniqueKey testKey; private KMECDeviceUniqueKey deviceUniqueKey; private KMHmacKey preSharedKey; + private KMHmacKey computedHmacKey; private boolean deviceReboot; // Data - originally was in repository @@ -580,12 +583,6 @@ public short hmacSign(HMACKey key, byte[] data, short dataStart, short dataLengt return hmacSignature.sign(data, dataStart, dataLength, mac, macStart); } - public boolean hmacVerify(HMACKey key, byte[] data, short dataStart, short dataLength, - byte[] mac, short macStart, short macLength) { - hmacSignature.init(key, Signature.MODE_VERIFY); - return hmacSignature.verify(data, dataStart, dataLength, mac, macStart, macLength); - } - @Override public short hmacKDF(KMMasterKey masterkey, byte[] data, short dataStart, short dataLength, byte[] signature, short signatureStart) { @@ -660,10 +657,11 @@ public short hmacSign(byte[] keyBuf, short keyStart, short keyLength, byte[] dat } @Override - public boolean hmacVerify(byte[] keyBuf, short keyStart, short keyLength, byte[] data, - short dataStart, short dataLength, byte[] mac, short macStart, short macLength) { - HMACKey key = createHMACKey(keyBuf, keyStart, keyLength); - return hmacVerify(key, data, dataStart, dataLength, mac, macStart, macLength); + public boolean hmacVerify(KMComputedHmacKey key, byte[] data, short dataStart, + short dataLength, byte[] mac, short macStart, short macLength) { + KMHmacKey hmacKey = (KMHmacKey) key; + hmacSignature.init(hmacKey.getKey(), Signature.MODE_VERIFY); + return hmacSignature.verify(data, dataStart, dataLength, mac, macStart, macLength); } @Override @@ -706,6 +704,14 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg, byte digest, b return null; } + @Override + public KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey) { + KMOperationImpl opr = null; + KMHmacKey key = (KMHmacKey) computedHmacKey; + Signature signerVerifier = createHmacSignerVerifier(KMType.VERIFY, KMType.SHA2_256, key.getKey()); + return new KMOperationImpl(signerVerifier); + } + @Override public KMOperation initAsymmetricOperation(byte purpose, byte alg, byte padding, byte digest, byte mgfDigest, byte[] privKeyBuf, short privKeyStart, short privKeyLength, @@ -1129,6 +1135,15 @@ public Signature createHmacSignerVerifier(short purpose, short digest, byte[] se return hmacSignerVerifier; } + private Signature createHmacSignerVerifier(short purpose, short digest, HMACKey key) { + byte alg = Signature.ALG_HMAC_SHA_256; + if (digest != KMType.SHA2_256) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + Signature hmacSignerVerifier = Signature.getInstance((byte) alg, false); + hmacSignerVerifier.init(key, (byte) purpose); + return hmacSignerVerifier; + } public KMCipher createAesGcmCipher(short mode, short tagLen, byte[] secret, short secretStart, short secretLength, @@ -1431,6 +1446,20 @@ public boolean isUpgrading() { return false; } + @Override + public KMComputedHmacKey createComputedHmacKey(byte[] keyData, short offset, short length) { + if (length != COMPUTED_HMAC_KEY_SIZE) { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + if (computedHmacKey == null) { + HMACKey key = (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, (short) (length * 8), + false); + computedHmacKey = new KMHmacKey(key); + } + computedHmacKey.setKey(keyData, offset, length); + return (KMComputedHmacKey) computedHmacKey; + } + @Override public KMMasterKey createMasterKey(short keySizeBits) { if (masterKey == null) { @@ -1726,6 +1755,20 @@ public void setProvisionLocked(boolean locked) { public boolean isProvisionLocked() { return isProvisionLocked; } + + @Override + public short messageDigest256(byte[] inBuff, short inOffset, + short inLength, byte[] outBuff, short outOffset) { + MessageDigest mDigest = null; + short len = 0; + try { + mDigest = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA_256, false); + len = mDigest.doFinal(inBuff, inOffset, inLength, outBuff, outOffset); + } catch (Exception e) { + + } + return len; + } private short getProvisionDataBufferOffset(byte dataType) { switch(dataType) { @@ -1797,6 +1840,11 @@ public short readProvisionedData(byte dataType, byte[] buf, short offset) { } @Override + public KMComputedHmacKey getComputedHmacKey() { + return (KMComputedHmacKey) computedHmacKey; + } + + @Override public short getProvisionedDataLength(byte dataType) { short provisionBufOffset = getProvisionDataBufferOffset(dataType); return Util.getShort(provisionData, provisionBufOffset); diff --git a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java index a0d84c35..09dcfa71 100644 --- a/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java +++ b/Applet/JCardSimProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java @@ -67,6 +67,14 @@ void createAsymmetricKey( short pubModMaxLength, short[] lengths); + /** + * Initializes the trusted confirmation operation. + * + * @param computedHmacKey Instance of the computed Hmac key. + * @return instance of KMOperation. + */ + KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey); + /** * Verify that the imported key is valid. If the algorithm and/or keysize are not supported then * it should throw a CryptoException. @@ -293,9 +301,7 @@ short hmacKDF( /** * This is a oneshot operation that verifies the signature using hmac algorithm. * - * @param keyBuf is the buffer with hmac key. - * @param keyStart is the start of the buffer. - * @param keyLength is the length of the buffer which will be in bytes from 8 to 64. + * @param hmacKey is the computed hmac key. * @param data is the buffer containing data. * @param dataStart is the start of the data. * @param dataLength is the length of the data. @@ -305,9 +311,7 @@ short hmacKDF( * @return true if the signature matches. */ boolean hmacVerify( - byte[] keyBuf, - short keyStart, - short keyLength, + KMComputedHmacKey hmacKey, byte[] data, short dataStart, short dataLength, @@ -559,6 +563,16 @@ KMOperation initAsymmetricOperation( */ boolean isUpgrading(); + /** + * This function creates an HMACKey and initializes the key with the provided input key data. + * + * @param keyData buffer containing the key data. + * @param offset start of the buffer. + * @param length length of the buffer. + * @return An instance of the KMComputedHmacKey. + */ + KMComputedHmacKey createComputedHmacKey(byte[] keyData, short offset, short length); + /** * This function generates an AES Key of keySizeBits, which is used as an master key. This * generated key is maintained by the SEProvider. This function should be called only once at the @@ -689,9 +703,30 @@ KMDeviceUniqueKey createDeviceUniqueKey(boolean testMode, * @return boot certificate chain. */ byte[] getBootCertificateChain(); + + /** + * Returns the computed Hmac key. + * + * @return Instance of the computed hmac key. + */ + KMComputedHmacKey getComputedHmacKey(); + + /** + * This is a one-shot operation the does digest of the input mesage. + * + * @param inBuff input buffer to be digested. + * @param inOffset start offset of the input buffer. + * @param inLength length of the input buffer. + * @param outBuff is the output buffer that contains the digested data. + * @param outOffset start offset of the digested output buffer. + * @return length of the digested data. + */ + short messageDigest256(byte[] inBuff, short inOffset, short inLength, byte[] outBuff, + short outOffset); public boolean isProvisionLocked(); - /** + +/** * This function creates an ECKey and initializes the ECPrivateKey with the provided input key * data. The initialized Key is maintained by the SEProvider. This function should be called only * while provisioning the attestation key. @@ -734,4 +769,5 @@ void persistProvisionData(byte[] buf, short certChainOff, short certChainLen, */ short getProvisionedDataLength(byte dataType); + } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index d5cd39ed..69db2b60 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -17,7 +17,6 @@ package com.android.javacard.keymaster; import com.android.javacard.seprovider.KMAttestationCert; -import com.android.javacard.seprovider.KMComputedHmacKey; import com.android.javacard.seprovider.KMDeviceUniqueKey; import com.android.javacard.seprovider.KMException; import com.android.javacard.seprovider.KMHmacKey;