Merge "Keymaster INT, LONG and DATE tag values are unsigned." into mnc-dev
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 @@
 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 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 @@
         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);
+        Date result = swEnforced.getDate(tag, null);
+        if (result != null) {
+            return result;
         }
-        return result;
+        return hwEnforced.getDate(tag, null);
     }
 
-    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;
-        }
-    }
-
+    /**
+     * 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 @@
 
     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 @@
                             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 @@
 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 @@
  * @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,42 +61,279 @@
         mArguments = in.createTypedArrayList(KeymasterArgument.CREATOR);
     }
 
-    public void addInt(int tag, int 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);
+    }
+
+    /**
+     * 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) {
+            addEnumTag(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);
+    }
+
+    /**
+     * 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;
+    }
+
+    private void addEnumTag(int tag, int value) {
         mArguments.add(new KeymasterIntArgument(tag, value));
     }
 
-    public void addInts(int tag, int... values) {
-        for (int value : values) {
-            addInt(tag, value);
-        }
+    private int getEnumTagValue(KeymasterArgument arg) {
+        return ((KeymasterIntArgument) arg).value;
     }
 
-    public void addLongs(int tag, long... values) {
-        for (long value : values) {
-            addLong(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));
     }
 
+    /**
+     * 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;
+    }
+
+    /**
+     * 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) {
+                values.add(getLongTagValue(arg));
+            }
+        }
+        return values;
+    }
+
+    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 void addLong(int tag, long value) {
-        mArguments.add(new KeymasterLongArgument(tag, value));
+    /**
+     * 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 false;
+        }
+        return true;
     }
 
-    public void addBlob(int tag, byte[] value) {
+    /**
+     * 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 ((KeymasterBlobArgument) arg).blob;
+    }
+
+    /**
+     * 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("Not a date tag: " + tag);
+        }
+        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);
+        }
         mArguments.add(new KeymasterDateArgument(tag, value));
     }
 
+    /**
+     * 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 (value != null) {
-            mArguments.add(new KeymasterDateArgument(tag, value));
+        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) {
+            throw new IllegalArgumentException("Not a date tag: " + tag);
         }
+        if (value != null) {
+            addDate(tag, value);
+        }
+    }
+
+    /**
+     * 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;
+        }
+        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;
     }
 
     private KeymasterArgument getArgumentByTag(int tag) {
@@ -104,107 +349,6 @@
         return getArgumentByTag(tag) != null;
     }
 
-    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);
-        }
-        KeymasterArgument arg = getArgumentByTag(tag);
-        if (arg == null) {
-            return defaultValue;
-        }
-        return ((KeymasterIntArgument) arg).value;
-    }
-
-    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);
-        }
-        KeymasterArgument arg = getArgumentByTag(tag);
-        if (arg == null) {
-            return defaultValue;
-        }
-        return ((KeymasterLongArgument) arg).value;
-    }
-
-    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 ((KeymasterDateArgument) arg).date;
-    }
-
-    public boolean getBoolean(int tag, boolean defaultValue) {
-        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) {
-            throw new IllegalArgumentException("Tag is not a boolean type: " + tag);
-        }
-        KeymasterArgument arg = getArgumentByTag(tag);
-        if (arg == null) {
-            return defaultValue;
-        }
-        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);
-        }
-        KeymasterArgument arg = getArgumentByTag(tag);
-        if (arg == null) {
-            return defaultValue;
-        }
-        return ((KeymasterBlobArgument) arg).blob;
-    }
-
-    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>();
-        for (KeymasterArgument arg : mArguments) {
-            if (arg.tag == tag) {
-                values.add(((KeymasterIntArgument) arg).value);
-            }
-        }
-        return values;
-    }
-
-    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 int size() {
         return mArguments.size();
     }
@@ -222,4 +366,16 @@
     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.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 @@
                             "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 @@
 
                 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 @@
         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 @@
                     + " 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 @@
         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 @@
         @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 @@
         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 @@
     @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 @@
         }
 
         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 @@
         }
 
         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 @@
     private int[] mKeymasterSignaturePaddings;
     private int[] mKeymasterDigests;
 
-    private long mRSAPublicExponent;
+    private BigInteger mRSAPublicExponent;
 
     protected AndroidKeyStoreKeyPairGeneratorSpi(int keymasterAlgorithm) {
         mOriginalKeymasterAlgorithm = keymasterAlgorithm;
@@ -320,7 +320,7 @@
         mKeymasterDigests = null;
         mKeySizeBits = 0;
         mSpec = null;
-        mRSAPublicExponent = -1;
+        mRSAPublicExponent = null;
         mEncryptionAtRestRequired = false;
         mRng = null;
         mKeyStore = null;
@@ -353,12 +353,12 @@
                     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 @@
         }
 
         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 @@
     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 @@
         }
         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 @@
                             .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 @@
         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 @@
         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 @@
     @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 @@
     @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 @@
             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 @@
                     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 @@
                 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 @@
                 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 @@
 
             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 @@
                         }
                     }
                 }
-                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 @@
         }
 
         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 @@
                 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 @@
                 }
             }
         }
-        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 @@
                     + " 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 @@
         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 @@
                         "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 @@
                 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 @@
 
     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 @@
         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 @@
         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 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 @@
         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 @@
 
     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 @@
             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 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 @@
         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 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);