summaryrefslogtreecommitdiffstats
path: root/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-06-22 18:09:35 -0700
committerAlex Klyubin <klyubin@google.com>2015-06-23 20:04:28 -0700
commitae6cb7aad56bb006769cd8a69b92af7236644fc1 (patch)
treee70a45074619bb3e1f97cb5dcfe0c28bbfe60129 /keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
parent12402dafeaf2ec8255d6331d3e82028d694b87d7 (diff)
downloadframeworks_base-ae6cb7aad56bb006769cd8a69b92af7236644fc1.zip
frameworks_base-ae6cb7aad56bb006769cd8a69b92af7236644fc1.tar.gz
frameworks_base-ae6cb7aad56bb006769cd8a69b92af7236644fc1.tar.bz2
Keymaster INT, LONG and DATE tag values are unsigned.
This CL ensures that Android Keystore framework code complies with signedness of keymaster tags. In particular: * INT tags are unsigned 32-bit numbers, and * LONG and DATE tags are unsigned 64-bit numbers. The ensure compliance, KeymasterArguments and KeyCharacteristics classes through which Android Keystore interacts with Keymaster tags have been modified as follows: * ENUM and INT tags which used to be conflated are now added/queried via separate methods, because ENUM can remain represented as an int data type whereas INT is now represented as a long data type with permitted range being [0; 2^32). * Methods for adding/quering LONG tags have been switched from the long data type to the BigInteger data type and now ensure that the value is in the permitted [0; 2^63). * Methods for adding/querying DATE tags now ensure the Date value is in the permitted range [0; 2^63) ms since Unix epoch. * Methods for adding tags throw an IllegalArgumentException if the tag type is unsuitable for the method. This is to ensure that tags with invalid values cannot be added through similar methods (e.g., INT tag added via an ENUM tag addition method invoked with a negative value). Bug: 22008538 Change-Id: I6eefd5cbb561cc52d27de952691af4d9d5e1af1e
Diffstat (limited to 'keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java')
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java35
1 files changed, 21 insertions, 14 deletions
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 7887923..9a2f908 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -93,26 +93,29 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = true;
origin = KeyProperties.Origin.fromKeymaster(
- keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
+ 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.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
+ keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else {
throw new ProviderException("Key origin not available");
}
- Integer keySizeInteger = keyCharacteristics.getInteger(KeymasterDefs.KM_TAG_KEY_SIZE);
- if (keySizeInteger == null) {
+ 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 = keySizeInteger;
+ keySize = (int) keySizeUnsigned;
purposes = KeyProperties.Purpose.allFromKeymaster(
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PURPOSE));
+ 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.getInts(KeymasterDefs.KM_TAG_PADDING)) {
+ for (int keymasterPadding : keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_PADDING)) {
try {
@KeyProperties.EncryptionPaddingEnum String jcaPadding =
KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
@@ -135,13 +138,13 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
signaturePaddingsList.toArray(new String[signaturePaddingsList.size()]);
digests = KeyProperties.Digest.allFromKeymaster(
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
+ keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST));
blockModes = KeyProperties.BlockMode.allFromKeymaster(
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
+ keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_BLOCK_MODE));
keymasterSwEnforcedUserAuthenticators =
- keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
+ keyCharacteristics.swEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
keymasterHwEnforcedUserAuthenticators =
- keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
+ keyCharacteristics.hwEnforced.getEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
} catch (IllegalArgumentException e) {
throw new ProviderException("Unsupported key characteristic", e);
}
@@ -153,8 +156,12 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME);
boolean userAuthenticationRequired =
!keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- int userAuthenticationValidityDurationSeconds =
- keyCharacteristics.getInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1);
+ 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);
@@ -172,7 +179,7 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
digests,
blockModes,
userAuthenticationRequired,
- userAuthenticationValidityDurationSeconds,
+ (int) userAuthenticationValidityDurationSeconds,
userAuthenticationRequirementEnforcedBySecureHardware);
}