Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ public class KMConfigurations {
// If the size of the attestation ids is known and lesser than 64
// then reduce the size here. It reduces the heap memory usage.
public static final byte MAX_ATTESTATION_IDS_SIZE = 64;
public static final short MAX_SUBJECT_DER_LEN = 1095;
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public class KMAndroidSEProvider implements KMSEProvider {
private KMRsaOAEPEncoding rsaOaepDecipher;
private KMPoolManager poolMgr;

private KMOperationImpl globalOperation;
// Entropy
private RandomData rng;

Expand Down Expand Up @@ -112,6 +113,8 @@ public KMAndroidSEProvider() {
kdf = Signature.getInstance(Signature.ALG_AES_CMAC_128, false);
hmacSignature = Signature.getInstance(Signature.ALG_HMAC_SHA_256, false);

globalOperation = new KMOperationImpl();

// Temporary transient array created to use locally inside functions.
tmpArray = JCSystem.makeTransientByteArray(TMP_ARRAY_SIZE,
JCSystem.CLEAR_ON_DESELECT);
Expand All @@ -131,7 +134,7 @@ void initStatics() {
}

public void clean() {
Util.arrayFillNonAtomic(tmpArray, (short) 0, (short) 256, (byte) 0);
Util.arrayFillNonAtomic(tmpArray, (short) 0, TMP_ARRAY_SIZE, (byte) 0);
}

public AESKey createAESKey(short keysize) {
Expand Down Expand Up @@ -352,7 +355,9 @@ public short aesGCMEncrypt(AESKey key,
false);
}
aesGcmCipher.init(key, Cipher.MODE_ENCRYPT, nonce, nonceStart, nonceLen);
aesGcmCipher.updateAAD(authData, authDataStart, authDataLen);
if (authDataLen != 0) {
aesGcmCipher.updateAAD(authData, authDataStart, authDataLen);
}
short ciphLen = aesGcmCipher.doFinal(secret, secretStart, secretLen,
encSecret, encSecretStart);
aesGcmCipher.retrieveTag(authTag, authTagStart, authTagLen);
Expand Down Expand Up @@ -398,7 +403,9 @@ public boolean aesGCMDecrypt(byte[] aesKey, short aesKeyStart,
boolean verification = false;
AESKey key = createAESKey(aesKey, aesKeyStart, aesKeyLen);
aesGcmCipher.init(key, Cipher.MODE_DECRYPT, nonce, nonceStart, nonceLen);
aesGcmCipher.updateAAD(authData, authDataStart, authDataLen);
if (authDataLen != 0) {
aesGcmCipher.updateAAD(authData, authDataStart, authDataLen);
}
// encrypt the secret
aesGcmCipher.doFinal(encSecret, encSecretStart, encSecretLen, secret,
secretStart);
Expand Down Expand Up @@ -479,9 +486,8 @@ public short hmacKDF(KMMasterKey masterkey, byte[] data, short dataStart,
try {
KMAESKey aesKey = (KMAESKey) masterkey;
short keyLen = (short) (aesKey.getKeySizeBits() / 8);
byte[] keyData = new byte[keyLen];
aesKey.getKey(keyData, (short) 0);
return hmacSign(keyData, (short) 0, keyLen, data, dataStart, dataLength,
aesKey.getKey(tmpArray, (short) 0);
return hmacSign(tmpArray, (short) 0, keyLen, data, dataStart, dataLength,
signature, signatureStart);
} finally {
clean();
Expand Down Expand Up @@ -697,6 +703,43 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg,
return opr;
}

@Override
public KMOperation initSymmetricOperation(byte purpose, byte alg, byte digest, byte padding, byte blockMode,
Object key, byte interfaceType, byte[] ivBuf, short ivStart, short ivLength, short macLength,
boolean oneShot) {
short keyLen = 0;
globalOperation.setPurpose(purpose);
globalOperation.setAlgorithmType(alg);
globalOperation.setPaddingAlgorithm(padding);
globalOperation.setBlockMode(blockMode);
try {
switch (interfaceType) {
case KMDataStoreConstants.INTERFACE_TYPE_MASTER_KEY:
KMAESKey aesKey = (KMAESKey) key;
keyLen = (short) (aesKey.getKeySizeBits() / 8);
aesKey.getKey(tmpArray, (short) 0);
break;

default:
KMException.throwIt(KMError.INVALID_ARGUMENT);
}

switch (alg) {
case KMType.HMAC:
HMACKey hmackey = createHMACKey(tmpArray, (short)0, keyLen);
globalOperation.setSignature(hmacSignature);
globalOperation.init(hmackey, digest, null, (short)0, (short)0);
break;

default:
KMException.throwIt(KMError.INVALID_ARGUMENT);
}
} finally {
clean();
}
return globalOperation;
}

@Override
public KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey) {
KMHmacKey key = (KMHmacKey) computedHmacKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,43 @@ KMOperation initSymmetricOperation(
short ivLength,
short macLength);

/**
* 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. 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
* @param alg is KMType.HMAC, KMType.AES or KMType.DES.
* @param digest is KMType.SHA2_256 in case of HMAC else it will be KMType.DIGEST_NONE.
* @param padding is KMType.PADDING_NONE or KMType.PKCS7 (in case of AES and DES).
* @param blockMode is KMType.CTR, KMType.GCM. KMType.CBC or KMType.ECB for AES or DES else it is
* 0.
* @param key is a key object.
* @param interfaceType defines the type of key in the key object.
* @param ivBuf is the iv buffer (in case on AES and DES algorithm without ECB mode)
* @param ivStart is the start of the iv buffer.
* @param ivLength is the length of the iv buffer. It will be zero in case of HMAC and AES/DES
* with ECB mode.
* @param macLength is the mac length in case of signing operation for hmac algorithm.
* @param oneShot if true, creates oneshot operation.
* @return KMOperation instance.
*/
KMOperation initSymmetricOperation(
byte purpose,
byte alg,
byte digest,
byte padding,
byte blockMode,
Object key,
byte interfaceType,
byte[] ivBuf,
short ivStart,
short ivLength,
short macLength,
boolean oneShot);

/**
* This function creates an Operation instance only for RKP module.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,12 @@ public short aesGCMEncrypt(
e.printStackTrace();
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
}
// Create auth data
byte[] aad = new byte[authDataLen];
Util.arrayCopyNonAtomic(authData, authDataStart, aad, (short) 0, authDataLen);
cipher.updateAAD(aad);
if (authDataLen != 0) {
// Create auth data
byte[] aad = new byte[authDataLen];
Util.arrayCopyNonAtomic(authData, authDataStart, aad, (short) 0, authDataLen);
cipher.updateAAD(aad);
}
// Encrypt secret
short len = 0;
byte[] outputBuf = new byte[cipher.getOutputSize(secretLen)];
Expand Down Expand Up @@ -444,11 +446,13 @@ public boolean aesGCMDecrypt(
e.printStackTrace();
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
}
// Create auth data
byte[] aad = new byte[authDataLen];
Util.arrayCopyNonAtomic(authData, authDataStart, aad, (short) 0,
if (authDataLen != 0) {
// Create auth data
byte[] aad = new byte[authDataLen];
Util.arrayCopyNonAtomic(authData, authDataStart, aad, (short) 0,
authDataLen);
cipher.updateAAD(aad);
cipher.updateAAD(aad);
}
// Append the auth tag at the end of data
byte[] inputBuf = new byte[(short) (encSecretLen + authTagLen)];
Util.arrayCopyNonAtomic(encSecret, encSecretStart, inputBuf, (short) 0,
Expand Down Expand Up @@ -666,6 +670,39 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg, byte digest, b
return null;
}

@Override
public KMOperation initSymmetricOperation(byte purpose, byte alg, byte digest, byte padding, byte blockMode,
Object key, byte interfaceType, byte[] ivBuf, short ivStart, short ivLength, short macLength,
boolean oneShot) {
KMOperationImpl operation = null;
short keyLen = 0;
byte[] keyData = null;

switch (interfaceType) {
case KMDataStoreConstants.INTERFACE_TYPE_MASTER_KEY:
KMAESKey aesKey = (KMAESKey) key;
keyLen = (short) (aesKey.getKeySizeBits() / 8);
keyData = new byte[keyLen];
aesKey.getKey(keyData, (short) 0);
break;

default:
KMException.throwIt(KMError.INVALID_ARGUMENT);
}

switch (alg){
case KMType.HMAC:
Signature signerVerifier = createHmacSignerVerifier(purpose, digest, keyData, (short)0,
keyLen);
operation = new KMOperationImpl(signerVerifier);
break;

default:
KMException.throwIt(KMError.INVALID_ARGUMENT);
}
return operation;
}

@Override
public KMOperation initTrustedConfirmationSymmetricOperation(KMComputedHmacKey computedHmacKey) {
KMOperationImpl opr = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,43 @@ KMOperation initSymmetricOperation(
short ivLength,
short macLength);

/**
* 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. 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
* @param alg is KMType.HMAC, KMType.AES or KMType.DES.
* @param digest is KMType.SHA2_256 in case of HMAC else it will be KMType.DIGEST_NONE.
* @param padding is KMType.PADDING_NONE or KMType.PKCS7 (in case of AES and DES).
* @param blockMode is KMType.CTR, KMType.GCM. KMType.CBC or KMType.ECB for AES or DES else it is
* 0.
* @param key is a key object.
* @param interfaceType defines the type of key in the key object.
* @param ivBuf is the iv buffer (in case on AES and DES algorithm without ECB mode)
* @param ivStart is the start of the iv buffer.
* @param ivLength is the length of the iv buffer. It will be zero in case of HMAC and AES/DES
* with ECB mode.
* @param macLength is the mac length in case of signing operation for hmac algorithm.
* @param oneShot if true, creates oneshot operation.
* @return KMOperation instance.
*/
KMOperation initSymmetricOperation(
byte purpose,
byte alg,
byte digest,
byte padding,
byte blockMode,
Object key,
byte interfaceType,
byte[] ivBuf,
short ivStart,
short ivLength,
short macLength,
boolean oneShot);

/**
* This function creates an Operation instance only for RKP module.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public class KMKeyParameters extends KMType {
KMType.ULONG_ARRAY_TAG, KMType.USER_SECURE_ID,
KMType.UINT_TAG, KMType.AUTH_TIMEOUT,
KMType.ENUM_TAG, KMType.USER_AUTH_TYPE,
KMType.BOOL_TAG, KMType.UNLOCKED_DEVICE_REQUIRED,
KMType.BOOL_TAG, KMType.TRUSTED_CONFIRMATION_REQUIRED,
KMType.BOOL_TAG, KMType.UNLOCKED_DEVICE_REQUIRED,
KMType.BOOL_TAG, KMType.TRUSTED_CONFIRMATION_REQUIRED,
};

private static final short[] invalidTagsArr = {
Expand Down
Loading