use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by crdroidandroid.
the class AndroidKeyStoreSecretKeyFactorySpi method getKeyInfo.
static KeyInfo getKeyInfo(KeyStore keyStore, String entryAlias, String keyAliasInKeystore, int keyUid) {
KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
int errorCode = keyStore.getKeyCharacteristics(keyAliasInKeystore, null, null, keyUid, keyCharacteristics);
if (errorCode != KeyStore.NO_ERROR) {
throw new ProviderException("Failed to obtain information about key." + " Keystore error: " + errorCode);
}
boolean insideSecureHardware;
@KeyProperties.OriginEnum int origin;
int keySize;
@KeyProperties.PurposeEnum int purposes;
String[] encryptionPaddings;
String[] signaturePaddings;
@KeyProperties.DigestEnum String[] digests;
@KeyProperties.BlockModeEnum String[] blockModes;
int keymasterSwEnforcedUserAuthenticators;
int keymasterHwEnforcedUserAuthenticators;
List<BigInteger> keymasterSecureUserIds;
try {
if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = true;
origin = KeyProperties.Origin.fromKeymaster(keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = false;
origin = KeyProperties.Origin.fromKeymaster(keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else {
throw new ProviderException("Key origin not available");
}
long keySizeUnsigned = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
if (keySizeUnsigned == -1) {
throw new ProviderException("Key size not available");
} else if (keySizeUnsigned > Integer.MAX_VALUE) {
throw new ProviderException("Key too large: " + keySizeUnsigned + " bits");
}
keySize = (int) keySizeUnsigned;
purposes = KeyProperties.Purpose.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PURPOSE));
List<String> encryptionPaddingsList = new ArrayList<String>();
List<String> signaturePaddingsList = new ArrayList<String>();
// Keymaster stores both types of paddings in the same array -- we split it into two.
for (int keymasterPadding : keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PADDING)) {
try {
@KeyProperties.EncryptionPaddingEnum String jcaPadding = KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
encryptionPaddingsList.add(jcaPadding);
} catch (IllegalArgumentException e) {
try {
@KeyProperties.SignaturePaddingEnum String padding = KeyProperties.SignaturePadding.fromKeymaster(keymasterPadding);
signaturePaddingsList.add(padding);
} catch (IllegalArgumentException e2) {
throw new ProviderException("Unsupported encryption padding: " + keymasterPadding);
}
}
}
encryptionPaddings = encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
signaturePaddings = signaturePaddingsList.toArray(new String[signaturePaddingsList.size()]);
digests = KeyProperties.Digest.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST));
blockModes = KeyProperties.BlockMode.allFromKeymaster(keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_BLOCK_MODE));
keymasterSwEnforcedUserAuthenticators = keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
keymasterHwEnforcedUserAuthenticators = keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
keymasterSecureUserIds = keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
} catch (IllegalArgumentException e) {
throw new ProviderException("Unsupported key characteristic", e);
}
Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME);
Date keyValidityForOriginationEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME);
Date keyValidityForConsumptionEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
boolean userAuthenticationRequired = !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
long userAuthenticationValidityDurationSeconds = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
if (userAuthenticationValidityDurationSeconds > Integer.MAX_VALUE) {
throw new ProviderException("User authentication timeout validity too long: " + userAuthenticationValidityDurationSeconds + " seconds");
}
boolean userAuthenticationRequirementEnforcedBySecureHardware = (userAuthenticationRequired) && (keymasterHwEnforcedUserAuthenticators != 0) && (keymasterSwEnforcedUserAuthenticators == 0);
boolean userAuthenticationValidWhileOnBody = keyCharacteristics.hwEnforced.getBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
boolean invalidatedByBiometricEnrollment = false;
if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT) {
// Fingerprint-only key; will be invalidated if the root SID isn't in the SID list.
invalidatedByBiometricEnrollment = keymasterSecureUserIds != null && !keymasterSecureUserIds.isEmpty() && !keymasterSecureUserIds.contains(getGateKeeperSecureUserId());
}
return new KeyInfo(entryAlias, insideSecureHardware, origin, keySize, keyValidityStart, keyValidityForOriginationEnd, keyValidityForConsumptionEnd, purposes, encryptionPaddings, signaturePaddings, digests, blockModes, userAuthenticationRequired, (int) userAuthenticationValidityDurationSeconds, userAuthenticationRequirementEnforcedBySecureHardware, userAuthenticationValidWhileOnBody, invalidatedByBiometricEnrollment);
}
use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by crdroidandroid.
the class KeyStoreTest method testGetKeyCharacteristicsSuccess.
public void testGetKeyCharacteristicsSuccess() throws Exception {
mKeyStore.onUserPasswordChanged(TEST_PASSWD);
String name = "test";
KeyCharacteristics gen = generateRsaKey(name);
KeyCharacteristics call = new KeyCharacteristics();
int result = mKeyStore.getKeyCharacteristics(name, null, null, call);
assertEquals("getKeyCharacteristics should succeed", KeyStore.NO_ERROR, result);
mKeyStore.delete("test");
}
use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by crdroidandroid.
the class KeyStoreTest method testAesGcmEncryptSuccess.
public void testAesGcmEncryptSuccess() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
args = new KeymasterArguments();
args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
args.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 128);
OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null);
IBinder token = result.token;
assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
result = mKeyStore.update(token, null, new byte[] { 0x01, 0x02, 0x03, 0x04 });
assertEquals("Update should succeed", KeyStore.NO_ERROR, result.resultCode);
assertEquals("Finish should succeed", KeyStore.NO_ERROR, mKeyStore.finish(token, null, null).resultCode);
// TODO: Assert that an AEAD tag was returned by finish
}
use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by crdroidandroid.
the class KeyStoreTest method generateRsaKey.
private KeyCharacteristics generateRsaKey(String name) throws Exception {
KeymasterArguments args = new KeymasterArguments();
args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
assertEquals("generateRsaKey should succeed", KeyStore.NO_ERROR, result);
return outCharacteristics;
}
use of android.security.keymaster.KeyCharacteristics in project android_frameworks_base by crdroidandroid.
the class KeyStoreTest method testGenerateRsaWithEntropy.
public void testGenerateRsaWithEntropy() throws Exception {
byte[] entropy = new byte[] { 1, 2, 3, 4, 5 };
String name = "test";
KeymasterArguments args = new KeymasterArguments();
args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int result = mKeyStore.generateKey(name, args, entropy, 0, outCharacteristics);
assertEquals("generateKey should succeed", KeyStore.NO_ERROR, result);
}
Aggregations