Merge "Add Keymaster 0.4 binder API"
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index bf51ed1..ac6bbb7 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -16,6 +16,10 @@
 
 package android.security;
 
+import android.security.keymaster.ExportResult;
+import android.security.keymaster.KeyCharacteristics;
+import android.security.keymaster.KeymasterArguments;
+import android.security.keymaster.OperationResult;
 import android.security.KeystoreArguments;
 
 /**
@@ -52,4 +56,19 @@
     int reset_uid(int uid);
     int sync_uid(int sourceUid, int targetUid);
     int password_uid(String password, int uid);
+
+    // Keymaster 0.4 methods
+    int addRngEntropy(in byte[] data);
+    int generateKey(String alias, in KeymasterArguments arguments, int uid, int flags,
+        out KeyCharacteristics characteristics);
+    int getKeyCharacteristics(String alias, in byte[] clientId,
+        in byte[] appId, out KeyCharacteristics characteristics);
+    int importKey(String alias, in KeymasterArguments arguments, int format,
+        in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics);
+    ExportResult exportKey(String alias, int format, in byte[] clientId, in byte[] appId);
+    OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable,
+        in KeymasterArguments params, out KeymasterArguments operationParams);
+    OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input);
+    OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature);
+    int abort(IBinder handle);
 }
diff --git a/core/java/android/security/keymaster/ExportResult.aidl b/core/java/android/security/keymaster/ExportResult.aidl
new file mode 100644
index 0000000..f522355
--- /dev/null
+++ b/core/java/android/security/keymaster/ExportResult.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+/* @hide */
+parcelable ExportResult;
diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java
new file mode 100644
index 0000000..bb44c03
--- /dev/null
+++ b/core/java/android/security/keymaster/ExportResult.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Class for handling parceling the return values from keymaster's export operation.
+ * @hide
+ */
+public class ExportResult implements Parcelable {
+    public final int resultCode;
+    public final byte[] exportData;
+
+    public static final Parcelable.Creator<ExportResult> CREATOR = new
+            Parcelable.Creator<ExportResult>() {
+                public ExportResult createFromParcel(Parcel in) {
+                    return new ExportResult(in);
+                }
+
+                public ExportResult[] newArray(int length) {
+                    return new ExportResult[length];
+                }
+            };
+
+    protected ExportResult(Parcel in) {
+        resultCode = in.readInt();
+        exportData = in.createByteArray();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(resultCode);
+        out.writeByteArray(exportData);
+    }
+};
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.aidl b/core/java/android/security/keymaster/KeyCharacteristics.aidl
new file mode 100644
index 0000000..15014b1
--- /dev/null
+++ b/core/java/android/security/keymaster/KeyCharacteristics.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+/* @hide */
+parcelable KeyCharacteristics;
diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java
new file mode 100644
index 0000000..b803a1b
--- /dev/null
+++ b/core/java/android/security/keymaster/KeyCharacteristics.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+
+/**
+ * @hide
+ */
+public class KeyCharacteristics implements Parcelable {
+    public KeymasterArguments swEnforced;
+    public KeymasterArguments hwEnforced;
+
+    public static final Parcelable.Creator<KeyCharacteristics> CREATOR = new
+            Parcelable.Creator<KeyCharacteristics>() {
+                public KeyCharacteristics createFromParcel(Parcel in) {
+                    return new KeyCharacteristics(in);
+                }
+
+                public KeyCharacteristics[] newArray(int length) {
+                    return new KeyCharacteristics[length];
+                }
+            };
+
+    public KeyCharacteristics() {}
+
+    protected KeyCharacteristics(Parcel in) {
+        readFromParcel(in);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        swEnforced.writeToParcel(out, flags);
+        hwEnforced.writeToParcel(out, flags);
+    }
+
+    public void readFromParcel(Parcel in) {
+        swEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
+        hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
+    }
+}
+
diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java
new file mode 100644
index 0000000..9a1c894
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterArgument.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelFormatException;
+
+/**
+ * Base class for the Java side of a Keymaster tagged argument.
+ * <p>
+ * Serialization code for this and subclasses must be kept in sync with system/security/keystore
+ * and with hardware/libhardware/include/hardware/keymaster_defs.h
+ * @hide
+ */
+abstract class KeymasterArgument implements Parcelable {
+    public final int tag;
+
+    public static final Parcelable.Creator<KeymasterArgument> CREATOR = new
+            Parcelable.Creator<KeymasterArgument>() {
+                public KeymasterArgument createFromParcel(Parcel in) {
+                    final int pos = in.dataPosition();
+                    final int tag = in.readInt();
+                    switch (KeymasterDefs.getTagType(tag)) {
+                        case KeymasterDefs.KM_ENUM:
+                        case KeymasterDefs.KM_ENUM_REP:
+                        case KeymasterDefs.KM_INT:
+                        case KeymasterDefs.KM_INT_REP:
+                            return new KeymasterIntArgument(tag, in);
+                        case KeymasterDefs.KM_LONG:
+                            return new KeymasterLongArgument(tag, in);
+                        case KeymasterDefs.KM_DATE:
+                            return new KeymasterDateArgument(tag, in);
+                        case KeymasterDefs.KM_BYTES:
+                        case KeymasterDefs.KM_BIGNUM:
+                            return new KeymasterBlobArgument(tag, in);
+                        case KeymasterDefs.KM_BOOL:
+                            return new KeymasterBooleanArgument(tag, in);
+                        default:
+                            throw new ParcelFormatException("Bad tag: " + tag + " at " + pos);
+                    }
+                }
+                public KeymasterArgument[] newArray(int size) {
+                    return new KeymasterArgument[size];
+                }
+            };
+
+    protected KeymasterArgument(int tag) {
+        this.tag = tag;
+    }
+
+    /**
+     * Writes the value of this argument, if any, to the provided parcel.
+     */
+    public abstract void writeValue(Parcel out);
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(tag);
+        writeValue(out);
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterArguments.aidl b/core/java/android/security/keymaster/KeymasterArguments.aidl
new file mode 100644
index 0000000..7aef5a6
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterArguments.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+/* @hide */
+parcelable KeymasterArguments;
diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java
new file mode 100644
index 0000000..b5fd4bd
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterArguments.java
@@ -0,0 +1,186 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Utility class for the java side of user specified Keymaster arguments.
+ * <p>
+ * Serialization code for this and subclasses must be kept in sync with system/security/keystore
+ * @hide
+ */
+public class KeymasterArguments implements Parcelable {
+    List<KeymasterArgument> mArguments;
+
+    public static final Parcelable.Creator<KeymasterArguments> CREATOR = new
+            Parcelable.Creator<KeymasterArguments>() {
+                public KeymasterArguments createFromParcel(Parcel in) {
+                    return new KeymasterArguments(in);
+                }
+                public KeymasterArguments[] newArray(int size) {
+                    return new KeymasterArguments[size];
+                }
+            };
+
+    public KeymasterArguments() {
+        mArguments = new ArrayList<KeymasterArgument>();
+    }
+
+    private KeymasterArguments(Parcel in) {
+        mArguments = in.createTypedArrayList(KeymasterArgument.CREATOR);
+    }
+
+    public void addInt(int tag, int value) {
+        mArguments.add(new KeymasterIntArgument(tag, value));
+    }
+
+    public void addBoolean(int tag) {
+        mArguments.add(new KeymasterBooleanArgument(tag));
+    }
+
+    public void addLong(int tag, long value) {
+        mArguments.add(new KeymasterLongArgument(tag, value));
+    }
+
+    public void addBlob(int tag, byte[] value) {
+        mArguments.add(new KeymasterBlobArgument(tag, value));
+    }
+
+    public void addDate(int tag, Date value) {
+        mArguments.add(new KeymasterDateArgument(tag, value));
+    }
+
+    private KeymasterArgument getArgumentByTag(int tag) {
+        for (KeymasterArgument arg : mArguments) {
+            if (arg.tag == tag) {
+                return arg;
+            }
+        }
+        return null;
+    }
+
+    public boolean containsTag(int tag) {
+        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) {
+        if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG) {
+            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 int size() {
+        return mArguments.size();
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeTypedList(mArguments);
+    }
+
+    public void readFromParcel(Parcel in) {
+        in.readTypedList(mArguments, KeymasterArgument.CREATOR);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java
new file mode 100644
index 0000000..27f1153
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+class KeymasterBlobArgument extends KeymasterArgument {
+    public final byte[] blob;
+
+    public KeymasterBlobArgument(int tag, byte[] blob) {
+        super(tag);
+        this.blob = blob;
+    }
+
+    public KeymasterBlobArgument(int tag, Parcel in) {
+        super(tag);
+        blob = in.createByteArray();
+    }
+
+    @Override
+    public void writeValue(Parcel out) {
+        out.writeByteArray(blob);
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java
new file mode 100644
index 0000000..8e17db4
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+class KeymasterBooleanArgument extends KeymasterArgument {
+
+    // Boolean arguments are always true if they exist and false if they don't.
+    public final boolean value = true;
+
+    public KeymasterBooleanArgument(int tag) {
+        super(tag);
+    }
+
+    public KeymasterBooleanArgument(int tag, Parcel in) {
+        super(tag);
+    }
+
+    @Override
+    public void writeValue(Parcel out) {
+        // Do nothing, value is implicit.
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java
new file mode 100644
index 0000000..e8f4055
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterDateArgument.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Date;
+
+/**
+ * @hide
+ */
+class KeymasterDateArgument extends KeymasterArgument {
+    public final Date date;
+
+    public KeymasterDateArgument(int tag, Date date) {
+        super(tag);
+        this.date = date;
+    }
+
+    public KeymasterDateArgument(int tag, Parcel in) {
+        super(tag);
+        date = new Date(in.readLong());
+    }
+
+    @Override
+    public void writeValue(Parcel out) {
+        out.writeLong(date.getTime());
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
new file mode 100644
index 0000000..88cad79
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+/**
+ * Class tracking all the keymaster enum values needed for the binder API to keystore.
+ * This must be kept in sync with hardware/libhardware/include/hardware/keymaster_defs.h
+ * See keymaster_defs.h for detailed descriptions of each constant.
+ * @hide
+ */
+public final class KeymasterDefs {
+
+    private KeymasterDefs() {}
+
+    // Tag types.
+    public static final int KM_INVALID = 0 << 28;
+    public static final int KM_ENUM = 1 << 28;
+    public static final int KM_ENUM_REP = 2 << 28;
+    public static final int KM_INT = 3 << 28;
+    public static final int KM_INT_REP = 4 << 28;
+    public static final int KM_LONG = 5 << 28;
+    public static final int KM_DATE = 6 << 28;
+    public static final int KM_BOOL = 7 << 28;
+    public static final int KM_BIGNUM = 8 << 28;
+    public static final int KM_BYTES = 9 << 28;
+
+    // Tag values.
+    public static final int KM_TAG_INVALID = KM_INVALID | 0;
+    public static final int KM_TAG_PURPOSE = KM_ENUM_REP | 1;
+    public static final int KM_TAG_ALGORITHM = KM_ENUM | 2;
+    public static final int KM_TAG_KEY_SIZE = KM_INT | 3;
+    public static final int KM_TAG_BLOCK_MODE = KM_ENUM | 4;
+    public static final int KM_TAG_DIGEST = KM_ENUM | 5;
+    public static final int KM_TAG_MAC_LENGTH = KM_INT | 6;
+    public static final int KM_TAG_PADDING = KM_ENUM | 7;
+    public static final int KM_TAG_RETURN_UNAUTHED = KM_BOOL | 8;
+    public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 9;
+
+    public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101;
+    public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102;
+    public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 705;
+
+    public static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_LONG | 200;
+    public static final int KM_TAG_DSA_GENERATOR = KM_BIGNUM | 201;
+    public static final int KM_TAG_DSA_P = KM_BIGNUM | 202;
+    public static final int KM_TAG_DSA_Q = KM_BIGNUM | 203;
+    public static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400;
+    public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401;
+    public static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402;
+    public static final int KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_INT | 403;
+    public static final int KM_TAG_MAX_USES_PER_BOOT = KM_INT | 404;
+
+    public static final int KM_TAG_ALL_USERS = KM_BOOL | 500;
+    public static final int KM_TAG_USER_ID = KM_INT | 501;
+    public static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 502;
+    public static final int KM_TAG_USER_AUTH_ID = KM_INT_REP | 503;
+    public static final int KM_TAG_AUTH_TIMEOUT = KM_INT | 504;
+
+    public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
+    public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
+
+    public static final int KM_TAG_APPLICATION_DATA = KM_BYTES | 700;
+    public static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701;
+    public static final int KM_TAG_ORIGIN = KM_ENUM | 702;
+    public static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703;
+    public static final int KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704;
+
+    public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000;
+    public static final int KM_TAG_NONCE = KM_BYTES | 1001;
+    public static final int KM_TAG_CHUNK_LENGTH = KM_INT | 1002;
+
+    // Algorithm values.
+    public static final int KM_ALGORITHM_RSA = 1;
+    public static final int KM_ALGORITHM_DSA = 2;
+    public static final int KM_ALGORITHM_ECDSA = 3;
+    public static final int KM_ALGORITHM_ECIES = 4;
+    public static final int KM_ALGORITHM_AES = 32;
+    public static final int KM_ALGORITHM_3DES = 33;
+    public static final int KM_ALGORITHM_SKIPJACK = 34;
+    public static final int KM_ALGORITHM_MARS = 48;
+    public static final int KM_ALGORITHM_RC6 = 49;
+    public static final int KM_ALGORITHM_SERPENT = 50;
+    public static final int KM_ALGORITHM_TWOFISH = 51;
+    public static final int KM_ALGORITHM_IDEA = 52;
+    public static final int KM_ALGORITHM_RC5 = 53;
+    public static final int KM_ALGORITHM_CAST5 = 54;
+    public static final int KM_ALGORITHM_BLOWFISH = 55;
+    public static final int KM_ALGORITHM_RC4 = 64;
+    public static final int KM_ALGORITHM_CHACHA20 = 65;
+    public static final int KM_ALGORITHM_HMAC = 128;
+
+    // Block modes.
+    public static final int KM_MODE_FIRST_UNAUTHENTICATED = 1;
+    public static final int KM_MODE_ECB = KM_MODE_FIRST_UNAUTHENTICATED;
+    public static final int KM_MODE_CBC = 2;
+    public static final int KM_MODE_CBC_CTS = 3;
+    public static final int KM_MODE_CTR = 4;
+    public static final int KM_MODE_OFB = 5;
+    public static final int KM_MODE_CFB = 6;
+    public static final int KM_MODE_XTS = 7;
+    public static final int KM_MODE_FIRST_AUTHENTICATED = 32;
+    public static final int KM_MODE_GCM = KM_MODE_FIRST_AUTHENTICATED;
+    public static final int KM_MODE_OCB = 33;
+    public static final int KM_MODE_CCM = 34;
+    public static final int KM_MODE_FIRST_MAC = 128;
+    public static final int KM_MODE_CMAC = KM_MODE_FIRST_MAC;
+    public static final int KM_MODE_POLY1305 = 129;
+
+    // Padding modes.
+    public static final int KM_PAD_NONE = 1;
+    public static final int KM_PAD_RSA_OAEP = 2;
+    public static final int KM_PAD_RSA_PSS = 3;
+    public static final int KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4;
+    public static final int KM_PAD_RSA_PKCS1_1_5_SIGN = 5;
+    public static final int KM_PAD_ANSI_X923 = 32;
+    public static final int KM_PAD_ISO_10126 = 33;
+    public static final int KM_PAD_ZERO = 64;
+    public static final int KM_PAD_PKCS7 = 65;
+    public static final int KM_PAD_ISO_7816_4 = 66;
+
+    // Digest modes.
+    public static final int KM_DIGEST_NONE = 0;
+    public static final int KM_DIGEST_MD5 = 1;
+    public static final int KM_DIGEST_SHA1 = 2;
+    public static final int KM_DIGEST_SHA_2_224 = 3;
+    public static final int KM_DIGEST_SHA_2_256 = 4;
+    public static final int KM_DIGEST_SHA_2_384 = 5;
+    public static final int KM_DIGEST_SHA_2_512 = 6;
+    public static final int KM_DIGEST_SHA_3_256 = 7;
+    public static final int KM_DIGEST_SHA_3_384 = 8;
+    public static final int KM_DIGEST_SHA_3_512 = 9;
+
+    // Key origins.
+    public static final int KM_ORIGIN_HARDWARE = 0;
+    public static final int KM_ORIGIN_SOFTWARE = 1;
+    public static final int KM_ORIGIN_IMPORTED = 2;
+
+    // Key usability requirements.
+    public static final int KM_BLOB_STANDALONE = 0;
+    public static final int KM_BLOB_REQUIRES_FILE_SYSTEM = 1;
+
+    // Operation Purposes.
+    public static final int KM_PURPOSE_ENCRYPT = 0;
+    public static final int KM_PURPOSE_DECRYPT = 1;
+    public static final int KM_PURPOSE_SIGN = 2;
+    public static final int KM_PURPOSE_VERIFY = 3;
+
+    // Key formats.
+    public static final int KM_KEY_FORMAT_X509 = 0;
+    public static final int KM_KEY_FORMAT_PKCS8 = 1;
+    public static final int KM_KEY_FORMAT_PKCS12 = 2;
+    public static final int KM_KEY_FORMAT_RAW = 3;
+
+    // Error codes.
+    public static final int KM_ERROR_OK = 0;
+    public static final int KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = -1;
+    public static final int KM_ERROR_UNSUPPORTED_PURPOSE = -2;
+    public static final int KM_ERROR_INCOMPATIBLE_PURPOSE = -3;
+    public static final int KM_ERROR_UNSUPPORTED_ALGORITHM = -4;
+    public static final int KM_ERROR_INCOMPATIBLE_ALGORITHM = -5;
+    public static final int KM_ERROR_UNSUPPORTED_KEY_SIZE = -6;
+    public static final int KM_ERROR_UNSUPPORTED_BLOCK_MODE = -7;
+    public static final int KM_ERROR_INCOMPATIBLE_BLOCK_MODE = -8;
+    public static final int KM_ERROR_UNSUPPORTED_TAG_LENGTH = -9;
+    public static final int KM_ERROR_UNSUPPORTED_PADDING_MODE = -10;
+    public static final int KM_ERROR_INCOMPATIBLE_PADDING_MODE = -11;
+    public static final int KM_ERROR_UNSUPPORTED_DIGEST = -12;
+    public static final int KM_ERROR_INCOMPATIBLE_DIGEST = -13;
+    public static final int KM_ERROR_INVALID_EXPIRATION_TIME = -14;
+    public static final int KM_ERROR_INVALID_USER_ID = -15;
+    public static final int KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT = -16;
+    public static final int KM_ERROR_UNSUPPORTED_KEY_FORMAT = -17;
+    public static final int KM_ERROR_INCOMPATIBLE_KEY_FORMAT = -18;
+    public static final int KM_ERROR_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19;
+    public static final int KM_ERROR_UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20;
+    public static final int KM_ERROR_INVALID_INPUT_LENGTH = -21;
+    public static final int KM_ERROR_KEY_EXPORT_OPTIONS_INVALID = -22;
+    public static final int KM_ERROR_DELEGATION_NOT_ALLOWED = -23;
+    public static final int KM_ERROR_KEY_NOT_YET_VALID = -24;
+    public static final int KM_ERROR_KEY_EXPIRED = -25;
+    public static final int KM_ERROR_KEY_USER_NOT_AUTHENTICATED = -26;
+    public static final int KM_ERROR_OUTPUT_PARAMETER_NULL = -27;
+    public static final int KM_ERROR_INVALID_OPERATION_HANDLE = -28;
+    public static final int KM_ERROR_INSUFFICIENT_BUFFER_SPACE = -29;
+    public static final int KM_ERROR_VERIFICATION_FAILED = -30;
+    public static final int KM_ERROR_TOO_MANY_OPERATIONS = -31;
+    public static final int KM_ERROR_UNEXPECTED_NULL_POINTER = -32;
+    public static final int KM_ERROR_INVALID_KEY_BLOB = -33;
+    public static final int KM_ERROR_IMPORTED_KEY_NOT_ENCRYPTED = -34;
+    public static final int KM_ERROR_IMPORTED_KEY_DECRYPTION_FAILED = -35;
+    public static final int KM_ERROR_IMPORTED_KEY_NOT_SIGNED = -36;
+    public static final int KM_ERROR_IMPORTED_KEY_VERIFICATION_FAILED = -37;
+    public static final int KM_ERROR_INVALID_ARGUMENT = -38;
+    public static final int KM_ERROR_UNSUPPORTED_TAG = -39;
+    public static final int KM_ERROR_INVALID_TAG = -40;
+    public static final int KM_ERROR_MEMORY_ALLOCATION_FAILED = -41;
+    public static final int KM_ERROR_INVALID_RESCOPING = -42;
+    public static final int KM_ERROR_INVALID_DSA_PARAMS = -43;
+    public static final int KM_ERROR_IMPORT_PARAMETER_MISMATCH = -44;
+    public static final int KM_ERROR_SECURE_HW_ACCESS_DENIED = -45;
+    public static final int KM_ERROR_OPERATION_CANCELLED = -46;
+    public static final int KM_ERROR_CONCURRENT_ACCESS_CONFLICT = -47;
+    public static final int KM_ERROR_SECURE_HW_BUSY = -48;
+    public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49;
+    public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50;
+    public static final int KM_ERROR_UNIMPLEMENTED = -100;
+    public static final int KM_ERROR_VERSION_MISMATCH = -101;
+    public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
+
+    public static int getTagType(int tag) {
+        return tag & (0xF << 28);
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java
new file mode 100644
index 0000000..71797ae
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterIntArgument.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+class KeymasterIntArgument extends KeymasterArgument {
+    public final int value;
+
+    public KeymasterIntArgument(int tag, int value) {
+        super(tag);
+        this.value = value;
+    }
+
+    public KeymasterIntArgument(int tag, Parcel in) {
+        super(tag);
+        value = in.readInt();
+    }
+
+    @Override
+    public void writeValue(Parcel out) {
+        out.writeInt(value);
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java
new file mode 100644
index 0000000..781b1ab
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterLongArgument.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+class KeymasterLongArgument extends KeymasterArgument {
+    public final long value;
+
+    public KeymasterLongArgument(int tag, long value) {
+        super(tag);
+        this.value = value;
+    }
+
+    public KeymasterLongArgument(int tag, Parcel in) {
+        super(tag);
+        value = in.readLong();
+    }
+
+    @Override
+    public void writeValue(Parcel out) {
+        out.writeLong(value);
+    }
+}
diff --git a/core/java/android/security/keymaster/OperationResult.aidl b/core/java/android/security/keymaster/OperationResult.aidl
new file mode 100644
index 0000000..699e8d0
--- /dev/null
+++ b/core/java/android/security/keymaster/OperationResult.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+/* @hide */
+parcelable OperationResult;
diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java
new file mode 100644
index 0000000..ad54c96
--- /dev/null
+++ b/core/java/android/security/keymaster/OperationResult.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+
+/**
+ * Class for handling the parceling of return values from keymaster crypto operations
+ * (begin/update/finish).
+ * @hide
+ */
+public class OperationResult implements Parcelable {
+    public final int resultCode;
+    public final IBinder token;
+    public final int inputConsumed;
+    public final byte[] output;
+
+    public static final Parcelable.Creator<OperationResult> CREATOR = new
+            Parcelable.Creator<OperationResult>() {
+                public OperationResult createFromParcel(Parcel in) {
+                    return new OperationResult(in);
+                }
+
+                public OperationResult[] newArray(int length) {
+                    return new OperationResult[length];
+                }
+            };
+
+    protected OperationResult(Parcel in) {
+        resultCode = in.readInt();
+        token = in.readStrongBinder();
+        inputConsumed = in.readInt();
+        output = in.createByteArray();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(resultCode);
+        out.writeStrongBinder(token);
+        out.writeInt(inputConsumed);
+        out.writeByteArray(output);
+    }
+}