From 407a8b7db1807655f2459b2bed148c8218238b0b Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Tue, 19 Jan 2021 20:49:17 +0530 Subject: [PATCH 1/5] 1. Exception handling for CryptoException and Generic exceptions 2. PKCS7 padding decrypt fix for AES/DES 3. Few tags were not supported. --- .../keymaster/KMAndroidSEProvider.java | 16 +-- .../javacard/keymaster/KMOperationImpl.java | 6 + .../javacard/keymaster/KMCipherImpl.java | 6 + .../javacard/keymaster/KMJCardSimulator.java | 28 +---- .../android/javacard/keymaster/KMUtils.java | 1 + .../android/javacard/keymaster/KMError.java | 9 ++ .../javacard/keymaster/KMKeyParameters.java | 32 +++++ .../javacard/keymaster/KMKeymasterApplet.java | 118 ++++++------------ .../javacard/keymaster/KMRepository.java | 2 +- .../javacard/keymaster/KMSEProvider.java | 72 +++++------ 10 files changed, 125 insertions(+), 165 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index aba38934..e18ae600 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -100,7 +100,7 @@ public class KMAndroidSEProvider implements KMSEProvider { (byte) 0x25, (byte) 0x51 }; static final short secp256r1_H = 1; // -------------------------------------------------------------- - public static final short AES_GCM_TAG_LENGTH = 12; + public static final short AES_GCM_TAG_LENGTH = 16; public static final short AES_GCM_NONCE_LENGTH = 12; public static final byte KEYSIZE_128_OFFSET = 0x00; public static final byte KEYSIZE_256_OFFSET = 0x01; @@ -608,7 +608,7 @@ public short aesGCMEncrypt(byte[] aesKey, short aesKeyStart, short aesKeyLen, short authTagStart, short authTagLen) { if (authTagLen != AES_GCM_TAG_LENGTH) { - KMException.throwIt(KMError.UNKNOWN_ERROR); + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); } if (nonceLen != AES_GCM_NONCE_LENGTH) { CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); @@ -1115,18 +1115,6 @@ public KMAttestationCert getAttestationCert(boolean rsaCert) { return KMAttestationCertImpl.instance(rsaCert); } - @Override - public short aesCCMSign(byte[] bufIn, short bufInStart, short buffInLength, - byte[] masterKeySecret, short masterKeyStart, short masterKeyLen, - byte[] bufOut, short bufStart) { - if (masterKeyLen > 16) { - return -1; - } - aesKeys[KEYSIZE_128_OFFSET].setKey(masterKeySecret, (short) masterKeyStart); - kdf.init(aesKeys[KEYSIZE_128_OFFSET], Signature.MODE_SIGN); - return kdf.sign(bufIn, bufInStart, buffInLength, bufOut, bufStart); - } - @Override public short cmacKdf(byte[] keyMaterial, short keyMaterialStart, short keyMaterialLen, byte[] label, short labelStart, short labelLen, diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java index b1f48827..1c7ab32d 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMOperationImpl.java @@ -161,6 +161,12 @@ public short finish(byte[] inputDataBuf, short inputDataStart, // padding byte always should be <= block size if ((short) paddingByte > blkSize || (short) paddingByte <= 0) KMException.throwIt(KMError.INVALID_ARGUMENT); + + for(short j = 1; j <= paddingByte; ++j) { + if (outputDataBuf[(short) (outputDataStart + len - j)] != paddingByte) { + KMException.throwIt(KMError.INVALID_ARGUMENT); + } + } len = (short) (len - (short) paddingByte);// remove the padding bytes } } else if (cipherAlg == KMType.AES && blockMode == KMType.GCM) { diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java index ea65a94c..264b74e5 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMCipherImpl.java @@ -121,6 +121,12 @@ public short doFinal(byte[] buffer, short startOff, short length, byte[] scratch //padding byte always should be <= block size if((short)paddingByte > blkSize || (short)paddingByte <= 0) KMException.throwIt(KMError.INVALID_ARGUMENT); + + for(short j = 1; j <= paddingByte; ++j) { + if (scratchPad[i+len -j] != paddingByte) { + KMException.throwIt(KMError.INVALID_ARGUMENT); + } + } len = (short)(len - (short)paddingByte);// remove the padding bytes } } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index 9c9e71c6..eb50fd6d 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -66,7 +66,7 @@ * creates its own RNG using PRNG. */ public class KMJCardSimulator implements KMSEProvider { - public static final short AES_GCM_TAG_LENGTH = 12; + public static final short AES_GCM_TAG_LENGTH = 16; public static final short AES_GCM_NONCE_LENGTH = 12; public static final short MAX_RND_NUM_SIZE = 64; public static final short ENTROPY_POOL_SIZE = 16; // simulator does not support 256 bit aes keys @@ -483,31 +483,7 @@ public boolean aesGCMDecrypt( public void getTrueRandomNumber(byte[] buf, short start, short length) { Util.arrayCopy(entropyPool,(short)0,buf,start,length); } - - @Override - public short aesCCMSign( - byte[] bufIn, - short bufInStart, - short buffInLength, - byte[] masterKeySecret, - short masterKeyStart, - short masterKeyLen, - byte[] bufOut, - short bufStart) { - if (masterKeyLen > 16) { - return -1; - } - AESKey key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false); - key.setKey(masterKeySecret, masterKeyStart); - byte[] in = new byte[buffInLength]; - Util.arrayCopyNonAtomic(bufIn, bufInStart,in,(short)0,buffInLength); - kdf.init(key, Signature.MODE_SIGN); - short len = kdf.sign(bufIn, bufInStart, buffInLength, bufOut, bufStart); - byte[] out = new byte[len]; - Util.arrayCopyNonAtomic(bufOut, bufStart,out,(short)0,len); - return len; - } - + public HMACKey cmacKdf(byte[] keyMaterial, short keyMaterialStart, short keyMaterialLen, byte[] label, short labelStart, short labelLen, byte[] context, short contextStart, short contextLength) { // This is hardcoded to requirement - 32 byte output with two concatenated 16 bytes K1 and K2. diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java index d9dce03b..756c3150 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -102,6 +102,7 @@ public static short convertToDate(short time, byte[] scratchPad, Util.arrayCopyNonAtomic(oneMonthMsec, (short) 0, scratchPad, (short) 8, (short) 8); monthCount = divide(scratchPad, (short) 0, (short) 8, (short) 16); + monthCount =+ 1; Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8); } diff --git a/Applet/src/com/android/javacard/keymaster/KMError.java b/Applet/src/com/android/javacard/keymaster/KMError.java index e70dc8c2..abb0e6df 100644 --- a/Applet/src/com/android/javacard/keymaster/KMError.java +++ b/Applet/src/com/android/javacard/keymaster/KMError.java @@ -92,4 +92,13 @@ public class KMError { public static short CMD_NOT_ALLOWED = 1005; public static short SW_WRONG_LENGTH = 1006; public static short INVALID_DATA = 1007; + //Crypto errors + public static short CRYPTO_ILLEGAL_USE = 1008; + public static short CRYPTO_ILLEGAL_VALUE = 1009; + public static short CRYPTO_INVALID_INIT = 1010; + public static short CRYPTO_NO_SUCH_ALGORITHM = 1011; + public static short CRYPTO_UNINITIALIZED_KEY = 1012; + //Generic Unknown error. + public static short GENERIC_UNKNOWN_ERROR = 1013; + } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java index ae759ffc..8c8475ac 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeyParameters.java @@ -100,6 +100,38 @@ public short findTag(short tagType, short tagKey){ } return ret; } + + public static boolean hasUnsupportedTags(short keyParamsPtr) { + final short[] tagArr = { + // Unsupported tags. + KMType.BOOL_TAG, KMType.TRUSTED_CONFIRMATION_REQUIRED, + KMType.BOOL_TAG, KMType.TRUSTED_USER_PRESENCE_REQUIRED, + KMType.BOOL_TAG, KMType.ALLOW_WHILE_ON_BODY, + KMType.UINT_TAG, KMType.MIN_SEC_BETWEEN_OPS, + }; + byte index = 0; + short tagInd; + short tagPtr; + short tagKey; + short tagType; + short arrPtr = KMKeyParameters.cast(keyParamsPtr).getVals(); + short len = KMArray.cast(arrPtr).length(); + while (index < len) { + tagInd = 0; + tagPtr = KMArray.cast(arrPtr).get(index); + tagKey = KMTag.getKey(tagPtr); + tagType = KMTag.getTagType(tagPtr); + while (tagInd < (short) tagArr.length) { + if ((tagArr[tagInd] == tagType) + && (tagArr[(short) (tagInd + 1)] == tagKey)) { + return true; + } + tagInd += 2; + } + index++; + } + return false; + } // KDF, ECIES_SINGLE_HASH_MODE missing from types.hal public static short makeHwEnforced(short keyParamsPtr, byte origin, diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index d9691a1e..febc7ec7 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -160,7 +160,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe public static final byte KEY_BLOB_KEYCHAR = 3; public static final byte KEY_BLOB_PUB_KEY = 4; // AES GCM constants - private static final byte AES_GCM_AUTH_TAG_LENGTH = 12; + private static final byte AES_GCM_AUTH_TAG_LENGTH = 16; private static final byte AES_GCM_NONCE_LENGTH = 12; // ComputeHMAC constants private static final short HMAC_SHARED_PARAM_MAX_SIZE = 64; @@ -245,6 +245,23 @@ private short mapISOErrorToKMError(short reason) { return KMError.UNKNOWN_ERROR; } } + + private short mapCryptoErrorToKMError(short reason) { + switch (reason) { + case CryptoException.ILLEGAL_USE: + return KMError.CRYPTO_ILLEGAL_USE; + case CryptoException.ILLEGAL_VALUE: + return KMError.CRYPTO_ILLEGAL_VALUE; + case CryptoException.INVALID_INIT: + return KMError.CRYPTO_INVALID_INIT; + case CryptoException.NO_SUCH_ALGORITHM: + return KMError.CRYPTO_NO_SUCH_ALGORITHM; + case CryptoException.UNINITIALIZED_KEY: + return KMError.CRYPTO_UNINITIALIZED_KEY; + default: + return KMError.UNKNOWN_ERROR; + } + } protected void validateApduHeader(APDU apdu) { // Read the apdu header and buffer. @@ -443,6 +460,12 @@ && isProvisioningComplete())) { } catch (ISOException exp) { sendError(apdu, mapISOErrorToKMError(exp.getReason())); freeOperations(); + } catch (CryptoException e) { + freeOperations(); + sendError(apdu, mapCryptoErrorToKMError(e.getReason())); + } catch (Exception e) { + freeOperations(); + sendError(apdu, KMError.GENERIC_UNKNOWN_ERROR); } finally { resetData(); repository.clean(); @@ -578,7 +601,6 @@ private void processAddRngEntropyCmd(APDU apdu) { //reclaim memory repository.reclaimMemory(bufferLength); - // Process KMByteBlob blob = KMByteBlob.cast(KMArray.cast(args).get((short) 0)); // Maximum 2KiB of seed is allowed. @@ -606,7 +628,6 @@ private void processGetCertChainCmd(APDU apdu) { sendOutgoing(apdu); } - private void processProvisionAttestationCertParams(APDU apdu) { receiveIncoming(apdu); // Arguments @@ -620,7 +641,6 @@ private void processProvisionAttestationCertParams(APDU apdu) { //reclaim memory repository.reclaimMemory(bufferLength); - // save issuer - DER Encoded tmpVariables[0] = KMArray.cast(args).get((short) 0); repository.setIssuer( @@ -1607,7 +1627,6 @@ private void processFinishOperationCmd(APDU apdu) { // Finish trusted Confirmation operation switch (op.getPurpose()) { case KMType.SIGN: - finishTrustedConfirmationOperation(op); case KMType.VERIFY: finishSigningVerifyingOperation(op, scratchPad); break; @@ -1631,7 +1650,6 @@ private void processFinishOperationCmd(APDU apdu) { KMArray.cast(tmpVariables[2]).add((short) 1, tmpVariables[1]); KMArray.cast(tmpVariables[2]).add((short) 2, data[OUTPUT_DATA]); - bufferStartOffset = repository.allocAvailableMemory(); // Encode the response bufferLength = encoder.encode(tmpVariables[2], buffer, bufferStartOffset); @@ -1905,31 +1923,6 @@ private void finishSigningVerifyingOperation(KMOperationState op, byte[] scratch } } - private void finishTrustedConfirmationOperation(KMOperationState op) { - // Perform trusted confirmation if required - if (op.isTrustedConfirmationRequired()) { - tmpVariables[0] = - KMKeyParameters.findTag( - KMType.BYTES_TAG, KMType.CONFIRMATION_TOKEN, data[KEY_PARAMETERS]); - if (tmpVariables[0] == KMType.INVALID_VALUE) { - KMException.throwIt(KMError.INVALID_ARGUMENT); - } - tmpVariables[0] = KMByteTag.cast(tmpVariables[0]).getValue(); - boolean verified = - op.getTrustedConfirmationSigner() - .verify( - KMByteBlob.cast(data[INPUT_DATA]).getBuffer(), - KMByteBlob.cast(data[INPUT_DATA]).getStartOff(), - KMByteBlob.cast(data[INPUT_DATA]).length(), - KMByteBlob.cast(tmpVariables[0]).getBuffer(), - KMByteBlob.cast(tmpVariables[0]).getStartOff(), - KMByteBlob.cast(tmpVariables[0]).length()); - if (!verified) { - KMException.throwIt(KMError.VERIFICATION_FAILED); - } - } - } - private void authorizeUpdateFinishOperation(KMOperationState op, byte[] scratchPad) { // If one time user Authentication is required if (op.isSecureUserIdReqd() && !op.isAuthTimeoutValidated()) { @@ -2111,8 +2104,6 @@ private void processUpdateOperationCmd(APDU apdu) { KMByteBlob.cast(data[INPUT_DATA]).getBuffer(), KMByteBlob.cast(data[INPUT_DATA]).getStartOff(), KMByteBlob.cast(data[INPUT_DATA]).length()); - // update trusted confirmation operation - updateTrustedConfirmationOperation(op); data[OUTPUT_DATA] = KMType.INVALID_VALUE; } else if (op.getPurpose() == KMType.ENCRYPT || op.getPurpose() == KMType.DECRYPT) { // Update for encrypt/decrypt using RSA will not be supported because to do this op state @@ -2200,16 +2191,6 @@ private void processUpdateOperationCmd(APDU apdu) { sendOutgoing(apdu); } - private void updateTrustedConfirmationOperation(KMOperationState op) { - if (op.isTrustedConfirmationRequired()) { - op.getTrustedConfirmationSigner() - .update( - KMByteBlob.cast(data[INPUT_DATA]).getBuffer(), - KMByteBlob.cast(data[INPUT_DATA]).getStartOff(), - KMByteBlob.cast(data[INPUT_DATA]).length()); - } - } - private void processBeginOperationCmd(APDU apdu) { // Receive the incoming request fully from the master into buffer. receiveIncoming(apdu); @@ -2257,7 +2238,6 @@ private void processBeginOperationCmd(APDU apdu) { authorizeAndBeginOperation(op, scratchPad); switch (op.getPurpose()) { case KMType.SIGN: - beginTrustedConfirmationOperation(op); case KMType.VERIFY: beginSignVerifyOperation(op); break; @@ -2304,42 +2284,6 @@ private void processBeginOperationCmd(APDU apdu) { sendOutgoing(apdu); } - private void beginTrustedConfirmationOperation(KMOperationState op) { - // Check for trusted confirmation - if required then set the signer in op state. - if (KMKeyParameters.findTag( - KMType.BOOL_TAG, KMType.TRUSTED_CONFIRMATION_REQUIRED, data[HW_PARAMETERS]) - != KMType.INVALID_VALUE) { - // get operation - // get the hmac key - short key = repository.getComputedHmacKey(); - if (key == 0) { - KMException.throwIt(KMError.OPERATION_CANCELLED); - } - /* - op.setTrustedConfirmationSigner(seProvider.initSymmetricOperation( - KMType.VERIFY,KMType.HMAC,KMType.SHA2_256,(byte)0,(byte)0,repository.getComputedHmacKey(), - (short) 0, (short) repository.getComputedHmacKey().length,null,(short)0,(short)0,(short)0)); - */ - op.setTrustedConfirmationSigner( - seProvider.initSymmetricOperation( - KMType.VERIFY, - KMType.HMAC, - KMType.SHA2_256, - (byte) 0, - (byte) 0, - KMByteBlob.cast(key).getBuffer(), - KMByteBlob.cast(key).getStartOff(), - KMByteBlob.cast(key).length(), - null, - (short) 0, - (short) 0, - (short) 0)); - - op.getTrustedConfirmationSigner() - .update(confirmationToken, (short) 0, (short) confirmationToken.length); - } - } - private void authorizeAlgorithm(KMOperationState op) { short alg = KMEnumTag.getValue(KMType.ALGORITHM, data[HW_PARAMETERS]); if (alg == KMType.INVALID_VALUE) { @@ -3435,6 +3379,20 @@ private static void processGenerateKey(APDU apdu) { KMException.throwIt(KMError.UNSUPPORTED_KEY_SIZE); } } + // Only STANDALONE is supported for BLOB_USAGE_REQ tag. + tmpVariables[0] = + KMKeyParameters.findTag(KMType.ENUM_TAG, KMType.BLOB_USAGE_REQ, data[KEY_PARAMETERS]); + if (tmpVariables[0] != KMType.INVALID_VALUE) { + tmpVariables[0] = KMEnumTag.getValue(KMType.BLOB_USAGE_REQ, data[KEY_PARAMETERS]); + if (tmpVariables[0] != KMType.STANDALONE) { + KMException.throwIt(KMError.UNSUPPORTED_TAG); + } + } + //Check if the tags are supported. + if(KMKeyParameters.hasUnsupportedTags(data[KEY_PARAMETERS])) { + KMException.throwIt(KMError.UNSUPPORTED_TAG); + } + // Check algorithm and dispatch to appropriate handler. switch (tmpVariables[3]) { case KMType.RSA: diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index b8dc8b8d..062e31b5 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -84,7 +84,7 @@ public class KMRepository implements KMUpgradable { public static final short DEVICE_LOCK_FLAG_SIZE = 1; public static final short BOOT_STATE_SIZE = 1; public static final short MAX_BLOB_STORAGE = 8; - public static final short AUTH_TAG_LENGTH = 12; + public static final short AUTH_TAG_LENGTH = 16; public static final short AUTH_TAG_ENTRY_SIZE = 15; public static final short MAX_OPS = 4; public static final byte BOOT_KEY_MAX_SIZE = 32; diff --git a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java index 81b35db2..3e981c9a 100644 --- a/Applet/src/com/android/javacard/keymaster/KMSEProvider.java +++ b/Applet/src/com/android/javacard/keymaster/KMSEProvider.java @@ -49,11 +49,12 @@ void createAsymmetricKey( short[] lengths); /** - * Verify that the imported key is valid. + * Verify that the imported key is valid. If the algorithm and/or keysize are not supported then it + * should throw a CryptoException. * * @param alg will be KMType.AES, KMType.DES or KMType.HMAC. * @param keysize will be 128 or 256 for AES or DES. It can be 64 to 512 (multiple of 8) for HMAC. - * @param buf is the buffer in which key has to be returned + * @param buf is the buffer that contains the symmetric key. * @param startOff is the start offset. * @param length of the data in the buf. This should match the keysize (in bytes). * @return true if the symmetric key is supported and valid. @@ -63,14 +64,15 @@ void createAsymmetricKey( /** * Validate that the imported asymmetric key pair is valid. For RSA the public key exponent must * always be 0x010001. The key size of RSA key pair must be 2048 bits and key size of EC key pair - * must be for p256 curve. + * must be for p256 curve. If the algorithms are not supported then it should throw a + * CryptoException. * * @param alg will be KMType.RSA or KMType.EC. - * @param privKeyBuf is the buffer to return the private key exponent in case of RSA or private + * @param privKeyBuf is the buffer that contains the private key exponent in case of RSA or private * key in case of EC. * @param privKeyStart is the start offset. * @param privKeyLength is the length of this private key buffer. - * @param pubModBuf is the buffer to return the modulus in case of RSA or public key in case of + * @param pubModBuf is the buffer that contains the modulus in case of RSA or public key in case of * EC. * @param pubModStart is the start of offset. * @param pubModLength is the length of this public key buffer. @@ -88,14 +90,14 @@ boolean importAsymmetricKey( /** * This is a oneshot operation that generates random number of desired length. * - * @param num is the buffer in which random number is returned to applet. + * @param num is the buffer in which random number is returned to the applet. * @param offset is start of the buffer. * @param length indicates the size of buffer and desired length of random number in bytes. */ void newRandomNumber(byte[] num, short offset, short length); /** - * This is a oneshot operation that adds the entropy to the entroy pool. This operation + * This is a oneshot operation that adds the entropy to the entropy pool. This operation * corresponds to addRndEntropy command. This method may ignore the added entropy value if the SE * provider does not support it. * @@ -108,14 +110,16 @@ boolean importAsymmetricKey( /** * This is a oneshot operation that generates and returns back a true random number. * - * @param num is the buffer in which entropy value is given. + * @param num is the buffer in which entropy value is returned. * @param offset is start of the buffer. * @param length length of the buffer. */ void getTrueRandomNumber(byte[] num, short offset, short length); /** - * This is a oneshot operation that performs encryption operation using AES GCM algorithm. + * This is a oneshot operation that performs encryption operation using AES GCM algorithm. It throws + * CryptoException if algorithm is not supported or if tag length is not equal to 16 or + * nonce length is not equal to 12. * * @param aesKey is the buffer that contains 128 bit or 256 bit aes key used to encrypt. * @param aesKeyStart is the start in aes key buffer. @@ -156,7 +160,8 @@ short aesGCMEncrypt( short authTagLen); /** - * This is a oneshot operation that performs decryption operation using AES GCM algorithm. + * This is a oneshot operation that performs decryption operation using AES GCM algorithm. It throws + * CryptoException if algorithm is not supported. * * @param aesKey is the buffer that contains 128 bit or 256 bit aes key used to encrypt. * @param aesKeyStart is the start in aes key buffer. @@ -164,7 +169,7 @@ short aesGCMEncrypt( * @param encData is the buffer of the input encrypted data. * @param encDataStart is the start of the encrypted data buffer. * @param encDataLen is the length of the data buffer. - * @param data is the buffer that contains output data to encrypt. + * @param data is the buffer that contains output decrypted data. * @param dataStart is the start of the data buffer. * @param nonce is the buffer of nonce. * @param nonceStart is the start of the nonce buffer. @@ -196,30 +201,7 @@ boolean aesGCMDecrypt( short authTagStart, short authTagLen); - /** - * This is a oneshot operation that performs signing using AES CCM algorithm. - * - * @param data is the input data buffer. - * @param dataStart is the start of the buffer. - * @param dataLen is the length of the input data - * @param aesKey is the aesKey buffer either 128 bit or 256 bit aes key. - * @param aesKeyStart is the start of the aes key. - * @param aesKeyLen is the length of the aes key buffer in bytes. - * @param signature is the output signature buffer. - * @param signatureStart is the start of the signature buffer. - * @return length of the signature buffer. - */ - short aesCCMSign( - byte[] data, - short dataStart, - short dataLen, - byte[] aesKey, - short aesKeyStart, - short aesKeyLen, - byte[] signature, - short signatureStart); - - /** + /** * This is a oneshot operation that performs key derivation function using cmac kdf (CKDF) as * defined in android keymaster hal definition. * @@ -299,7 +281,8 @@ boolean hmacVerify( /** * This is a oneshot operation that decrypts the data using RSA algorithm with oaep256 padding. - * The public exponent is always 0x010001. + * The public exponent is always 0x010001. It throws CryptoException if OAEP encoding validation + * fails. * * @param privExp is the private exponent (2048 bit) buffer. * @param privExpStart is the start of the private exponent buffer. @@ -309,8 +292,8 @@ boolean hmacVerify( * @param modLength is the length of the modulus buffer in bytes. * @param inputDataBuf is the buffer of the input data. * @param inputDataStart is the start of the input data buffer. - * @param inputDataLength is the length of the inpur data buffer in bytes. - * @param outputDataBuf is the buffer of the decrypted data buffer. + * @param inputDataLength is the length of the input data buffer in bytes. + * @param outputDataBuf is the output buffer that contains the decrypted data. * @param outputDataStart is the start of the output data buffer. * @return length of the decrypted data. */ @@ -336,11 +319,11 @@ short rsaDecipherOAEP256( * @param inputDataBuf is the buffer of the input data. * @param inputDataStart is the start of the input data buffer. * @param inputDataLength is the length of the inpur data buffer in bytes. - * @param outputDataBuf is the buffer of the decrypted data buffer. + * @param outputDataBuf is the output buffer that contains the signature. * @param outputDataStart is the start of the output data buffer. * @return length of the decrypted data. */ - public short ecSign256( + short ecSign256( byte[] secret, short secretStart, short secretLength, @@ -354,7 +337,7 @@ public short ecSign256( * This creates a persistent operation for signing, verify, encryption and decryption using HMAC, * AES and DES algorithms when keymaster hal's beginOperation function is executed. The * KMOperation instance can be reclaimed by the seProvider when KMOperation is finished or - * aborted. + * aborted. It throws CryptoException if algorithm is not supported. * * @param purpose is KMType.ENCRYPT or KMType.DECRYPT for AES and DES algorithm. It will be * KMType.SIGN and KMType.VERIFY for HMAC algorithm @@ -391,7 +374,8 @@ KMOperation initSymmetricOperation( * This creates a persistent operation for signing, verify, encryption and decryption using RSA * and EC algorithms when keymaster hal's beginOperation function is executed. For RSA the public * exponent is always 0x0100101. For EC the curve is always p256. The KMOperation instance can be - * reclaimed by the seProvider when KMOperation is finished or aborted. + * reclaimed by the seProvider when KMOperation is finished or aborted. It throws CryptoException + * if algorithm is not supported. * * @param purpose is KMType.ENCRYPT or KMType.DECRYPT for RSA. It will be * KMType.SIGN and * KMType.VERIFY for RSA and EC algorithms. @@ -439,12 +423,12 @@ KMOperation initAsymmetricOperation( * @param len is the length of the buffer. * @param totalLen is the total length of cert chain. */ - public void persistPartialCertificateChain(byte[] buf, short offset, short len, short totalLen); + void persistPartialCertificateChain(byte[] buf, short offset, short len, short totalLen); /** * This operation clears the certificate chain from persistent memory. */ - public void clearCertificateChain(); + void clearCertificateChain(); /** * The operation reads the certificate chain from persistent memory. From f297133d7d5519212f453aba7ce7895d41ddaf09 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 20 Jan 2021 20:41:07 +0530 Subject: [PATCH 2/5] Remove trusted confirmation related code --- .../android/javacard/keymaster/KMUtils.java | 13 +++++----- .../android/javacard/keymaster/KMUtils.java | 14 +++++----- .../android/javacard/keymaster/KMError.java | 26 +++++++++---------- .../javacard/keymaster/KMKeymasterApplet.java | 1 - .../javacard/keymaster/KMOperationState.java | 22 ++-------------- .../javacard/keymaster/KMRepository.java | 4 +-- 6 files changed, 30 insertions(+), 50 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java index d9dce03b..08309f86 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -13,23 +13,23 @@ public class KMUtils { public static final byte[] oneDayMsec = { 0, 0, 0, 0, 0x05, 0x26, 0x5C, 0x00 }; // 86400000 msec public static final byte[] oneMonthMsec = { - 0, 0, 0, 0, (byte) 0x9A, 0x7E, (byte) 0xC8, 0x00 }; // 2592000000 msec + 0, 0, 0, 0, (byte) 0x9C,(byte) 0xBE, (byte) 0xBD, 0x50}; // 2629746000 msec public static final byte[] oneYearMsec = { - 0, 0, 0, 0x07, 0x57, (byte) 0xB1, 0x2C, 0x00 }; // 31536000000 msec + 0, 0, 0, 0x75, (byte) 0x8F, 0x0D, (byte) 0xFC, 0x00 }; // 31556952000 msec // Leap year + 3 yrs public static final byte[] fourYrsMsec = { - 0, 0, 0, 0x1D, 0x63, (byte) 0xEB, 0x0C, 0x00 }; // 126230400000 msec + 0, 0, 0, 0x1D, 0x63, (byte) 0xC3, 0x7F, 0x00 }; // 126227808000 msec public static final byte[] firstJan2020 = { - 0, 0, 0x01, 0x6F, 0x60, 0x1E, 0x5C, 0x00 }; // 1577865600000 msec + 0, 0, 0x01, 0x76, (byte) 0xBB, 0x3E, (byte) 0x70, 0x40 }; // 1609459200000 msec public static final byte[] firstJan2051 = { - 0, 0, 0x02, 0x53, 0x27, (byte) 0xC5, (byte) 0x90, 0x00 }; // 2556172800000 + 0, 0, 0x02, 0x53, 0x26, (byte) 0x0E, (byte) 0x1C, 0x00 }; // 2556144000000 // msec // -------------------------------------- public static short convertToDate(short time, byte[] scratchPad, boolean utcFlag) { short yrsCount = 0; - short monthCount = 0; + short monthCount = 1; short dayCount = 0; short hhCount = 0; short mmCount = 0; @@ -102,6 +102,7 @@ public static short convertToDate(short time, byte[] scratchPad, Util.arrayCopyNonAtomic(oneMonthMsec, (short) 0, scratchPad, (short) 8, (short) 8); monthCount = divide(scratchPad, (short) 0, (short) 8, (short) 16); + monthCount++; Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8); } diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java index 756c3150..08309f86 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -13,23 +13,23 @@ public class KMUtils { public static final byte[] oneDayMsec = { 0, 0, 0, 0, 0x05, 0x26, 0x5C, 0x00 }; // 86400000 msec public static final byte[] oneMonthMsec = { - 0, 0, 0, 0, (byte) 0x9A, 0x7E, (byte) 0xC8, 0x00 }; // 2592000000 msec + 0, 0, 0, 0, (byte) 0x9C,(byte) 0xBE, (byte) 0xBD, 0x50}; // 2629746000 msec public static final byte[] oneYearMsec = { - 0, 0, 0, 0x07, 0x57, (byte) 0xB1, 0x2C, 0x00 }; // 31536000000 msec + 0, 0, 0, 0x75, (byte) 0x8F, 0x0D, (byte) 0xFC, 0x00 }; // 31556952000 msec // Leap year + 3 yrs public static final byte[] fourYrsMsec = { - 0, 0, 0, 0x1D, 0x63, (byte) 0xEB, 0x0C, 0x00 }; // 126230400000 msec + 0, 0, 0, 0x1D, 0x63, (byte) 0xC3, 0x7F, 0x00 }; // 126227808000 msec public static final byte[] firstJan2020 = { - 0, 0, 0x01, 0x6F, 0x60, 0x1E, 0x5C, 0x00 }; // 1577865600000 msec + 0, 0, 0x01, 0x76, (byte) 0xBB, 0x3E, (byte) 0x70, 0x40 }; // 1609459200000 msec public static final byte[] firstJan2051 = { - 0, 0, 0x02, 0x53, 0x27, (byte) 0xC5, (byte) 0x90, 0x00 }; // 2556172800000 + 0, 0, 0x02, 0x53, 0x26, (byte) 0x0E, (byte) 0x1C, 0x00 }; // 2556144000000 // msec // -------------------------------------- public static short convertToDate(short time, byte[] scratchPad, boolean utcFlag) { short yrsCount = 0; - short monthCount = 0; + short monthCount = 1; short dayCount = 0; short hhCount = 0; short mmCount = 0; @@ -102,7 +102,7 @@ public static short convertToDate(short time, byte[] scratchPad, Util.arrayCopyNonAtomic(oneMonthMsec, (short) 0, scratchPad, (short) 8, (short) 8); monthCount = divide(scratchPad, (short) 0, (short) 8, (short) 16); - monthCount =+ 1; + monthCount++; Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8); } diff --git a/Applet/src/com/android/javacard/keymaster/KMError.java b/Applet/src/com/android/javacard/keymaster/KMError.java index abb0e6df..85c71654 100644 --- a/Applet/src/com/android/javacard/keymaster/KMError.java +++ b/Applet/src/com/android/javacard/keymaster/KMError.java @@ -85,20 +85,20 @@ public class KMError { public static short UNKNOWN_ERROR = 1000; //Extended errors - public static short SW_CONDITIONS_NOT_SATISFIED = 1001; - public static short UNSUPPORTED_CLA = 1002; - public static short INVALID_P1P2 = 1003; - public static short UNSUPPORTED_INSTRUCTION = 1004; - public static short CMD_NOT_ALLOWED = 1005; - public static short SW_WRONG_LENGTH = 1006; - public static short INVALID_DATA = 1007; + public static short SW_CONDITIONS_NOT_SATISFIED = 10001; + public static short UNSUPPORTED_CLA = 10002; + public static short INVALID_P1P2 = 10003; + public static short UNSUPPORTED_INSTRUCTION = 10004; + public static short CMD_NOT_ALLOWED = 10005; + public static short SW_WRONG_LENGTH = 10006; + public static short INVALID_DATA = 10007; //Crypto errors - public static short CRYPTO_ILLEGAL_USE = 1008; - public static short CRYPTO_ILLEGAL_VALUE = 1009; - public static short CRYPTO_INVALID_INIT = 1010; - public static short CRYPTO_NO_SUCH_ALGORITHM = 1011; - public static short CRYPTO_UNINITIALIZED_KEY = 1012; + public static short CRYPTO_ILLEGAL_USE = 10008; + public static short CRYPTO_ILLEGAL_VALUE = 10009; + public static short CRYPTO_INVALID_INIT = 10010; + public static short CRYPTO_NO_SUCH_ALGORITHM = 10011; + public static short CRYPTO_UNINITIALIZED_KEY = 10012; //Generic Unknown error. - public static short GENERIC_UNKNOWN_ERROR = 1013; + public static short GENERIC_UNKNOWN_ERROR = 10013; } diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index febc7ec7..a37e6aa8 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -1624,7 +1624,6 @@ private void processFinishOperationCmd(APDU apdu) { } // Authorize the finish operation authorizeUpdateFinishOperation(op, scratchPad); - // Finish trusted Confirmation operation switch (op.getPurpose()) { case KMType.SIGN: case KMType.VERIFY: diff --git a/Applet/src/com/android/javacard/keymaster/KMOperationState.java b/Applet/src/com/android/javacard/keymaster/KMOperationState.java index 6647a6a8..347c9920 100644 --- a/Applet/src/com/android/javacard/keymaster/KMOperationState.java +++ b/Applet/src/com/android/javacard/keymaster/KMOperationState.java @@ -28,7 +28,7 @@ public class KMOperationState { public static final byte MAX_DATA = 20; - public static final byte MAX_REFS = 2; + public static final byte MAX_REFS = 1; private static final byte DATA = 0; private static final byte REFS = 1; // byte type @@ -53,9 +53,6 @@ public class KMOperationState { // Object References private static final byte OPERATION = 0; - private static final byte HMAC_SIGNER = 1; - - private static KMOperation hmacSigner; // used for trusted confirmation. private static KMOperation op; private static byte[] data; private static Object[] slot; @@ -85,14 +82,13 @@ public static KMOperationState read(Object[] slot) { Util.arrayCopy((byte[]) slot[DATA], (short) 0, data, (short) 0, (short) data.length); Object[] ops = ((Object[]) slot[REFS]); op = (KMOperation) ops[OPERATION]; - hmacSigner = (KMOperation) ops[HMAC_SIGNER]; KMOperationState.slot = slot; return opState; } public void persist() { if (!dFlag) return; - KMRepository.instance().persistOperation(data, Util.getShort(data, OP_HANDLE), op, hmacSigner); + KMRepository.instance().persistOperation(data, Util.getShort(data, OP_HANDLE), op); dFlag = false; } @@ -104,21 +100,8 @@ public short getKeySize() { return Util.getShort(data, KEY_SIZE); } - public void setTrustedConfirmationSigner(KMOperation hmacSigner) { - KMOperationState.hmacSigner = hmacSigner; - } - - public KMOperation getTrustedConfirmationSigner() { - return KMOperationState.hmacSigner; - } - - public boolean isTrustedConfirmationRequired() { - return KMOperationState.hmacSigner != null; - } - public void reset() { dFlag = false; - hmacSigner = null; op = null; slot = null; Util.arrayFillNonAtomic( @@ -135,7 +118,6 @@ public void release() { Util.arrayFillNonAtomic( (byte[]) slot[0], (short) 0, (short) ((byte[]) slot[0]).length, (byte) 0); ops[OPERATION] = null; - ops[HMAC_SIGNER] = null; JCSystem.commitTransaction(); reset(); } diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index 062e31b5..c2809c08 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -148,7 +148,7 @@ public KMOperationState reserveOperation(){ } //TODO refactor following method - public void persistOperation(byte[] data, short opHandle, KMOperation op, KMOperation hmacSigner) { + public void persistOperation(byte[] data, short opHandle, KMOperation op) { short index = 0; byte[] opId; //Update an existing operation state. @@ -160,7 +160,6 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op, KMOper Util.arrayCopy(data, (short) 0, (byte[]) slot[0], (short) 0, (short) ((byte[]) slot[0]).length); Object[] ops = ((Object[]) slot[1]); ops[0] = op; - ops[1] = hmacSigner; JCSystem.commitTransaction(); return; } @@ -178,7 +177,6 @@ public void persistOperation(byte[] data, short opHandle, KMOperation op, KMOper Util.arrayCopy(data, (short) 0, (byte[]) slot[0], (short) 0, (short) ((byte[]) slot[0]).length); Object[] ops = ((Object[]) slot[1]); ops[0] = op; - ops[1] = hmacSigner; JCSystem.commitTransaction(); break; } From 489e175a4ef80bd03e90f2ae8753b718d5c9cb17 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Wed, 20 Jan 2021 22:17:20 +0530 Subject: [PATCH 3/5] certificate chain input validation --- .../com/android/javacard/keymaster/KMAndroidSEProvider.java | 3 +++ .../src/com/android/javacard/keymaster/KMJCardSimulator.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java index e18ae600..b2833e8b 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAndroidSEProvider.java @@ -1143,6 +1143,9 @@ public void persistPartialCertificateChain(byte[] buf, short offset, short len, // Next single byte holds the array header. // Next 3 bytes holds the Byte array header with the cert1 length. // Next 3 bytes holds the Byte array header with the cert2 length. + if (totalLen > CERT_CHAIN_MAX_SIZE) { + KMException.throwIt(KMError.INVALID_INPUT_LENGTH); + } short persistedLen = Util.getShort(certificateChain, (short) 0); if (persistedLen > totalLen) { KMException.throwIt(KMError.INVALID_INPUT_LENGTH); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java index eb50fd6d..a9a6a937 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMJCardSimulator.java @@ -1246,6 +1246,9 @@ public void persistPartialCertificateChain(byte[] buf, short offset, // Next single byte holds the array header. // Next 3 bytes holds the Byte array header with the cert1 length. // Next 3 bytes holds the Byte array header with the cert2 length. + if (totalLen > CERT_CHAIN_MAX_SIZE) { + KMException.throwIt(KMError.INVALID_INPUT_LENGTH); + } short persistedLen = Util.getShort(certificateChain, (short) 0); if (persistedLen > totalLen) { KMException.throwIt(KMError.INVALID_INPUT_LENGTH); From 7d34a133433ab6de1fedfb692f976b9ad678c148 Mon Sep 17 00:00:00 2001 From: BKSSM Venkateswarlu Date: Thu, 21 Jan 2021 12:18:38 +0530 Subject: [PATCH 4/5] 1. Renamed INS_SHARED_SECRET to INS_PRESHARED_SECRET. 2. Removed AuthorityKeyIdentifier. --- .../keymaster/KMAttestationCertImpl.java | 93 +------------------ .../keymaster/KMAttestationCertImpl.java | 81 ---------------- .../javacard/keymaster/KMAttestationCert.java | 8 -- .../javacard/keymaster/KMKeymasterApplet.java | 26 ++---- .../javacard/keymaster/KMRepository.java | 48 ++++------ 5 files changed, 32 insertions(+), 224 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 40bd751b..5a36e3c3 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -30,8 +30,6 @@ public class KMAttestationCertImpl implements KMAttestationCert { private static final byte[] androidExtn = { 0x06, 0x0A, 0X2B, 0X06, 0X01, 0X04, 0X01, (byte) 0XD6, 0X79, 0X02, 0X01, 0X11 }; - // Authority Key Identifier Extn - 2.5.29.35 - private static final byte[] authKeyIdExtn = {0x06, 0x03, 0X55, 0X1D, 0X23}; private static final short ECDSA_MAX_SIG_LEN = 72; //Signature algorithm identifier - always ecdsaWithSha256 - 1.2.840.10045.4.3.2 @@ -95,7 +93,6 @@ public class KMAttestationCertImpl implements KMAttestationCert { private static short verifiedBootKey; private static byte verifiedState; private static short verifiedHash; - private static short authKey; private static short issuer; private static short signPriv; @@ -138,7 +135,6 @@ private static void init() { verifiedState = 0; rsaCert = true; deviceLocked = 0; - authKey = 0; signPriv = 0; } @@ -148,12 +144,6 @@ public KMAttestationCert verifiedBootHash(short obj) { return this; } - @Override - public KMAttestationCert authKey(short obj) { - authKey = obj; - return this; - } - @Override public KMAttestationCert verifiedBootKey(short obj) { verifiedBootKey = obj; @@ -259,46 +249,6 @@ private void createKeyUsage(short tag) { } } - private static void encodeCert( - short buf, - short keyChar, - short uniqueId, - short notBefore, - short notAfter, - short pubKey, - short attChallenge, - short attAppId, - boolean rsaCert) { - init(); - stack = KMByteBlob.cast(buf).getBuffer(); - start = KMByteBlob.cast(buf).getStartOff(); - length = KMByteBlob.cast(buf).length(); - stackPtr = (short) (start + length); - /* KMAttestationCertImpl.attChallenge = attChallenge; - KMAttestationCertImpl.attAppId = attAppId; - KMAttestationCertImpl.hwParams = KMKeyCharacteristics.cast(keyChar).getHardwareEnforced(); - KMAttestationCertImpl.swParams = KMKeyCharacteristics.cast(keyChar).getSoftwareEnforced(); - KMAttestationCertImpl.notBefore = notBefore; - KMAttestationCertImpl.notAfter = notAfter; - KMAttestationCertImpl.pubKey = pubKey; - KMAttestationCertImpl.uniqueId = uniqueId; - - */ - short last = stackPtr; - decrementStackPtr((short) 256); - signatureOffset = stackPtr; - pushBitStringHeader((byte) 0, (short) (last - stackPtr)); - // signatureOffset = pushSignature(null, (short) 0, (short) 256); - pushAlgorithmId(X509SignAlgIdentifier); - tbsLength = stackPtr; - pushTbsCert(rsaCert); - tbsOffset = stackPtr; - tbsLength = (short) (tbsLength - tbsOffset); - pushSequenceHeader((short) (last - stackPtr)); - // print(stack, stackPtr, (short)(last - stackPtr)); - certStart = stackPtr; - } - private static void pushTbsCert(boolean rsaCert) { short last = stackPtr; pushExtensions(); @@ -335,7 +285,6 @@ private static void pushExtensions() { short last = stackPtr; // byte keyusage = 0; // byte unusedBits = 8; - pushAuthKeyId(); /* if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.SIGN, hwParams)) { keyusage = (byte) (keyusage | keyUsageSign); @@ -480,19 +429,13 @@ private static void pushKeyDescription() { private static void pushSWParams() { short last = stackPtr; - // ATTESTATION_APPLICATION_ID 709 is softwareEnforced. + // Below are the allowed softwareEnforced Authorization tags inside the attestation certificate's extension. short[] tagIds = { KMType.ATTESTATION_APPLICATION_ID, KMType.CREATION_DATETIME, KMType.USAGE_EXPIRE_DATETIME, KMType.ORIGINATION_EXPIRE_DATETIME, KMType.ACTIVE_DATETIME, KMType.UNLOCKED_DEVICE_REQUIRED }; byte index = 0; do { - /* - if(tagIds[index] == KMType.ATTESTATION_APPLICATION_ID) { - pushAttIds(tagIds[index]); - continue; - } - */ pushParams(swParams, swParamsIndex, tagIds[index]); } while (++index < tagIds.length); pushSequenceHeader((short) (last - stackPtr)); @@ -500,7 +443,7 @@ private static void pushSWParams() { private static void pushHWParams() { short last = stackPtr; - // Attestation ids are not included. As per VTS attestation ids are not supported currenlty. + // Below are the allowed hardwareEnforced Authorization tags inside the attestation certificate's extension. short[] tagIds = { KMType.BOOT_PATCH_LEVEL, KMType.VENDOR_PATCH_LEVEL, KMType.OS_PATCH_LEVEL, KMType.OS_VERSION, KMType.ROOT_OF_TRUST, @@ -511,9 +454,9 @@ private static void pushHWParams() { KMType.ROLLBACK_RESISTANCE, KMType.RSA_PUBLIC_EXPONENT, KMType.ECCURVE, KMType.PADDING, KMType.DIGEST, KMType.KEYSIZE, KMType.ALGORITHM, KMType.PURPOSE }; + byte index = 0; do { - // if(pushAttIds(tagIds[index])) continue; if (tagIds[index] == KMType.ROOT_OF_TRUST) { pushRoT(); continue; @@ -600,7 +543,6 @@ private static void pushTag(short tag) { // } private static void pushRoT() { short last = stackPtr; - byte val = 0x00; // verified boot hash // pushOctetString(repo.verifiedBootHash, (short) 0, (short) repo.verifiedBootHash.length); pushOctetString( @@ -764,39 +706,10 @@ private static void pushKeyUsage(byte keyUsage, byte unusedBits) { pushSequenceHeader((short) (last - stackPtr)); } - // SEQUENCE {ObjId, OCTET STRING{SEQUENCE{[0]keyIdentifier}}} - private static void pushAuthKeyId() { - short last = stackPtr; - // if (repo.getAuthKeyId() == 0) return; - if (authKey == 0) return; - - pushKeyIdentifier( - KMByteBlob.cast(authKey).getBuffer(), - KMByteBlob.cast(authKey).getStartOff(), - KMByteBlob.cast(authKey).length()); - pushSequenceHeader((short) (last - stackPtr)); - pushOctetStringHeader((short) (last - stackPtr)); - pushBytes(authKeyIdExtn, (short) 0, (short) authKeyIdExtn.length); // ObjId - pushSequenceHeader((short) (last - stackPtr)); - } - - private static void pushKeyIdentifier(byte[] buf, short start, short len) { - pushBytes(buf, start, len); // keyIdentifier - pushLength(len); // len - pushByte((byte) 0x80); // Context specific tag [0] - } - private static void pushAlgorithmId(byte[] algId) { pushBytes(algId, (short) 0, (short) algId.length); } - private static short pushSignature(byte[] buf, short start, short len) { - pushBytes(buf, start, len); - short signatureOff = stackPtr; - pushBitStringHeader((byte) 0, len); - return signatureOff; - } - private static void pushIntegerHeader(short len) { pushLength(len); pushByte((byte) 0x02); diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java index 136ec4ba..cd9567d3 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java @@ -30,8 +30,6 @@ public class KMAttestationCertImpl implements KMAttestationCert { private static final byte[] androidExtn = { 0x06, 0x0A, 0X2B, 0X06, 0X01, 0X04, 0X01, (byte) 0XD6, 0X79, 0X02, 0X01, 0X11 }; - // Authority Key Identifier Extn - 2.5.29.35 - private static final byte[] authKeyIdExtn = {0x06, 0x03, 0X55, 0X1D, 0X23}; private static final short ECDSA_MAX_SIG_LEN = 72; //Signature algorithm identifier - always ecdsaWithSha256 - 1.2.840.10045.4.3.2 @@ -95,7 +93,6 @@ public class KMAttestationCertImpl implements KMAttestationCert { private static short verifiedBootKey; private static byte verifiedState; private static short verifiedHash; - private static short authKey; private static short issuer; private static short signPriv; @@ -138,7 +135,6 @@ private static void init() { verifiedState = 0; rsaCert = true; deviceLocked = 0; - authKey = 0; signPriv = 0; } @@ -148,12 +144,6 @@ public KMAttestationCert verifiedBootHash(short obj) { return this; } - @Override - public KMAttestationCert authKey(short obj) { - authKey = obj; - return this; - } - @Override public KMAttestationCert verifiedBootKey(short obj) { verifiedBootKey = obj; @@ -259,46 +249,6 @@ private void createKeyUsage(short tag) { } } - private static void encodeCert( - short buf, - short keyChar, - short uniqueId, - short notBefore, - short notAfter, - short pubKey, - short attChallenge, - short attAppId, - boolean rsaCert) { - init(); - stack = KMByteBlob.cast(buf).getBuffer(); - start = KMByteBlob.cast(buf).getStartOff(); - length = KMByteBlob.cast(buf).length(); - stackPtr = (short) (start + length); - /* KMAttestationCertImpl.attChallenge = attChallenge; - KMAttestationCertImpl.attAppId = attAppId; - KMAttestationCertImpl.hwParams = KMKeyCharacteristics.cast(keyChar).getHardwareEnforced(); - KMAttestationCertImpl.swParams = KMKeyCharacteristics.cast(keyChar).getSoftwareEnforced(); - KMAttestationCertImpl.notBefore = notBefore; - KMAttestationCertImpl.notAfter = notAfter; - KMAttestationCertImpl.pubKey = pubKey; - KMAttestationCertImpl.uniqueId = uniqueId; - - */ - short last = stackPtr; - decrementStackPtr((short) 256); - signatureOffset = stackPtr; - pushBitStringHeader((byte) 0, (short) (last - stackPtr)); - // signatureOffset = pushSignature(null, (short) 0, (short) 256); - pushAlgorithmId(X509SignAlgIdentifier); - tbsLength = stackPtr; - pushTbsCert(rsaCert); - tbsOffset = stackPtr; - tbsLength = (short) (tbsLength - tbsOffset); - pushSequenceHeader((short) (last - stackPtr)); - // print(stack, stackPtr, (short)(last - stackPtr)); - certStart = stackPtr; - } - private static void pushTbsCert(boolean rsaCert) { short last = stackPtr; pushExtensions(); @@ -335,7 +285,6 @@ private static void pushExtensions() { short last = stackPtr; // byte keyusage = 0; // byte unusedBits = 8; - pushAuthKeyId(); /* if (KMEnumArrayTag.contains(KMType.PURPOSE, KMType.SIGN, hwParams)) { keyusage = (byte) (keyusage | keyUsageSign); @@ -594,7 +543,6 @@ private static void pushTag(short tag) { // } private static void pushRoT() { short last = stackPtr; - byte val = 0x00; // verified boot hash // pushOctetString(repo.verifiedBootHash, (short) 0, (short) repo.verifiedBootHash.length); pushOctetString( @@ -758,39 +706,10 @@ private static void pushKeyUsage(byte keyUsage, byte unusedBits) { pushSequenceHeader((short) (last - stackPtr)); } - // SEQUENCE {ObjId, OCTET STRING{SEQUENCE{[0]keyIdentifier}}} - private static void pushAuthKeyId() { - short last = stackPtr; - // if (repo.getAuthKeyId() == 0) return; - if (authKey == 0) return; - - pushKeyIdentifier( - KMByteBlob.cast(authKey).getBuffer(), - KMByteBlob.cast(authKey).getStartOff(), - KMByteBlob.cast(authKey).length()); - pushSequenceHeader((short) (last - stackPtr)); - pushOctetStringHeader((short) (last - stackPtr)); - pushBytes(authKeyIdExtn, (short) 0, (short) authKeyIdExtn.length); // ObjId - pushSequenceHeader((short) (last - stackPtr)); - } - - private static void pushKeyIdentifier(byte[] buf, short start, short len) { - pushBytes(buf, start, len); // keyIdentifier - pushLength(len); // len - pushByte((byte) 0x80); // Context specific tag [0] - } - private static void pushAlgorithmId(byte[] algId) { pushBytes(algId, (short) 0, (short) algId.length); } - private static short pushSignature(byte[] buf, short start, short len) { - pushBytes(buf, start, len); - short signatureOff = stackPtr; - pushBitStringHeader((byte) 0, len); - return signatureOff; - } - private static void pushIntegerHeader(short len) { pushLength(len); pushByte((byte) 0x02); diff --git a/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java index f15fbfcb..d27f015a 100644 --- a/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java +++ b/Applet/src/com/android/javacard/keymaster/KMAttestationCert.java @@ -32,14 +32,6 @@ public interface KMAttestationCert { */ KMAttestationCert verifiedBootState(byte val); - /** - * Set authentication key Id from CA Certificate set during provisioning. - * - * @param obj This is a KMByteBlob containing authentication Key Id. - * @return instance of KMAttestationCert - */ - KMAttestationCert authKey(short obj); - /** * Set uniqueId received from CA certificate during provisioning. * diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index a37e6aa8..a1157f34 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -75,7 +75,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private static final byte INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD = INS_BEGIN_KM_CMD + 2; //0x02 private static final byte INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD = INS_BEGIN_KM_CMD + 3; //0x03 private static final byte INS_PROVISION_ATTEST_IDS_CMD = INS_BEGIN_KM_CMD + 4; //0x04 - private static final byte INS_PROVISION_SHARED_SECRET_CMD = INS_BEGIN_KM_CMD + 5; //0x05 + private static final byte INS_PROVISION_PRESHARED_SECRET_CMD = INS_BEGIN_KM_CMD + 5; //0x05 private static final byte INS_SET_BOOT_PARAMS_CMD = INS_BEGIN_KM_CMD + 6; //0x06 private static final byte INS_LOCK_PROVISIONING_CMD = INS_BEGIN_KM_CMD + 7; //0x07 private static final byte INS_GET_PROVISION_STATUS_CMD = INS_BEGIN_KM_CMD + 8; //0x08 @@ -113,7 +113,7 @@ public class KMKeymasterApplet extends Applet implements AppletEvent, ExtendedLe private static final byte PROVISION_STATUS_ATTESTATION_CERT_CHAIN = 0x02; private static final byte PROVISION_STATUS_ATTESTATION_CERT_PARAMS = 0x04; private static final byte PROVISION_STATUS_ATTEST_IDS = 0x08; - private static final byte PROVISION_STATUS_SHARED_SECRET = 0x10; + private static final byte PROVISION_STATUS_PRESHARED_SECRET = 0x10; private static final byte PROVISION_STATUS_BOOT_PARAM = 0x20; private static final byte PROVISION_STATUS_PROVISIONING_LOCKED = 0x40; @@ -339,9 +339,9 @@ public void process(APDU apdu) { sendError(apdu, KMError.OK); return; - case INS_PROVISION_SHARED_SECRET_CMD: + case INS_PROVISION_PRESHARED_SECRET_CMD: processProvisionSharedSecretCmd(apdu); - provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_SHARED_SECRET; + provisionStatus |= KMKeymasterApplet.PROVISION_STATUS_PRESHARED_SECRET; sendError(apdu, KMError.OK); return; @@ -461,9 +461,11 @@ && isProvisioningComplete())) { sendError(apdu, mapISOErrorToKMError(exp.getReason())); freeOperations(); } catch (CryptoException e) { + e.printStackTrace(); freeOperations(); sendError(apdu, mapCryptoErrorToKMError(e.getReason())); } catch (Exception e) { + e.printStackTrace(); freeOperations(); sendError(apdu, KMError.GENERIC_UNKNOWN_ERROR); } finally { @@ -476,7 +478,7 @@ private boolean isProvisioningComplete() { if((0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_KEY)) && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_CHAIN)) && (0 != (provisionStatus & PROVISION_STATUS_ATTESTATION_CERT_PARAMS)) - && (0 != (provisionStatus & PROVISION_STATUS_SHARED_SECRET)) + && (0 != (provisionStatus & PROVISION_STATUS_PRESHARED_SECRET)) && (0 != (provisionStatus & PROVISION_STATUS_BOOT_PARAM))) { return true; } else { @@ -632,10 +634,9 @@ private void processProvisionAttestationCertParams(APDU apdu) { receiveIncoming(apdu); // Arguments short blob = KMByteBlob.exp(); - short argsProto = KMArray.instance((short) 3); + short argsProto = KMArray.instance((short) 2); KMArray.cast(argsProto).add((short) 0, blob); // Cert - DER encoded issuer KMArray.cast(argsProto).add((short) 1, blob); // Cert - Expiry Time - KMArray.cast(argsProto).add((short) 2, blob); // Cert - Auth Key Id // Decode the argument. short args = decoder.decode(argsProto, buffer, bufferStartOffset, bufferLength); //reclaim memory @@ -654,13 +655,6 @@ private void processProvisionAttestationCertParams(APDU apdu) { KMByteBlob.cast(tmpVariables[0]).getBuffer(), KMByteBlob.cast(tmpVariables[0]).getStartOff(), KMByteBlob.cast(tmpVariables[0]).length()); - - // Auth Key Id - from cert associated with imported attestation key. - tmpVariables[0] = KMArray.cast(args).get((short) 2); - repository.setAuthKeyId( - KMByteBlob.cast(tmpVariables[0]).getBuffer(), - KMByteBlob.cast(tmpVariables[0]).getStartOff(), - KMByteBlob.cast(tmpVariables[0]).length()); } private void processProvisionAttestationCertChainCmd(APDU apdu) { @@ -1438,9 +1432,7 @@ private void processAttestKeyCmd(APDU apdu) { addTags(KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getHardwareEnforced(), true, cert); addTags( KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getSoftwareEnforced(), false, cert); - if (repository.getAuthKeyId() != 0) { - cert.authKey(repository.getAuthKeyId()); - } + cert.deviceLocked(repository.getDeviceLock()); cert.issuer(repository.getIssuer()); cert.publicKey(data[PUB_KEY]); diff --git a/Applet/src/com/android/javacard/keymaster/KMRepository.java b/Applet/src/com/android/javacard/keymaster/KMRepository.java index c2809c08..4bcdf28b 100644 --- a/Applet/src/com/android/javacard/keymaster/KMRepository.java +++ b/Applet/src/com/android/javacard/keymaster/KMRepository.java @@ -29,7 +29,7 @@ */ public class KMRepository implements KMUpgradable { // Data table configuration - public static final short DATA_INDEX_SIZE = 33; + public static final short DATA_INDEX_SIZE = 32; public static final short DATA_INDEX_ENTRY_SIZE = 4; public static final short DATA_MEM_SIZE = 2048; public static final short HEAP_SIZE = 10000; @@ -50,26 +50,25 @@ public class KMRepository implements KMUpgradable { public static final byte ATT_ID_MANUFACTURER = 6; public static final byte ATT_ID_MODEL = 7; public static final byte ATT_EC_KEY = 12; - public static final byte CERT_AUTH_KEY_ID = 13; - public static final byte CERT_ISSUER = 14; - public static final byte CERT_EXPIRY_TIME = 15; - public static final byte BOOT_OS_VERSION = 16; - public static final byte BOOT_OS_PATCH = 17; - public static final byte VENDOR_PATCH_LEVEL = 18; - public static final byte BOOT_PATCH_LEVEL = 19; - public static final byte BOOT_VERIFIED_BOOT_KEY = 20; - public static final byte BOOT_VERIFIED_BOOT_HASH = 21; - public static final byte BOOT_VERIFIED_BOOT_STATE = 22; - public static final byte BOOT_DEVICE_LOCKED_STATUS = 23; - public static final byte BOOT_DEVICE_LOCKED_TIME = 24; - public static final byte AUTH_TAG_1 = 25; - public static final byte AUTH_TAG_2 = 26; - public static final byte AUTH_TAG_3 = 27; - public static final byte AUTH_TAG_4 = 28; - public static final byte AUTH_TAG_5 = 29; - public static final byte AUTH_TAG_6 = 30; - public static final byte AUTH_TAG_7 = 31; - public static final byte AUTH_TAG_8 = 32; + public static final byte CERT_ISSUER = 13; + public static final byte CERT_EXPIRY_TIME = 14; + public static final byte BOOT_OS_VERSION = 15; + public static final byte BOOT_OS_PATCH = 16; + public static final byte VENDOR_PATCH_LEVEL = 17; + public static final byte BOOT_PATCH_LEVEL = 18; + public static final byte BOOT_VERIFIED_BOOT_KEY = 19; + public static final byte BOOT_VERIFIED_BOOT_HASH = 20; + public static final byte BOOT_VERIFIED_BOOT_STATE = 21; + public static final byte BOOT_DEVICE_LOCKED_STATUS = 22; + public static final byte BOOT_DEVICE_LOCKED_TIME = 23; + public static final byte AUTH_TAG_1 = 24; + public static final byte AUTH_TAG_2 = 25; + public static final byte AUTH_TAG_3 = 26; + public static final byte AUTH_TAG_4 = 27; + public static final byte AUTH_TAG_5 = 28; + public static final byte AUTH_TAG_6 = 29; + public static final byte AUTH_TAG_7 = 30; + public static final byte AUTH_TAG_8 = 31; // Data Item sizes public static final short MASTER_KEY_SIZE = 16; @@ -567,13 +566,6 @@ public void setCertExpiryTime(byte[] buf, short start, short len) { writeDataEntry(CERT_EXPIRY_TIME, buf,start,len); } - public short getAuthKeyId() { - return readData(CERT_AUTH_KEY_ID); - } - - public void setAuthKeyId(byte[] buf, short start, short len) { - writeDataEntry(CERT_AUTH_KEY_ID,buf,start,len); - } private static final byte[] zero = {0,0,0,0,0,0,0,0}; public short getOsVersion(){ From 606138149106d4dee78adc51eb2b589e73a445d4 Mon Sep 17 00:00:00 2001 From: bvenkateswarlu Date: Thu, 21 Jan 2021 14:19:13 +0530 Subject: [PATCH 5/5] Fixed the issue with KMFunctionalTest --- .../src/com/android/javacard/keymaster/KMUtils.java | 2 +- .../src/com/android/javacard/keymaster/KMUtils.java | 2 +- .../com/android/javacard/test/KMFunctionalTest.java | 13 +++++-------- .../javacard/keymaster/KMKeymasterApplet.java | 2 -- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java index 08309f86..2e0f8d99 100644 --- a/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -20,7 +20,7 @@ public class KMUtils { public static final byte[] fourYrsMsec = { 0, 0, 0, 0x1D, 0x63, (byte) 0xC3, 0x7F, 0x00 }; // 126227808000 msec public static final byte[] firstJan2020 = { - 0, 0, 0x01, 0x76, (byte) 0xBB, 0x3E, (byte) 0x70, 0x40 }; // 1609459200000 msec + 0, 0, 0x01, 0x6F, 0x5E, 0x66, (byte)0xE8, 0x00 }; // 1577836800000 msec public static final byte[] firstJan2051 = { 0, 0, 0x02, 0x53, 0x26, (byte) 0x0E, (byte) 0x1C, 0x00 }; // 2556144000000 // msec diff --git a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java index 08309f86..4569fb15 100644 --- a/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java +++ b/Applet/JCardSimProvider/src/com/android/javacard/keymaster/KMUtils.java @@ -20,7 +20,7 @@ public class KMUtils { public static final byte[] fourYrsMsec = { 0, 0, 0, 0x1D, 0x63, (byte) 0xC3, 0x7F, 0x00 }; // 126227808000 msec public static final byte[] firstJan2020 = { - 0, 0, 0x01, 0x76, (byte) 0xBB, 0x3E, (byte) 0x70, 0x40 }; // 1609459200000 msec + 0, 0, 0x01, 0x6F, 0x5E, 0x66, (byte)0xE8, 0x00 }; // 1577836800000 msec public static final byte[] firstJan2051 = { 0, 0, 0x02, 0x53, 0x26, (byte) 0x0E, (byte) 0x1C, 0x00 }; // 2556144000000 // msec diff --git a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java index fb248f2d..0e6408d2 100644 --- a/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java +++ b/Applet/JCardSimProvider/test/com/android/javacard/test/KMFunctionalTest.java @@ -59,7 +59,7 @@ public class KMFunctionalTest { private static final byte INS_PROVISION_ATTESTATION_CERT_CHAIN_CMD = INS_BEGIN_KM_CMD + 2; //0x02 private static final byte INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD = INS_BEGIN_KM_CMD + 3; //0x03 private static final byte INS_PROVISION_ATTEST_IDS_CMD = INS_BEGIN_KM_CMD + 4; //0x04 - private static final byte INS_PROVISION_SHARED_SECRET_CMD = INS_BEGIN_KM_CMD + 5; //0x05 + private static final byte INS_PROVISION_PRESHARED_SECRET_CMD = INS_BEGIN_KM_CMD + 5; //0x05 private static final byte INS_SET_BOOT_PARAMS_CMD = INS_BEGIN_KM_CMD + 6; //0x06 private static final byte INS_LOCK_PROVISIONING_CMD = INS_BEGIN_KM_CMD + 7; //0x07 private static final byte INS_GET_PROVISION_STATUS_CMD = INS_BEGIN_KM_CMD + 8; //0x08 @@ -538,16 +538,13 @@ private void provisionSigningKey(CardSimulator simulator) { private void provisionCertificateParams(CardSimulator simulator) { - short arrPtr = KMArray.instance((short) 3); + short arrPtr = KMArray.instance((short) 2); short byteBlob1 = KMByteBlob.instance(X509Issuer, (short) 0, (short) X509Issuer.length); KMArray.cast(arrPtr).add((short) 0, byteBlob1); short byteBlob2 = KMByteBlob.instance(expiryTime, (short) 0, (short) expiryTime.length); KMArray.cast(arrPtr).add((short) 1, byteBlob2); - short byteBlob3 = KMByteBlob.instance(authKeyId, (short) 0, - (short) authKeyId.length); - KMArray.cast(arrPtr).add((short) 2, byteBlob3); CommandAPDU apdu = encodeApdu( (byte) INS_PROVISION_ATTESTATION_CERT_PARAMS_CMD, arrPtr); @@ -565,7 +562,7 @@ private void provisionSharedSecret(CardSimulator simulator) { (short) sharedKeySecret.length); KMArray.cast(arrPtr).add((short) 0, byteBlob); - CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_SHARED_SECRET_CMD, + CommandAPDU apdu = encodeApdu((byte) INS_PROVISION_PRESHARED_SECRET_CMD, arrPtr); // print(commandAPDU.getBytes()); ResponseAPDU response = simulator.transmitCommand(apdu); @@ -1622,11 +1619,11 @@ public void testImportWrappedKey(){ byte[] nonce = new byte[12]; cryptoProvider.newRandomNumber(nonce,(short)0,(short)12); byte[] authData = "Auth Data".getBytes(); - byte[] authTag = new byte[12]; + byte[] authTag = new byte[16]; cryptoProvider.aesGCMEncrypt(transportKeyMaterial,(short)0,(short)32,wrappedKey, (short)0,(short)16,encWrappedKey,(short)0, nonce,(short)0, (short)12,authData,(short)0,(short)authData.length, - authTag, (short)0, (short)12); + authTag, (short)0, (short)16); byte[] maskingKey = {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0}; byte[] maskedTransportKey = new byte[32]; for(int i=0; i< maskingKey.length;i++){ diff --git a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java index a1157f34..b9ae5ce4 100644 --- a/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java +++ b/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java @@ -461,11 +461,9 @@ && isProvisioningComplete())) { sendError(apdu, mapISOErrorToKMError(exp.getReason())); freeOperations(); } catch (CryptoException e) { - e.printStackTrace(); freeOperations(); sendError(apdu, mapCryptoErrorToKMError(e.getReason())); } catch (Exception e) { - e.printStackTrace(); freeOperations(); sendError(apdu, KMError.GENERIC_UNKNOWN_ERROR); } finally {