summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--core/java/android/security/keymaster/KeyCharacteristics.java101
-rw-r--r--core/java/android/security/keymaster/KeymasterArgument.java3
-rw-r--r--core/java/android/security/keymaster/KeymasterArguments.java334
-rw-r--r--keystore/java/android/security/KeyStore.java9
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java14
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java10
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java6
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java12
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java27
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreProvider.java11
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java14
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java6
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java35
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreSpi.java22
-rw-r--r--keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java10
-rw-r--r--keystore/java/android/security/keystore/KeymasterUtils.java12
-rw-r--r--keystore/tests/src/android/security/KeyStoreTest.java113
17 files changed, 461 insertions, 278 deletions
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
index 03248e5..c91e20c 100644
--- a/core/java/android/security/keymaster/KeyCharacteristics.java
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +19,7 @@ package android.security.keymaster;
import android.os.Parcel;
import android.os.Parcelable;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -30,8 +31,8 @@ public class KeyCharacteristics implements Parcelable {
public KeymasterArguments swEnforced;
public KeymasterArguments hwEnforced;
- public static final Parcelable.Creator<KeyCharacteristics> CREATOR = new
- Parcelable.Creator<KeyCharacteristics>() {
+ public static final Parcelable.Creator<KeyCharacteristics> CREATOR =
+ new Parcelable.Creator<KeyCharacteristics>() {
@Override
public KeyCharacteristics createFromParcel(Parcel in) {
return new KeyCharacteristics(in);
@@ -65,73 +66,85 @@ public class KeyCharacteristics implements Parcelable {
hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
}
- public Integer getInteger(int tag) {
+ /**
+ * Returns the value of the specified enum tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an enum tag.
+ */
+ public Integer getEnum(int tag) {
if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getInt(tag, -1);
+ return hwEnforced.getEnum(tag, -1);
} else if (swEnforced.containsTag(tag)) {
- return swEnforced.getInt(tag, -1);
+ return swEnforced.getEnum(tag, -1);
} else {
return null;
}
}
- public int getInt(int tag, int defaultValue) {
- Integer result = getInteger(tag);
- return (result != null) ? result : defaultValue;
- }
-
- public List<Integer> getInts(int tag) {
+ /**
+ * Returns all values of the specified repeating enum tag.
+ *
+ * throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
+ */
+ public List<Integer> getEnums(int tag) {
List<Integer> result = new ArrayList<Integer>();
- result.addAll(hwEnforced.getInts(tag));
- result.addAll(swEnforced.getInts(tag));
+ result.addAll(hwEnforced.getEnums(tag));
+ result.addAll(swEnforced.getEnums(tag));
return result;
}
- public Long getLong(int tag) {
+ /**
+ * Returns the value of the specified unsigned 32-bit int tag or {@code defaultValue} if the tag
+ * is not present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag.
+ */
+ public long getUnsignedInt(int tag, long defaultValue) {
if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getLong(tag, -1);
- } else if (swEnforced.containsTag(tag)) {
- return swEnforced.getLong(tag, -1);
+ return hwEnforced.getUnsignedInt(tag, defaultValue);
} else {
- return null;
+ return swEnforced.getUnsignedInt(tag, defaultValue);
}
}
- public long getLong(int tag, long defaultValue) {
- Long result = getLong(tag);
- return (result != null) ? result : defaultValue;
- }
-
- public List<Long> getLongs(int tag) {
- List<Long> result = new ArrayList<Long>();
- result.addAll(hwEnforced.getLongs(tag));
- result.addAll(swEnforced.getLongs(tag));
+ /**
+ * Returns all values of the specified repeating unsigned 64-bit long tag.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a repeating unsigned 64-bit long tag.
+ */
+ public List<BigInteger> getUnsignedLongs(int tag) {
+ List<BigInteger> result = new ArrayList<BigInteger>();
+ result.addAll(hwEnforced.getUnsignedLongs(tag));
+ result.addAll(swEnforced.getUnsignedLongs(tag));
return result;
}
+ /**
+ * Returns the value of the specified date tag or {@code null} if the tag is not present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if the tag's value
+ * represents a time instant which is after {@code 2^63 - 1} milliseconds since Unix
+ * epoch.
+ */
public Date getDate(int tag) {
- Date result = hwEnforced.getDate(tag, null);
- if (result == null) {
- result = swEnforced.getDate(tag, null);
- }
- return result;
- }
-
- public Date getDate(int tag, Date defaultValue) {
- if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getDate(tag, null);
- } else if (hwEnforced.containsTag(tag)) {
- return swEnforced.getDate(tag, null);
- } else {
- return defaultValue;
+ Date result = swEnforced.getDate(tag, null);
+ if (result != null) {
+ return result;
}
+ return hwEnforced.getDate(tag, null);
}
+ /**
+ * Returns {@code true} if the provided boolean tag is present, {@code false} if absent.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
+ */
public boolean getBoolean(int tag) {
if (hwEnforced.containsTag(tag)) {
- return hwEnforced.getBoolean(tag, false);
+ return hwEnforced.getBoolean(tag);
} else {
- return swEnforced.getBoolean(tag, false);
+ return swEnforced.getBoolean(tag);
}
}
}
diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java
index 9adde35..d1d8371 100644
--- a/core/java/android/security/keymaster/KeymasterArgument.java
+++ b/core/java/android/security/keymaster/KeymasterArgument.java
@@ -32,6 +32,7 @@ abstract class KeymasterArgument implements Parcelable {
public static final Parcelable.Creator<KeymasterArgument> CREATOR = new
Parcelable.Creator<KeymasterArgument>() {
+ @Override
public KeymasterArgument createFromParcel(Parcel in) {
final int pos = in.dataPosition();
final int tag = in.readInt();
@@ -55,6 +56,8 @@ abstract class KeymasterArgument implements Parcelable {
throw new ParcelFormatException("Bad tag: " + tag + " at " + pos);
}
}
+
+ @Override
public KeymasterArgument[] newArray(int size) {
return new KeymasterArgument[size];
}
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
index 363376c..ee0ad6d 100644
--- a/core/java/android/security/keymaster/KeymasterArguments.java
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +19,7 @@ package android.security.keymaster;
import android.os.Parcel;
import android.os.Parcelable;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -30,7 +31,14 @@ import java.util.List;
* @hide
*/
public class KeymasterArguments implements Parcelable {
- List<KeymasterArgument> mArguments;
+
+ private static final long UINT32_RANGE = 1L << 32;
+ public static final long UINT32_MAX_VALUE = UINT32_RANGE - 1;
+
+ private static final BigInteger UINT64_RANGE = BigInteger.ONE.shiftLeft(64);
+ public static final BigInteger UINT64_MAX_VALUE = UINT64_RANGE.subtract(BigInteger.ONE);
+
+ private List<KeymasterArgument> mArguments;
public static final Parcelable.Creator<KeymasterArguments> CREATOR = new
Parcelable.Creator<KeymasterArguments>() {
@@ -53,156 +61,292 @@ public class KeymasterArguments implements Parcelable {
mArguments = in.createTypedArrayList(KeymasterArgument.CREATOR);
}
- public void addInt(int tag, int value) {
- mArguments.add(new KeymasterIntArgument(tag, value));
+ /**
+ * Adds an enum tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an enum tag.
+ */
+ public void addEnum(int tag, int value) {
+ int tagType = KeymasterDefs.getTagType(tag);
+ if ((tagType != KeymasterDefs.KM_ENUM) && (tagType != KeymasterDefs.KM_ENUM_REP)) {
+ throw new IllegalArgumentException("Not an enum or repeating enum tag: " + tag);
+ }
+ addEnumTag(tag, value);
}
- public void addInts(int tag, int... values) {
+ /**
+ * Adds a repeated enum tag with the provided values.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
+ */
+ public void addEnums(int tag, int... values) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ENUM_REP) {
+ throw new IllegalArgumentException("Not a repeating enum tag: " + tag);
+ }
for (int value : values) {
- addInt(tag, value);
+ addEnumTag(tag, value);
}
}
- public void addLongs(int tag, long... values) {
- for (long value : values) {
- addLong(tag, value);
+ /**
+ * Returns the value of the specified enum tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an enum tag.
+ */
+ public int getEnum(int tag, int defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ENUM) {
+ throw new IllegalArgumentException("Not an enum tag: " + tag);
}
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return defaultValue;
+ }
+ return getEnumTagValue(arg);
}
- public void addBoolean(int tag) {
- mArguments.add(new KeymasterBooleanArgument(tag));
+ /**
+ * Returns all values of the specified repeating enum tag.
+ *
+ * throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
+ */
+ public List<Integer> getEnums(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_ENUM_REP) {
+ throw new IllegalArgumentException("Not a repeating enum tag: " + tag);
+ }
+ List<Integer> values = new ArrayList<Integer>();
+ for (KeymasterArgument arg : mArguments) {
+ if (arg.tag == tag) {
+ values.add(getEnumTagValue(arg));
+ }
+ }
+ return values;
}
- public void addLong(int tag, long value) {
- mArguments.add(new KeymasterLongArgument(tag, value));
+ private void addEnumTag(int tag, int value) {
+ mArguments.add(new KeymasterIntArgument(tag, value));
}
- public void addBlob(int tag, byte[] value) {
- mArguments.add(new KeymasterBlobArgument(tag, value));
+ private int getEnumTagValue(KeymasterArgument arg) {
+ return ((KeymasterIntArgument) arg).value;
}
- public void addDate(int tag, Date value) {
- mArguments.add(new KeymasterDateArgument(tag, value));
+ /**
+ * Adds an unsigned 32-bit int tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag or if
+ * {@code value} is outside of the permitted range [0; 2^32).
+ */
+ public void addUnsignedInt(int tag, long value) {
+ int tagType = KeymasterDefs.getTagType(tag);
+ if ((tagType != KeymasterDefs.KM_INT) && (tagType != KeymasterDefs.KM_INT_REP)) {
+ throw new IllegalArgumentException("Not an int or repeating int tag: " + tag);
+ }
+ // Keymaster's KM_INT is unsigned 32 bit.
+ if ((value < 0) || (value > UINT32_MAX_VALUE)) {
+ throw new IllegalArgumentException("Int tag value out of range: " + value);
+ }
+ mArguments.add(new KeymasterIntArgument(tag, (int) value));
}
- public void addDateIfNotNull(int tag, Date value) {
- if (value != null) {
- mArguments.add(new KeymasterDateArgument(tag, value));
+ /**
+ * Returns the value of the specified unsigned 32-bit int tag or {@code defaultValue} if the tag
+ * is not present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag.
+ */
+ public long getUnsignedInt(int tag, long defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_INT) {
+ throw new IllegalArgumentException("Not an int tag: " + tag);
+ }
+ KeymasterArgument arg = getArgumentByTag(tag);
+ if (arg == null) {
+ return defaultValue;
}
+ // Keymaster's KM_INT is unsigned 32 bit.
+ return ((KeymasterIntArgument) arg).value & 0xffffffffL;
}
- private KeymasterArgument getArgumentByTag(int tag) {
+ /**
+ * Adds an unsigned 64-bit long tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not an unsigned 64-bit long tag or if
+ * {@code value} is outside of the permitted range [0; 2^64).
+ */
+ public void addUnsignedLong(int tag, BigInteger value) {
+ int tagType = KeymasterDefs.getTagType(tag);
+ if ((tagType != KeymasterDefs.KM_LONG) && (tagType != KeymasterDefs.KM_LONG_REP)) {
+ throw new IllegalArgumentException("Not a long or repeating long tag: " + tag);
+ }
+ addLongTag(tag, value);
+ }
+
+ /**
+ * Returns all values of the specified repeating unsigned 64-bit long tag.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a repeating unsigned 64-bit long tag.
+ */
+ public List<BigInteger> getUnsignedLongs(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG_REP) {
+ throw new IllegalArgumentException("Tag is not a repeating long: " + tag);
+ }
+ List<BigInteger> values = new ArrayList<BigInteger>();
for (KeymasterArgument arg : mArguments) {
if (arg.tag == tag) {
- return arg;
+ values.add(getLongTagValue(arg));
}
}
- return null;
+ return values;
}
- public boolean containsTag(int tag) {
- return getArgumentByTag(tag) != null;
+ private void addLongTag(int tag, BigInteger value) {
+ // Keymaster's KM_LONG is unsigned 64 bit.
+ if ((value.signum() == -1) || (value.compareTo(UINT64_MAX_VALUE) > 0)) {
+ throw new IllegalArgumentException("Long tag value out of range: " + value);
+ }
+ mArguments.add(new KeymasterLongArgument(tag, value.longValue()));
+ }
+
+ private BigInteger getLongTagValue(KeymasterArgument arg) {
+ // Keymaster's KM_LONG is unsigned 64 bit. We're forced to use BigInteger for type safety
+ // because there's no unsigned long type.
+ return toUint64(((KeymasterLongArgument) arg).value);
+ }
+
+ /**
+ * Adds the provided boolean tag. Boolean tags are considered to be set to {@code true} if
+ * present and {@code false} if absent.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
+ */
+ public void addBoolean(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
+ throw new IllegalArgumentException("Not a boolean tag: " + tag);
+ }
+ mArguments.add(new KeymasterBooleanArgument(tag));
}
- public int getInt(int tag, int defaultValue) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_ENUM:
- case KeymasterDefs.KM_INT:
- break; // Accepted types
- case KeymasterDefs.KM_INT_REP:
- case KeymasterDefs.KM_ENUM_REP:
- throw new IllegalArgumentException("Repeatable tags must use getInts: " + tag);
- default:
- throw new IllegalArgumentException("Tag is not an int type: " + tag);
+ /**
+ * Returns {@code true} if the provided boolean tag is present, {@code false} if absent.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
+ */
+ public boolean getBoolean(int tag) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
+ throw new IllegalArgumentException("Not a boolean tag: " + tag);
}
KeymasterArgument arg = getArgumentByTag(tag);
if (arg == null) {
- return defaultValue;
+ return false;
}
- return ((KeymasterIntArgument) arg).value;
+ return true;
}
- public long getLong(int tag, long defaultValue) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_LONG:
- break; // Accepted type
- case KeymasterDefs.KM_LONG_REP:
- throw new IllegalArgumentException("Repeatable tags must use getLongs: " + tag);
- default:
- throw new IllegalArgumentException("Tag is not a long type: " + tag);
+ /**
+ * Adds a bytes tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a bytes tag.
+ */
+ public void addBytes(int tag, byte[] value) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BYTES) {
+ throw new IllegalArgumentException("Not a bytes tag: " + tag);
+ }
+ if (value == null) {
+ throw new NullPointerException("value == nulll");
+ }
+ mArguments.add(new KeymasterBlobArgument(tag, value));
+ }
+
+ /**
+ * Returns the value of the specified bytes tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a bytes tag.
+ */
+ public byte[] getBytes(int tag, byte[] defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BYTES) {
+ throw new IllegalArgumentException("Not a bytes tag: " + tag);
}
KeymasterArgument arg = getArgumentByTag(tag);
if (arg == null) {
return defaultValue;
}
- return ((KeymasterLongArgument) arg).value;
+ return ((KeymasterBlobArgument) arg).blob;
}
- public Date getDate(int tag, Date defaultValue) {
+ /**
+ * Adds a date tag with the provided value.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if {@code value} is
+ * before the start of Unix epoch.
+ */
+ public void addDate(int tag, Date value) {
if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
- throw new IllegalArgumentException("Tag is not a date type: " + tag);
+ throw new IllegalArgumentException("Not a date tag: " + tag);
}
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
+ if (value == null) {
+ throw new NullPointerException("value == nulll");
+ }
+ // Keymaster's KM_DATE is unsigned, but java.util.Date is signed, thus preventing us from
+ // using values larger than 2^63 - 1.
+ if (value.getTime() < 0) {
+ throw new IllegalArgumentException("Date tag value out of range: " + value);
}
- return ((KeymasterDateArgument) arg).date;
+ mArguments.add(new KeymasterDateArgument(tag, value));
}
- public boolean getBoolean(int tag, boolean defaultValue) {
- if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
- throw new IllegalArgumentException("Tag is not a boolean type: " + tag);
+ /**
+ * Adds a date tag with the provided value, if the value is not {@code null}. Does nothing if
+ * the {@code value} is null.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if {@code value} is
+ * before the start of Unix epoch.
+ */
+ public void addDateIfNotNull(int tag, Date value) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
+ throw new IllegalArgumentException("Not a date tag: " + tag);
}
- KeymasterArgument arg = getArgumentByTag(tag);
- if (arg == null) {
- return defaultValue;
+ if (value != null) {
+ addDate(tag, value);
}
- return true;
}
- public byte[] getBlob(int tag, byte[] defaultValue) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_BYTES:
- case KeymasterDefs.KM_BIGNUM:
- break; // Allowed types.
- default:
- throw new IllegalArgumentException("Tag is not a blob type: " + tag);
+ /**
+ * Returns the value of the specified date tag or {@code defaultValue} if the tag is not
+ * present.
+ *
+ * @throws IllegalArgumentException if {@code tag} is not a date tag or if the tag's value
+ * represents a time instant which is after {@code 2^63 - 1} milliseconds since Unix
+ * epoch.
+ */
+ public Date getDate(int tag, Date defaultValue) {
+ if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
+ throw new IllegalArgumentException("Tag is not a date type: " + tag);
}
KeymasterArgument arg = getArgumentByTag(tag);
if (arg == null) {
return defaultValue;
}
- return ((KeymasterBlobArgument) arg).blob;
+ Date result = ((KeymasterDateArgument) arg).date;
+ // Keymaster's KM_DATE is unsigned, but java.util.Date is signed, thus preventing us from
+ // using values larger than 2^63 - 1.
+ if (result.getTime() < 0) {
+ throw new IllegalArgumentException("Tag value too large. Tag: " + tag);
+ }
+ return result;
}
- public List<Integer> getInts(int tag) {
- switch (KeymasterDefs.getTagType(tag)) {
- case KeymasterDefs.KM_INT_REP:
- case KeymasterDefs.KM_ENUM_REP:
- break; // Allowed types.
- default:
- throw new IllegalArgumentException("Tag is not a repeating type: " + tag);
- }
- List<Integer> values = new ArrayList<Integer>();
+ private KeymasterArgument getArgumentByTag(int tag) {
for (KeymasterArgument arg : mArguments) {
if (arg.tag == tag) {
- values.add(((KeymasterIntArgument) arg).value);
+ return arg;
}
}
- return values;
+ return null;
}
- public List<Long> getLongs(int tag) {
- if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG_REP) {
- throw new IllegalArgumentException("Tag is not a repeating long: " + tag);
- }
- List<Long> values = new ArrayList<Long>();
- for (KeymasterArgument arg : mArguments) {
- if (arg.tag == tag) {
- values.add(((KeymasterLongArgument) arg).value);
- }
- }
- return values;
+ public boolean containsTag(int tag) {
+ return getArgumentByTag(tag) != null;
}
public int size() {
@@ -222,4 +366,16 @@ public class KeymasterArguments implements Parcelable {
public int describeContents() {
return 0;
}
+
+ /**
+ * Converts the provided value to non-negative {@link BigInteger}, treating the sign bit of the
+ * provided value as the most significant bit of the result.
+ */
+ public static BigInteger toUint64(long value) {
+ if (value >= 0) {
+ return BigInteger.valueOf(value);
+ } else {
+ return BigInteger.valueOf(value).add(UINT64_RANGE);
+ }
+ }
}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 6a08368..98b44dc 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -40,6 +40,7 @@ import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.UserNotAuthenticatedException;
import android.util.Log;
+import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.util.List;
import java.util.Locale;
@@ -663,14 +664,14 @@ public class KeyStore {
"Failed to obtained key characteristics",
getKeyStoreException(getKeyCharacteristicsErrorCode));
}
- List<Long> keySids =
- keyCharacteristics.getLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
+ List<BigInteger> keySids =
+ keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
if (keySids.isEmpty()) {
// Key is not bound to any SIDs -- no amount of authentication will help here.
return new KeyPermanentlyInvalidatedException();
}
long rootSid = GateKeeper.getSecureUserId();
- if ((rootSid != 0) && (keySids.contains(Long.valueOf(rootSid)))) {
+ if ((rootSid != 0) && (keySids.contains(KeymasterArguments.toUint64(rootSid)))) {
// One of the key's SIDs is the current root SID -- user can be authenticated
// against that SID.
return new UserNotAuthenticatedException();
@@ -678,7 +679,7 @@ public class KeyStore {
long fingerprintOnlySid = getFingerprintOnlySid();
if ((fingerprintOnlySid != 0)
- && (keySids.contains(Long.valueOf(fingerprintOnlySid)))) {
+ && (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) {
// One of the key's SIDs is the current fingerprint SID -- user can be
// authenticated against that SID.
return new UserNotAuthenticatedException();
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
index f412743..83dad0e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
@@ -207,7 +207,7 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC
protected final void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
super.addAlgorithmSpecificParametersToBegin(keymasterArgs);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
+ keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mTagLengthBits);
}
protected final int getTagLengthBits() {
@@ -288,11 +288,11 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC
+ " practices.");
}
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
if (mIv != null) {
- keymasterArgs.addBlob(KeymasterDefs.KM_TAG_NONCE, mIv);
+ keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
}
}
@@ -302,7 +302,7 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC
mIvHasBeenUsed = true;
// NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBlob(KeymasterDefs.KM_TAG_NONCE, null);
+ byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
if ((returnedIv != null) && (returnedIv.length == 0)) {
returnedIv = null;
}
@@ -406,7 +406,7 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC
@Override
public OperationResult update(byte[] input) {
KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addBlob(KeymasterDefs.KM_TAG_ASSOCIATED_DATA, input);
+ keymasterArgs.addBytes(KeymasterDefs.KM_TAG_ASSOCIATED_DATA, input);
// KeyStore does not reflect AAD in inputConsumed, but users of Stream rely on this
// field. We fix this discrepancy here. KeyStore.update contract is that all of AAD
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
index d19a766..f80feef 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreECDSASignatureSpi.java
@@ -89,11 +89,13 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
if (errorCode != KeyStore.NO_ERROR) {
throw getKeyStore().getInvalidKeyException(key.getAlias(), errorCode);
}
- int keySizeBits = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
+ long keySizeBits = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
if (keySizeBits == -1) {
throw new InvalidKeyException("Size of key not known");
+ } else if (keySizeBits > Integer.MAX_VALUE) {
+ throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
}
- mGroupSizeBytes = (keySizeBits + 7) / 8;
+ mGroupSizeBytes = (int) ((keySizeBits + 7) / 8);
super.initKey(key);
}
@@ -112,8 +114,8 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
@Override
protected void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_EC);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_EC);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
}
@Override
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
index f7c184c..cc858d3 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
@@ -159,9 +159,9 @@ public abstract class AndroidKeyStoreHmacSpi extends MacSpi implements KeyStoreC
}
KeymasterArguments keymasterArgs = new KeymasterArguments();
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, mMacSizeBits);
OperationResult opResult = mKeyStore.begin(
mKey.getAlias(),
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 66509e2..258133d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -268,12 +268,12 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- args.addInts(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
- args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
- args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
- args.addInts(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
+ args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
+ args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
KeymasterUtils.addUserAuthArgs(args,
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index ff265cf..3058bd3 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -160,7 +160,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
private int[] mKeymasterSignaturePaddings;
private int[] mKeymasterDigests;
- private long mRSAPublicExponent;
+ private BigInteger mRSAPublicExponent;
protected AndroidKeyStoreKeyPairGeneratorSpi(int keymasterAlgorithm) {
mOriginalKeymasterAlgorithm = keymasterAlgorithm;
@@ -320,7 +320,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
mKeymasterDigests = null;
mKeySizeBits = 0;
mSpec = null;
- mRSAPublicExponent = -1;
+ mRSAPublicExponent = null;
mEncryptionAtRestRequired = false;
mRng = null;
mKeyStore = null;
@@ -353,12 +353,12 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
throw new InvalidAlgorithmParameterException(
"RSA public exponent must be positive: " + publicExponent);
}
- if (publicExponent.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
+ if (publicExponent.compareTo(KeymasterArguments.UINT64_MAX_VALUE) > 0) {
throw new InvalidAlgorithmParameterException(
"Unsupported RSA public exponent: " + publicExponent
- + ". Only exponents <= " + Long.MAX_VALUE + " supported");
+ + ". Maximum supported value: " + KeymasterArguments.UINT64_MAX_VALUE);
}
- mRSAPublicExponent = publicExponent.longValue();
+ mRSAPublicExponent = publicExponent;
break;
}
case KeymasterDefs.KM_ALGORITHM_EC:
@@ -404,13 +404,13 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- args.addInts(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
- args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
- args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterEncryptionPaddings);
- args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
- args.addInts(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
+ args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
+ args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterEncryptionPaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
KeymasterUtils.addUserAuthArgs(args,
mSpec.isUserAuthenticationRequired(),
@@ -493,7 +493,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
private void addAlgorithmSpecificParameters(KeymasterArguments keymasterArgs) {
switch (mKeymasterAlgorithm) {
case KeymasterDefs.KM_ALGORITHM_RSA:
- keymasterArgs.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, mRSAPublicExponent);
+ keymasterArgs.addUnsignedLong(
+ KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, mRSAPublicExponent);
break;
case KeymasterDefs.KM_ALGORITHM_EC:
break;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 967319a..ba39ba7 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -226,8 +226,8 @@ public class AndroidKeyStoreProvider extends Provider {
}
final byte[] x509EncodedPublicKey = exportResult.exportData;
- int keymasterAlgorithm = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_ALGORITHM, -1);
- if (keymasterAlgorithm == -1) {
+ Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
+ if (keymasterAlgorithm == null) {
throw new UnrecoverableKeyException("Key algorithm unknown");
}
@@ -277,13 +277,12 @@ public class AndroidKeyStoreProvider extends Provider {
.initCause(KeyStore.getKeyStoreException(errorCode));
}
- int keymasterAlgorithm = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_ALGORITHM, -1);
- if (keymasterAlgorithm == -1) {
+ Integer keymasterAlgorithm = keyCharacteristics.getEnum(KeymasterDefs.KM_TAG_ALGORITHM);
+ if (keymasterAlgorithm == null) {
throw new UnrecoverableKeyException("Key algorithm unknown");
}
- List<Integer> keymasterDigests =
- keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST);
+ List<Integer> keymasterDigests = keyCharacteristics.getEnums(KeymasterDefs.KM_TAG_DIGEST);
int keymasterDigest;
if (keymasterDigests.isEmpty()) {
keymasterDigest = -1;
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
index 38e216d..1d4ca40 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java
@@ -374,7 +374,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
protected final void addAlgorithmSpecificParametersToBegin(
KeymasterArguments keymasterArgs) {
super.addAlgorithmSpecificParametersToBegin(keymasterArgs);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
}
@Override
@@ -500,11 +500,13 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
if (errorCode != KeyStore.NO_ERROR) {
throw getKeyStore().getInvalidKeyException(keystoreKey.getAlias(), errorCode);
}
- int keySizeBits = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
+ long keySizeBits = keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1);
if (keySizeBits == -1) {
throw new InvalidKeyException("Size of key not known");
+ } else if (keySizeBits > Integer.MAX_VALUE) {
+ throw new InvalidKeyException("Key too large: " + keySizeBits + " bits");
}
- mModulusSizeBytes = (keySizeBits + 7) / 8;
+ mModulusSizeBytes = (int) ((keySizeBits + 7) / 8);
setKey(keystoreKey);
}
@@ -527,14 +529,14 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
@Override
protected void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
int purposeOverride = getKeymasterPurposeOverride();
if ((purposeOverride != -1)
&& ((purposeOverride == KeymasterDefs.KM_PURPOSE_SIGN)
|| (purposeOverride == KeymasterDefs.KM_PURPOSE_VERIFY))) {
// Keymaster sign/verify requires digest to be specified. For raw sign/verify it's NONE.
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
}
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
index 954b71a..ecfc97e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSASignatureSpi.java
@@ -157,8 +157,8 @@ abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSp
@Override
protected final void addAlgorithmSpecificParametersToBegin(
@NonNull KeymasterArguments keymasterArgs) {
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
}
}
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);
}
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 084e30e..de483f4 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -398,18 +398,18 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
importArgs = new KeymasterArguments();
try {
- importArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM,
+ importArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM,
KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(
key.getAlgorithm()));
@KeyProperties.PurposeEnum int purposes = spec.getPurposes();
- importArgs.addInts(KeymasterDefs.KM_TAG_PURPOSE,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_PURPOSE,
KeyProperties.Purpose.allToKeymaster(purposes));
if (spec.isDigestsSpecified()) {
- importArgs.addInts(KeymasterDefs.KM_TAG_DIGEST,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_DIGEST,
KeyProperties.Digest.allToKeymaster(spec.getDigests()));
}
- importArgs.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE,
KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes()));
int[] keymasterEncryptionPaddings =
KeyProperties.EncryptionPadding.allToKeymaster(
@@ -429,8 +429,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
}
}
}
- importArgs.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
- importArgs.addInts(KeymasterDefs.KM_TAG_PADDING,
+ importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
+ importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
KeymasterUtils.addUserAuthArgs(importArgs,
spec.isUserAuthenticationRequired(),
@@ -567,7 +567,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
}
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm);
int[] keymasterDigests;
if (params.isDigestsSpecified()) {
@@ -606,7 +606,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
keymasterDigests = EmptyArray.INT;
}
}
- args.addInts(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
+ args.addEnums(KeymasterDefs.KM_TAG_DIGEST, keymasterDigests);
if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
if (keymasterDigests.length == 0) {
throw new KeyStoreException("At least one digest algorithm must be specified"
@@ -630,14 +630,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
}
}
}
- args.addInts(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
- args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
+ args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes));
+ args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
if (params.getSignaturePaddings().length > 0) {
throw new KeyStoreException("Signature paddings not supported for symmetric keys");
}
int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
params.getEncryptionPaddings());
- args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
+ args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
KeymasterUtils.addUserAuthArgs(args,
params.isUserAuthenticationRequired(),
params.getUserAuthenticationValidityDurationSeconds());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
index 6c53c6a..486519c 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreUnauthenticatedAESCipherSpi.java
@@ -240,11 +240,11 @@ class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSp
+ " practices.");
}
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
- keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockMode);
+ keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
if ((mIvRequired) && (mIv != null)) {
- keymasterArgs.addBlob(KeymasterDefs.KM_TAG_NONCE, mIv);
+ keymasterArgs.addBytes(KeymasterDefs.KM_TAG_NONCE, mIv);
}
}
@@ -254,7 +254,7 @@ class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSp
mIvHasBeenUsed = true;
// NOTE: Keymaster doesn't always return an IV, even if it's used.
- byte[] returnedIv = keymasterArgs.getBlob(KeymasterDefs.KM_TAG_NONCE, null);
+ byte[] returnedIv = keymasterArgs.getBytes(KeymasterDefs.KM_TAG_NONCE, null);
if ((returnedIv != null) && (returnedIv.length == 0)) {
returnedIv = null;
}
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 4b37d90..0006601 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -110,8 +110,9 @@ public abstract class KeymasterUtils {
"At least one fingerprint must be enrolled to create keys requiring user"
+ " authentication for every use");
}
- args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, fingerprintOnlySid);
- args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
+ KeymasterArguments.toUint64(fingerprintOnlySid));
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
} else {
// The key is authorized for use for the specified amount of time after the user has
// authenticated. Whatever unlocks the secure lock screen should authorize this key.
@@ -120,10 +121,11 @@ public abstract class KeymasterUtils {
throw new IllegalStateException("Secure lock screen must be enabled"
+ " to create keys requiring user authentication");
}
- args.addLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, rootSid);
- args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
+ KeymasterArguments.toUint64(rootSid));
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
- args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
userAuthenticationValidityDurationSeconds);
}
}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 0b60c62..319cf32 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -702,14 +702,13 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
private KeyCharacteristics generateRsaKey(String name) throws Exception {
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ 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.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
- args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
- RSAKeyGenParameterSpec.F4.longValue());
+ 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);
@@ -726,14 +725,13 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
byte[] entropy = new byte[] {1,2,3,4,5};
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ 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.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
- args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
- RSAKeyGenParameterSpec.F4.longValue());
+ 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);
@@ -759,16 +757,15 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
String name = "test";
byte[] id = new byte[] {0x01, 0x02, 0x03};
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+ 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.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
- args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
- args.addLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
- RSAKeyGenParameterSpec.F4.longValue());
+ args.addBytes(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
@@ -795,12 +792,12 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
public void testAesGcmEncryptSuccess() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
+ 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();
@@ -808,10 +805,10 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 128);
+ 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;
@@ -832,12 +829,12 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
private int importAesKey(String name, byte[] key, int size, int mode) {
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, mode);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, size);
+ 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.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mode);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, size);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
return mKeyStore.importKey(name, args, KeymasterDefs.KM_KEY_FORMAT_RAW, key, 0,
new KeyCharacteristics());
@@ -877,9 +874,9 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
hexToBytes("b6ed21b99ca6f4f9f153e7b1beafed1d"),
hexToBytes("23304b7a39f9f3ff067d8d8f9e24ecc7")};
KeymasterArguments beginArgs = new KeymasterArguments();
- beginArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- beginArgs.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
- beginArgs.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ beginArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ beginArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+ beginArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
for (int i = 0; i < testVectors.length; i++) {
byte[] cipherText = doOperation(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, testVectors[i],
beginArgs);
@@ -897,12 +894,12 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
public void testOperationPruning() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
+ 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_CTR);
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
@@ -910,9 +907,9 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
true, args, null);
assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
@@ -930,13 +927,13 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
public void testAuthNeeded() throws Exception {
String name = "test";
KeymasterArguments args = new KeymasterArguments();
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
- args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
- args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
- args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
- args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
- args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
+ 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_PKCS7);
+ args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
+ args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+ args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
KeyCharacteristics outCharacteristics = new KeyCharacteristics();
int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);