diff --git a/keymaster/.clang-format b/keymaster/.clang-format
new file mode 100644
index 0000000..5747e19
--- /dev/null
+++ b/keymaster/.clang-format
@@ -0,0 +1,10 @@
+BasedOnStyle: LLVM
+IndentWidth: 4
+UseTab: Never
+BreakBeforeBraces: Attach
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+ColumnLimit: 100
+PointerBindsToType: true
+SpacesBeforeTrailingComments: 2
diff --git a/keymaster/Android.mk b/keymaster/Android.mk
new file mode 100644
index 0000000..233ed95
--- /dev/null
+++ b/keymaster/Android.mk
@@ -0,0 +1,180 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH := $(call my-dir)
+
+###
+# libkeymaster_messages contains just the code necessary to communicate with a
+# AndroidKeymaster implementation, e.g. one running in TrustZone.
+##
+include $(CLEAR_VARS)
+LOCAL_MODULE:= libkeymaster_messages
+LOCAL_SRC_FILES:= \
+		android_keymaster_messages.cpp \
+		android_keymaster_utils.cpp \
+		authorization_set.cpp \
+		keymaster_tags.cpp \
+		logger.cpp \
+		serializable.cpp
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/include
+LOCAL_CFLAGS = -Wall -Werror -Wunused -DKEYMASTER_NAME_TAGS
+LOCAL_CLANG := true
+# TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
+# Currently, if enabled, these flags will cause an internal error in Clang.
+LOCAL_CLANG_CFLAGS += -fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
+LOCAL_MODULE_TAGS := optional
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_SHARED_LIBRARY)
+
+###
+# libkeymaster1 contains almost everything needed for a keymaster1
+# implementation, lacking only a subclass of the (abstract) KeymasterContext
+# class to provide environment-specific services and a wrapper to translate from
+# the function-based keymaster HAL API to the message-based AndroidKeymaster API.
+###
+include $(CLEAR_VARS)
+LOCAL_MODULE:= libkeymaster1
+LOCAL_SRC_FILES:= \
+		aes_key.cpp \
+		aes_operation.cpp \
+		android_keymaster.cpp \
+		android_keymaster_messages.cpp \
+		android_keymaster_utils.cpp \
+		asymmetric_key.cpp \
+		asymmetric_key_factory.cpp \
+		attestation_record.cpp \
+		auth_encrypted_key_blob.cpp \
+		ec_key.cpp \
+		ec_key_factory.cpp \
+		ecdsa_operation.cpp \
+		ecies_kem.cpp \
+		hkdf.cpp \
+		hmac.cpp \
+		hmac_key.cpp \
+		hmac_operation.cpp \
+		integrity_assured_key_blob.cpp \
+		iso18033kdf.cpp \
+		kdf.cpp \
+		key.cpp \
+		keymaster_enforcement.cpp \
+		nist_curve_key_exchange.cpp \
+		ocb.c \
+		ocb_utils.cpp \
+		openssl_err.cpp \
+		openssl_utils.cpp \
+		operation.cpp \
+		operation_table.cpp \
+		rsa_key.cpp \
+		rsa_key_factory.cpp \
+		rsa_operation.cpp \
+		symmetric_key.cpp
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/include
+LOCAL_SHARED_LIBRARIES := libcrypto libkeymaster_messages
+LOCAL_CFLAGS = -Wall -Werror -Wunused
+LOCAL_CLANG := true
+LOCAL_CLANG_CFLAGS += -Wno-error=unused-const-variable -Wno-error=unused-private-field
+# TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
+# Currently, if enabled, these flags will cause an internal error in Clang.
+LOCAL_CLANG_CFLAGS += -fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
+# Ignore benigh warnings for now.
+LOCAL_CLANG_CFLAGS += -Wno-error=unused-private-field
+LOCAL_MODULE_TAGS := optional
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_SHARED_LIBRARY)
+
+
+###
+# libsoftkeymaster provides a software-based keymaster HAL implementation.
+# This is used by keystore as a fallback for when the hardware keymaster does
+# not support the request.
+###
+include $(CLEAR_VARS)
+LOCAL_MODULE := libsoftkeymasterdevice
+LOCAL_SRC_FILES := \
+	ec_keymaster0_key.cpp \
+	ec_keymaster1_key.cpp \
+	ecdsa_keymaster1_operation.cpp \
+	keymaster0_engine.cpp \
+	keymaster1_engine.cpp \
+	rsa_keymaster0_key.cpp \
+	rsa_keymaster1_key.cpp \
+	rsa_keymaster1_operation.cpp \
+	soft_keymaster_context.cpp \
+	soft_keymaster_device.cpp \
+	soft_keymaster_logger.cpp
+LOCAL_C_INCLUDES := \
+	system/security/keystore \
+	$(LOCAL_PATH)/include
+LOCAL_CFLAGS = -Wall -Werror -Wunused
+LOCAL_CLANG := true
+LOCAL_CLANG_CFLAGS += -Wno-error=unused-const-variable -Wno-error=unused-private-field
+# TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
+# Currently, if enabled, these flags will cause an internal error in Clang.
+LOCAL_CLANG_CFLAGS += -fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
+LOCAL_SHARED_LIBRARIES := libkeymaster_messages libkeymaster1 liblog libcrypto
+LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+include $(BUILD_SHARED_LIBRARY)
+
+###
+# libkeymasterfiles is an empty library that exports all of the files in keymaster as includes.
+###
+include $(CLEAR_VARS)
+LOCAL_MODULE := libkeymasterfiles
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+	$(LOCAL_PATH) \
+	$(LOCAL_PATH)/include
+LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+# Unit tests for libkeymaster
+include $(CLEAR_VARS)
+LOCAL_MODULE := keymaster_tests
+LOCAL_SRC_FILES := \
+	android_keymaster_messages_test.cpp \
+	android_keymaster_test.cpp \
+	android_keymaster_test_utils.cpp \
+	attestation_record_test.cpp \
+	authorization_set_test.cpp \
+	hkdf_test.cpp \
+	hmac_test.cpp \
+	kdf1_test.cpp \
+	kdf2_test.cpp \
+	kdf_test.cpp \
+	key_blob_test.cpp \
+	keymaster_enforcement_test.cpp
+
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/include
+LOCAL_CFLAGS = -Wall -Werror -Wunused -DKEYMASTER_NAME_TAGS
+LOCAL_CLANG := true
+LOCAL_CLANG_CFLAGS += -Wno-error=unused-const-variable -Wno-error=unused-private-field
+# TODO(krasin): reenable coverage flags, when the new Clang toolchain is released.
+# Currently, if enabled, these flags will cause an internal error in Clang.
+LOCAL_CLANG_CFLAGS += -fno-sanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp
+LOCAL_MODULE_TAGS := tests
+LOCAL_SHARED_LIBRARIES := \
+	libsoftkeymasterdevice \
+	libkeymaster_messages \
+	libkeymaster1 \
+	libcrypto \
+	libsoftkeymaster
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_NATIVE_TEST)
diff --git a/keymaster/List.h b/keymaster/List.h
new file mode 100644
index 0000000..403cd7f
--- /dev/null
+++ b/keymaster/List.h
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+//
+// Templated list class.  Normally we'd use STL, but we don't have that.
+// This class mimics STL's interfaces.
+//
+// Objects are copied into the list with the '=' operator or with copy-
+// construction, so if the compiler's auto-generated versions won't work for
+// you, define your own.
+//
+// The only class you want to use from here is "List".
+//
+#ifndef _LIBS_UTILS_LIST_H
+#define _LIBS_UTILS_LIST_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace android {
+
+/*
+ * Doubly-linked list.  Instantiate with "List<MyClass> myList".
+ *
+ * Objects added to the list are copied using the assignment operator,
+ * so this must be defined.
+ */
+template<typename T> 
+class List 
+{
+protected:
+    /*
+     * One element in the list.
+     */
+    class _Node {
+    public:
+        explicit _Node(const T& val) : mVal(val) {}
+        ~_Node() {}
+        inline T& getRef() { return mVal; }
+        inline const T& getRef() const { return mVal; }
+        inline _Node* getPrev() const { return mpPrev; }
+        inline _Node* getNext() const { return mpNext; }
+        inline void setVal(const T& val) { mVal = val; }
+        inline void setPrev(_Node* ptr) { mpPrev = ptr; }
+        inline void setNext(_Node* ptr) { mpNext = ptr; }
+    private:
+        friend class List;
+        friend class _ListIterator;
+        T           mVal;
+        _Node*      mpPrev;
+        _Node*      mpNext;
+    };
+
+    /*
+     * Iterator for walking through the list.
+     */
+    
+    template <typename TYPE>
+    struct CONST_ITERATOR {
+        typedef _Node const * NodePtr;
+        typedef const TYPE Type;
+    };
+    
+    template <typename TYPE>
+    struct NON_CONST_ITERATOR {
+        typedef _Node* NodePtr;
+        typedef TYPE Type;
+    };
+    
+    template<
+        typename U,
+        template <class> class Constness
+    > 
+    class _ListIterator {
+        typedef _ListIterator<U, Constness>     _Iter;
+        typedef typename Constness<U>::NodePtr  _NodePtr;
+        typedef typename Constness<U>::Type     _Type;
+
+        explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}
+
+    public:
+        _ListIterator() {}
+        _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}
+        ~_ListIterator() {}
+        
+        // this will handle conversions from iterator to const_iterator
+        // (and also all convertible iterators)
+        // Here, in this implementation, the iterators can be converted
+        // if the nodes can be converted
+        template<typename V> explicit 
+        _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}
+        
+
+        /*
+         * Dereference operator.  Used to get at the juicy insides.
+         */
+        _Type& operator*() const { return mpNode->getRef(); }
+        _Type* operator->() const { return &(mpNode->getRef()); }
+
+        /*
+         * Iterator comparison.
+         */
+        inline bool operator==(const _Iter& right) const { 
+            return mpNode == right.mpNode; }
+        
+        inline bool operator!=(const _Iter& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * handle comparisons between iterator and const_iterator
+         */
+        template<typename OTHER>
+        inline bool operator==(const OTHER& right) const { 
+            return mpNode == right.mpNode; }
+        
+        template<typename OTHER>
+        inline bool operator!=(const OTHER& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * Incr/decr, used to move through the list.
+         */
+        inline _Iter& operator++() {     // pre-increment
+            mpNode = mpNode->getNext();
+            return *this;
+        }
+        const _Iter operator++(int) {    // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getNext();
+            return tmp;
+        }
+        inline _Iter& operator--() {     // pre-increment
+            mpNode = mpNode->getPrev();
+            return *this;
+        }
+        const _Iter operator--(int) {   // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getPrev();
+            return tmp;
+        }
+
+        inline _NodePtr getNode() const { return mpNode; }
+
+        _NodePtr mpNode;    /* should be private, but older gcc fails */
+    private:
+        friend class List;
+    };
+
+public:
+    List() {
+        prep();
+    }
+    List(const List<T>& src) {      // copy-constructor
+        prep();
+        insert(begin(), src.begin(), src.end());
+    }
+    virtual ~List() {
+        clear();
+        delete[] (unsigned char*) mpMiddle;
+    }
+
+    typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;
+    typedef _ListIterator<T, CONST_ITERATOR> const_iterator;
+
+    List<T>& operator=(const List<T>& right);
+
+    /* returns true if the list is empty */
+    inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }
+
+    /* return #of elements in list */
+    size_t size() const {
+        return size_t(distance(begin(), end()));
+    }
+
+    /*
+     * Return the first element or one past the last element.  The
+     * _Node* we're returning is converted to an "iterator" by a
+     * constructor in _ListIterator.
+     */
+    inline iterator begin() { 
+        return iterator(mpMiddle->getNext()); 
+    }
+    inline const_iterator begin() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); 
+    }
+    inline iterator end() { 
+        return iterator(mpMiddle); 
+    }
+    inline const_iterator end() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle)); 
+    }
+
+    /* add the object to the head or tail of the list */
+    void push_front(const T& val) { insert(begin(), val); }
+    void push_back(const T& val) { insert(end(), val); }
+
+    /* insert before the current node; returns iterator at new node */
+    iterator insert(iterator posn, const T& val) 
+    {
+        _Node* newNode = new _Node(val);        // alloc & copy-construct
+        newNode->setNext(posn.getNode());
+        newNode->setPrev(posn.getNode()->getPrev());
+        posn.getNode()->getPrev()->setNext(newNode);
+        posn.getNode()->setPrev(newNode);
+        return iterator(newNode);
+    }
+
+    /* insert a range of elements before the current node */
+    void insert(iterator posn, const_iterator first, const_iterator last) {
+        for ( ; first != last; ++first)
+            insert(posn, *first);
+    }
+
+    /* remove one entry; returns iterator at next node */
+    iterator erase(iterator posn) {
+        _Node* pNext = posn.getNode()->getNext();
+        _Node* pPrev = posn.getNode()->getPrev();
+        pPrev->setNext(pNext);
+        pNext->setPrev(pPrev);
+        delete posn.getNode();
+        return iterator(pNext);
+    }
+
+    /* remove a range of elements */
+    iterator erase(iterator first, iterator last) {
+        while (first != last)
+            erase(first++);     // don't erase than incr later!
+        return iterator(last);
+    }
+
+    /* remove all contents of the list */
+    void clear() {
+        _Node* pCurrent = mpMiddle->getNext();
+        _Node* pNext;
+
+        while (pCurrent != mpMiddle) {
+            pNext = pCurrent->getNext();
+            delete pCurrent;
+            pCurrent = pNext;
+        }
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * Measure the distance between two iterators.  On exist, "first"
+     * will be equal to "last".  The iterators must refer to the same
+     * list.
+     *
+     * FIXME: This is actually a generic iterator function. It should be a 
+     * template function at the top-level with specializations for things like
+     * vector<>, which can just do pointer math). Here we limit it to
+     * _ListIterator of the same type but different constness.
+     */
+    template<
+        typename U,
+        template <class> class CL,
+        template <class> class CR
+    > 
+    ptrdiff_t distance(
+            _ListIterator<U, CL> first, _ListIterator<U, CR> last) const 
+    {
+        ptrdiff_t count = 0;
+        while (first != last) {
+            ++first;
+            ++count;
+        }
+        return count;
+    }
+
+private:
+    /*
+     * I want a _Node but don't need it to hold valid data.  More
+     * to the point, I don't want T's constructor to fire, since it
+     * might have side-effects or require arguments.  So, we do this
+     * slightly uncouth storage alloc.
+     */
+    void prep() {
+        mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
+        mpMiddle->setPrev(mpMiddle);
+        mpMiddle->setNext(mpMiddle);
+    }
+
+    /*
+     * This node plays the role of "pointer to head" and "pointer to tail".
+     * It sits in the middle of a circular list of nodes.  The iterator
+     * runs around the circle until it encounters this one.
+     */
+    _Node*      mpMiddle;
+};
+
+/*
+ * Assignment operator.
+ *
+ * The simplest way to do this would be to clear out the target list and
+ * fill it with the source.  However, we can speed things along by
+ * re-using existing elements.
+ */
+template<class T>
+List<T>& List<T>::operator=(const List<T>& right)
+{
+    if (this == &right)
+        return *this;       // self-assignment
+    iterator firstDst = begin();
+    iterator lastDst = end();
+    const_iterator firstSrc = right.begin();
+    const_iterator lastSrc = right.end();
+    while (firstSrc != lastSrc && firstDst != lastDst)
+        *firstDst++ = *firstSrc++;
+    if (firstSrc == lastSrc)        // ran out of elements in source?
+        erase(firstDst, lastDst);   // yes, erase any extras
+    else
+        insert(lastDst, firstSrc, lastSrc);     // copy remaining over
+    return *this;
+}
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_LIST_H
diff --git a/keymaster/MODULE_LICENSE_APACHE2 b/keymaster/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/keymaster/MODULE_LICENSE_APACHE2
diff --git a/keymaster/Makefile b/keymaster/Makefile
new file mode 100644
index 0000000..fc8a540
--- /dev/null
+++ b/keymaster/Makefile
@@ -0,0 +1,381 @@
+#####
+# Local unit test Makefile
+#
+# This makefile builds and runs the keymaster unit tests locally on the development
+# machine, not on an Android device.  Android.mk builds the same tests into the
+# "keymaster_tests" binary for execution on-device, but this Makefile runs them locally,
+# for a very fast edit/build/test development cycle.
+#
+# To build and run these tests, one pre-requisite must be manually installed: BoringSSL.
+# This Makefile expects to find BoringSSL in a directory adjacent to $ANDROID_BUILD_TOP.
+# To get and build it, first install the Ninja build tool (e.g. apt-get install
+# ninja-build), then do:
+#
+# cd $ANDROID_BUILD_TOP/..
+# git clone https://boringssl.googlesource.com/boringssl
+# cd boringssl
+# mdkir build
+# cd build
+# cmake -GNinja ..
+# ninja
+#
+# Then return to $ANDROID_BUILD_TOP/system/keymaster and run "make".
+#####
+
+BASE=../..
+SUBS=system/core \
+	hardware/libhardware \
+	external/gtest \
+	system/security/softkeymaster \
+	system/security/keystore
+GTEST=$(BASE)/external/gtest
+
+INCLUDES=$(foreach dir,$(SUBS),-I $(BASE)/$(dir)/include) \
+	-I $(BASE)/libnativehelper/include/nativehelper \
+	-I $(GTEST) -Iinclude -I$(BASE)/../boringssl/include
+
+ifdef FORCE_32_BIT
+ARCH_FLAGS = -m32
+endif
+
+ifdef USE_CLANG
+CC=/usr/bin/clang
+CXX=/usr/bin/clang
+CXXFLAGS +=-std=c++11 -DKEYMASTER_CLANG_TEST_BUILD
+CFLAGS += -DKEYMASTER_CLANG_TEST_BUILD
+else
+CXXFLAGS +=-std=c++0x -fprofile-arcs -ftest-coverage
+CFLAGS += -fprofile-arcs -ftest-coverage
+endif
+
+LDFLAGS += $(ARCH_FLAGS)
+CPPFLAGS = $(INCLUDES) -g -O0 -MD -MP
+CXXFLAGS += -Wall -Werror -Wno-unused -Winit-self -Wpointer-arith -Wunused-parameter \
+	-Werror=sign-compare -Werror=return-type -fno-permissive \
+	-Wno-deprecated-declarations -fno-exceptions -DKEYMASTER_NAME_TAGS $(ARCH_FLAGS)
+CFLAGS += $(ARCH_FLAGS)
+
+# Uncomment to enable debug logging.
+# CXXFLAGS += -DDEBUG
+
+LDLIBS=-L$(BASE)/../boringssl/build/crypto -lcrypto -lpthread -lstdc++ -lgcov
+
+CPPSRCS=\
+	aes_key.cpp \
+	aes_operation.cpp \
+	android_keymaster.cpp \
+	android_keymaster_messages.cpp \
+	android_keymaster_messages_test.cpp \
+	android_keymaster_test.cpp \
+	android_keymaster_test_utils.cpp \
+	android_keymaster_utils.cpp \
+	asymmetric_key.cpp \
+	asymmetric_key_factory.cpp \
+	attestation_record.cpp \
+	attestation_record_test.cpp \
+	auth_encrypted_key_blob.cpp \
+	authorization_set.cpp \
+	authorization_set_test.cpp \
+	ec_key.cpp \
+	ec_key_factory.cpp \
+	ec_keymaster0_key.cpp \
+	ec_keymaster1_key.cpp \
+	ecdsa_keymaster1_operation.cpp \
+	ecdsa_operation.cpp \
+	ecies_kem.cpp \
+	ecies_kem_test.cpp \
+	gtest_main.cpp \
+	hkdf.cpp \
+	hkdf_test.cpp \
+	hmac.cpp \
+	hmac_key.cpp \
+	hmac_operation.cpp \
+	hmac_test.cpp \
+	integrity_assured_key_blob.cpp \
+	iso18033kdf.cpp \
+	kdf.cpp \
+	kdf_test.cpp \
+	kdf1_test.cpp \
+	kdf2_test.cpp \
+	key.cpp \
+	key_blob_test.cpp \
+	keymaster0_engine.cpp \
+	keymaster1_engine.cpp \
+	keymaster_enforcement.cpp \
+	keymaster_enforcement_test.cpp \
+	keymaster_tags.cpp \
+	logger.cpp \
+	nist_curve_key_exchange.cpp \
+	nist_curve_key_exchange_test.cpp \
+	ocb_utils.cpp \
+	openssl_err.cpp \
+	openssl_utils.cpp \
+	operation.cpp \
+	operation_table.cpp \
+	rsa_key.cpp \
+	rsa_key_factory.cpp \
+	rsa_keymaster0_key.cpp \
+	rsa_keymaster1_key.cpp \
+	rsa_keymaster1_operation.cpp \
+	rsa_operation.cpp \
+	serializable.cpp \
+	soft_keymaster_context.cpp \
+	soft_keymaster_device.cpp \
+	symmetric_key.cpp
+
+CCSRCS=$(GTEST)/src/gtest-all.cc
+CSRCS=ocb.c
+
+OBJS=$(CPPSRCS:.cpp=.o) $(CCSRCS:.cc=.o) $(CSRCS:.c=.o)
+DEPS=$(CPPSRCS:.cpp=.d) $(CCSRCS:.cc=.d) $(CSRCS:.c=.d)
+
+BINARIES = \
+	android_keymaster_messages_test \
+	android_keymaster_test \
+	attestation_record_test \
+	authorization_set_test \
+	ecies_kem_test \
+	hkdf_test \
+	hmac_test \
+	kdf_test \
+	kdf1_test \
+	kdf2_test \
+	key_blob_test \
+	keymaster_enforcement_test \
+	nist_curve_key_exchange_test
+
+.PHONY: coverage memcheck massif clean run
+
+%.run: %
+	./$<
+	touch $@
+
+run: $(BINARIES:=.run)
+
+coverage: coverage.info
+	genhtml coverage.info --output-directory coverage
+
+coverage.info: run
+	lcov --capture --directory=. --output-file coverage.info
+
+%.coverage : %
+	$(MAKE) clean && $(MAKE) $<
+	./$<
+	lcov --capture --directory=. --output-file coverage.info
+	genhtml coverage.info --output-directory coverage
+
+#UNINIT_OPTS=--track-origins=yes
+UNINIT_OPTS=--undef-value-errors=no
+
+MEMCHECK_OPTS=--leak-check=full \
+	--show-reachable=yes \
+	--vgdb=full \
+	$(UNINIT_OPTS) \
+	--error-exitcode=1 \
+	--suppressions=valgrind.supp \
+	--gen-suppressions=all
+
+MASSIF_OPTS=--tool=massif \
+	--stacks=yes
+
+%.memcheck : %
+	valgrind $(MEMCHECK_OPTS) ./$< && \
+	touch $@
+
+%.massif : %
+	valgrind $(MASSIF_OPTS) --massif-out-file=$@ ./$<
+
+memcheck: $(BINARIES:=.memcheck)
+
+massif: $(BINARIES:=.massif)
+
+GTEST_OBJS = $(GTEST)/src/gtest-all.o gtest_main.o
+
+hmac_test: hmac_test.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	authorization_set.o \
+	hmac.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+hkdf_test: hkdf_test.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	authorization_set.o \
+	hkdf.o \
+	hmac.o \
+	kdf.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+kdf_test: kdf_test.o \
+	android_keymaster_utils.o \
+	kdf.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+kdf1_test: kdf1_test.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	authorization_set.o \
+	iso18033kdf.o \
+	kdf.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+kdf2_test: kdf2_test.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	authorization_set.o \
+	iso18033kdf.o \
+	kdf.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+nist_curve_key_exchange_test: nist_curve_key_exchange_test.o \
+	android_keymaster_test_utils.o \
+	authorization_set.o \
+	keymaster_tags.o \
+	logger.o \
+	nist_curve_key_exchange.o \
+	openssl_err.o \
+	openssl_utils.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+ecies_kem_test: ecies_kem_test.o \
+	android_keymaster_utils.o \
+	android_keymaster_test_utils.o \
+	authorization_set.o \
+	ecies_kem.o \
+	hkdf.o \
+	hmac.o \
+	kdf.o \
+	keymaster_tags.o \
+	logger.o \
+	nist_curve_key_exchange.o \
+	openssl_err.o \
+	openssl_utils.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+authorization_set_test: authorization_set_test.o \
+	android_keymaster_test_utils.o \
+	authorization_set.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+key_blob_test: key_blob_test.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	auth_encrypted_key_blob.o \
+	authorization_set.o \
+	integrity_assured_key_blob.o \
+	keymaster_tags.o \
+	logger.o \
+	ocb.o \
+	ocb_utils.o \
+	openssl_err.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+android_keymaster_messages_test: android_keymaster_messages_test.o \
+	android_keymaster_messages.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	authorization_set.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+android_keymaster_test: android_keymaster_test.o \
+	aes_key.o \
+	aes_operation.o \
+	android_keymaster.o \
+	android_keymaster_messages.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	asymmetric_key.o \
+	asymmetric_key_factory.o \
+	attestation_record.o \
+	auth_encrypted_key_blob.o \
+	authorization_set.o \
+	ec_key.o \
+	ec_key_factory.o \
+	ec_keymaster0_key.o \
+	ec_keymaster1_key.o \
+	ecdsa_keymaster1_operation.o \
+	ecdsa_operation.o \
+	hmac_key.o \
+	hmac_operation.o \
+	integrity_assured_key_blob.o \
+	key.o \
+	keymaster0_engine.o \
+	keymaster1_engine.o \
+	keymaster_enforcement.o \
+	keymaster_tags.o \
+	logger.o \
+	ocb.o \
+	ocb_utils.o \
+	openssl_err.o \
+	openssl_utils.o \
+	operation.o \
+	operation_table.o \
+	rsa_key.o \
+	rsa_key_factory.o \
+	rsa_keymaster0_key.o \
+	rsa_keymaster1_key.o \
+	rsa_keymaster1_operation.o \
+	rsa_operation.o \
+	serializable.o \
+	soft_keymaster_context.o \
+	soft_keymaster_device.o \
+	symmetric_key.o \
+	$(BASE)/system/security/softkeymaster/keymaster_openssl.o \
+	$(BASE)/system/security/keystore/keyblob_utils.o \
+	$(GTEST_OBJS)
+
+keymaster_enforcement_test: keymaster_enforcement_test.o \
+	android_keymaster_messages.o \
+	android_keymaster_test_utils.o \
+	android_keymaster_utils.o \
+	authorization_set.o \
+	keymaster_enforcement.o \
+	keymaster_tags.o \
+	logger.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+attestation_record_test: attestation_record_test.o \
+	android_keymaster_test_utils.o \
+	attestation_record.o \
+	authorization_set.o \
+	keymaster_tags.o \
+	logger.o \
+	openssl_err.o \
+	serializable.o \
+	$(GTEST_OBJS)
+
+$(GTEST)/src/gtest-all.o: CXXFLAGS:=$(subst -Wmissing-declarations,,$(CXXFLAGS))
+
+clean:
+	rm -f $(OBJS) $(DEPS) $(BINARIES) \
+		$(BINARIES:=.run) $(BINARIES:=.memcheck) $(BINARIES:=.massif) \
+		*gcov *gcno *gcda coverage.info
+	rm -rf coverage
+
+-include $(CPPSRCS:.cpp=.d)
+-include $(CCSRCS:.cc=.d)
diff --git a/keymaster/NOTICE b/keymaster/NOTICE
new file mode 100644
index 0000000..34bdaf1
--- /dev/null
+++ b/keymaster/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/keymaster/ae.h b/keymaster/ae.h
new file mode 100644
index 0000000..864d349
--- /dev/null
+++ b/keymaster/ae.h
@@ -0,0 +1,164 @@
+/* ---------------------------------------------------------------------------
+ *
+ * AEAD API 0.12 - 23-MAY-2012
+ *
+ * This file gives an interface appropriate for many authenticated
+ * encryption with associated data (AEAD) implementations. It does not try
+ * to accommodate all possible options or limitations that an implementation
+ * might have -- you should consult the documentation of your chosen
+ * implementation to find things like RFC 5116 constants, alignment
+ * requirements, whether the incremental interface is supported, etc.
+ *
+ * This file is in the public domain. It is provided "as is", without
+ * warranty of any kind. Use at your own risk.
+ *
+ * Comments are welcome: Ted Krovetz <ted@krovetz>.
+ *
+ * ------------------------------------------------------------------------ */
+
+#ifndef _AE_H_
+#define _AE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --------------------------------------------------------------------------
+ *
+ * Constants
+ *
+ * ----------------------------------------------------------------------- */
+
+/* Return status codes: Negative return values indicate an error occurred.
+ * For full explanations of error values, consult the implementation's
+ * documentation.                                                          */
+#define AE_SUCCESS (0)        /* Indicates successful completion of call  */
+#define AE_INVALID (-1)       /* Indicates bad tag during decryption      */
+#define AE_NOT_SUPPORTED (-2) /* Indicates unsupported option requested   */
+
+/* Flags: When data can be processed "incrementally", these flags are used
+ * to indicate whether the submitted data is the last or not.               */
+#define AE_FINALIZE (1) /* This is the last of data                  */
+#define AE_PENDING (0)  /* More data of is coming                    */
+
+/* --------------------------------------------------------------------------
+ *
+ * AEAD opaque structure definition
+ *
+ * ----------------------------------------------------------------------- */
+
+typedef struct _ae_ctx ae_ctx;
+
+/* --------------------------------------------------------------------------
+ *
+ * Data Structure Routines
+ *
+ * ----------------------------------------------------------------------- */
+
+ae_ctx* ae_allocate(void* misc); /* Allocate ae_ctx, set optional ptr   */
+void ae_free(ae_ctx* ctx);       /* Deallocate ae_ctx struct            */
+int ae_clear(ae_ctx* ctx);       /* Undo initialization                 */
+int ae_ctx_sizeof(void);         /* Return sizeof(ae_ctx)               */
+/* ae_allocate() allocates an ae_ctx structure, but does not initialize it.
+ * ae_free() deallocates an ae_ctx structure, but does not zero it.
+ * ae_clear() zeroes sensitive values associated with an ae_ctx structure
+ * and deallocates any auxiliary structures allocated during ae_init().
+ * ae_ctx_sizeof() returns sizeof(ae_ctx), to aid in any static allocations.
+ */
+
+/* --------------------------------------------------------------------------
+ *
+ * AEAD Routines
+ *
+ * ----------------------------------------------------------------------- */
+
+int ae_init(ae_ctx* ctx, const void* key, int key_len, int nonce_len, int tag_len);
+/* --------------------------------------------------------------------------
+ *
+ * Initialize an ae_ctx context structure.
+ *
+ * Parameters:
+ *  ctx       - Pointer to an ae_ctx structure to be initialized
+ *  key       - Pointer to user-supplied key
+ *  key_len   - Length of key supplied, in bytes
+ *  nonce_len - Length of nonces to be used for this key, in bytes
+ *  tag_len   - Length of tags to be produced for this key, in bytes
+ *
+ * Returns:
+ *  AE_SUCCESS       - Success. Ctx ready for use.
+ *  AE_NOT_SUPPORTED - An unsupported length was supplied. Ctx is untouched.
+ *  Otherwise        - Error. Check implementation documentation for codes.
+ *
+ * ----------------------------------------------------------------------- */
+
+int ae_encrypt(ae_ctx* ctx, const void* nonce, const void* pt, int pt_len, const void* ad,
+               int ad_len, void* ct, void* tag, int final);
+/* --------------------------------------------------------------------------
+ *
+ * Encrypt plaintext; provide for authentication of ciphertext/associated data.
+ *
+ * Parameters:
+ *  ctx    - Pointer to an ae_ctx structure initialized by ae_init.
+ *  nonce  - Pointer to a nonce_len (defined in ae_init) byte nonce.
+ *  pt     - Pointer to plaintext bytes to be encrypted.
+ *  pt_len - number of bytes pointed to by pt.
+ *  ad     - Pointer to associated data.
+ *  ad_len - number of bytes pointed to by ad.
+ *  ct     - Pointer to buffer to receive ciphertext encryption.
+ *  tag    - Pointer to receive authentication tag; or NULL
+ *           if tag is to be bundled into the ciphertext.
+ *  final  - Non-zero if this call completes the plaintext being encrypted.
+ *
+ * If nonce!=NULL then a message is being initiated. If final!=0
+ * then a message is being finalized. If final==0 or nonce==NULL
+ * then the incremental interface is being used. If nonce!=NULL and
+ * ad_len<0, then use same ad as last message.
+ *
+ * Returns:
+ *  non-negative     - Number of bytes written to ct.
+ *  AE_NOT_SUPPORTED - Usage mode unsupported (eg, incremental and/or sticky).
+ *  Otherwise        - Error. Check implementation documentation for codes.
+ *
+ * ----------------------------------------------------------------------- */
+
+int ae_decrypt(ae_ctx* ctx, const void* nonce, const void* ct, int ct_len, const void* ad,
+               int ad_len, void* pt, const void* tag, int final);
+/* --------------------------------------------------------------------------
+ *
+ * Decrypt ciphertext; provide authenticity of plaintext and associated data.
+ *
+ * Parameters:
+ *  ctx    - Pointer to an ae_ctx structure initialized by ae_init.
+ *  nonce  - Pointer to a nonce_len (defined in ae_init) byte nonce.
+ *  ct     - Pointer to ciphertext bytes to be decrypted.
+ *  ct_len - number of bytes pointed to by ct.
+ *  ad     - Pointer to associated data.
+ *  ad_len - number of bytes pointed to by ad.
+ *  pt     - Pointer to buffer to receive plaintext decryption.
+ *  tag    - Pointer to tag_len (defined in ae_init) bytes; or NULL
+ *           if tag is bundled into the ciphertext. Non-NULL tag is only
+ *           read when final is non-zero.
+ *  final  - Non-zero if this call completes the ciphertext being decrypted.
+ *
+ * If nonce!=NULL then "ct" points to the start of a ciphertext. If final!=0
+ * then "in" points to the final piece of ciphertext. If final==0 or nonce==
+ * NULL then the incremental interface is being used. If nonce!=NULL and
+ * ad_len<0, then use same ad as last message.
+ *
+ * Returns:
+ *  non-negative     - Number of bytes written to pt.
+ *  AE_INVALID       - Authentication failure.
+ *  AE_NOT_SUPPORTED - Usage mode unsupported (eg, incremental and/or sticky).
+ *  Otherwise        - Error. Check implementation documentation for codes.
+ *
+ * NOTE !!! NOTE !!! -- The ciphertext should be assumed possibly inauthentic
+ *                      until it has been completely written and it is
+ *                      verified that this routine did not return AE_INVALID.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+} /* closing brace for extern "C" */
+#endif
+
+#endif /* _AE_H_ */
diff --git a/keymaster/aes_key.cpp b/keymaster/aes_key.cpp
new file mode 100644
index 0000000..6b784b7
--- /dev/null
+++ b/keymaster/aes_key.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "aes_key.h"
+
+#include <assert.h>
+
+#include <new>
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include "aes_operation.h"
+
+namespace keymaster {
+
+AesEncryptionOperationFactory encrypt_factory;
+AesDecryptionOperationFactory decrypt_factory;
+
+OperationFactory* AesKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_ENCRYPT:
+        return &encrypt_factory;
+    case KM_PURPOSE_DECRYPT:
+        return &decrypt_factory;
+    default:
+        return nullptr;
+    }
+}
+
+keymaster_error_t AesKeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                         const AuthorizationSet& /* additional_params */,
+                                         const AuthorizationSet& hw_enforced,
+                                         const AuthorizationSet& sw_enforced,
+                                         UniquePtr<Key>* key) const {
+    if (!key)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    uint32_t min_mac_length = 0;
+    if (hw_enforced.Contains(TAG_BLOCK_MODE, KM_MODE_GCM) ||
+        sw_enforced.Contains(TAG_BLOCK_MODE, KM_MODE_GCM)) {
+
+        if (!hw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length) &&
+            !sw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length)) {
+
+            LOG_E("AES-GCM key must have KM_TAG_MIN_MAC_LENGTH", 0);
+            return KM_ERROR_INVALID_KEY_BLOB;
+        }
+    }
+
+    keymaster_error_t error = KM_ERROR_OK;
+    key->reset(new (std::nothrow) AesKey(key_material, hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return error;
+}
+
+keymaster_error_t AesKeyFactory::validate_algorithm_specific_new_key_params(
+    const AuthorizationSet& key_description) const {
+    if (key_description.Contains(TAG_BLOCK_MODE, KM_MODE_GCM)) {
+        uint32_t min_tag_length;
+        if (!key_description.GetTagValue(TAG_MIN_MAC_LENGTH, &min_tag_length))
+            return KM_ERROR_MISSING_MIN_MAC_LENGTH;
+
+        if (min_tag_length % 8 != 0)
+            return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH;
+
+        if (min_tag_length < kMinGcmTagLength || min_tag_length > kMaxGcmTagLength)
+            return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH;
+    } else {
+        // Not GCM
+        if (key_description.find(TAG_MIN_MAC_LENGTH) != -1) {
+            LOG_W("KM_TAG_MIN_MAC_LENGTH found for non AES-GCM key", 0);
+            return KM_ERROR_INVALID_TAG;
+        }
+    }
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/aes_key.h b/keymaster/aes_key.h
new file mode 100644
index 0000000..a4ab2f2
--- /dev/null
+++ b/keymaster/aes_key.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_AES_KEY_H_
+#define SYSTEM_KEYMASTER_AES_KEY_H_
+
+#include <openssl/aes.h>
+
+#include "symmetric_key.h"
+
+namespace keymaster {
+
+const size_t kMinGcmTagLength = 12 * 8;
+const size_t kMaxGcmTagLength = 16 * 8;
+
+class AesKeyFactory : public SymmetricKeyFactory {
+  public:
+    explicit AesKeyFactory(const KeymasterContext* context) : SymmetricKeyFactory(context) {}
+
+    keymaster_algorithm_t registry_key() const { return KM_ALGORITHM_AES; }
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+  private:
+    bool key_size_supported(size_t key_size_bits) const override {
+        return key_size_bits == 128 || key_size_bits == 192 || key_size_bits == 256;
+    }
+    keymaster_error_t validate_algorithm_specific_new_key_params(
+        const AuthorizationSet& key_description) const override;
+};
+
+class AesKey : public SymmetricKey {
+  public:
+    AesKey(const KeymasterKeyBlob& key_material, const AuthorizationSet& hw_enforced,
+           const AuthorizationSet& sw_enforced, keymaster_error_t* error)
+        : SymmetricKey(key_material, hw_enforced, sw_enforced, error) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_AES_KEY_H_
diff --git a/keymaster/aes_operation.cpp b/keymaster/aes_operation.cpp
new file mode 100644
index 0000000..4c5c88c
--- /dev/null
+++ b/keymaster/aes_operation.cpp
@@ -0,0 +1,651 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "aes_operation.h"
+
+#include <stdio.h>
+
+#include <new>
+
+#include <UniquePtr.h>
+
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include <keymaster/logger.h>
+
+#include "aes_key.h"
+#include "openssl_err.h"
+
+namespace keymaster {
+
+static const size_t GCM_NONCE_SIZE = 12;
+
+inline bool allows_padding(keymaster_block_mode_t block_mode) {
+    switch (block_mode) {
+    case KM_MODE_CTR:
+    case KM_MODE_GCM:
+        return false;
+    case KM_MODE_ECB:
+    case KM_MODE_CBC:
+        return true;
+    }
+    assert(false /* Can't get here */);
+    return false;
+}
+
+static keymaster_error_t GetAndValidateGcmTagLength(const AuthorizationSet& begin_params,
+                                                    const AuthorizationSet& key_params,
+                                                    size_t* tag_length) {
+    uint32_t tag_length_bits;
+    if (!begin_params.GetTagValue(TAG_MAC_LENGTH, &tag_length_bits)) {
+        return KM_ERROR_MISSING_MAC_LENGTH;
+    }
+
+    uint32_t min_tag_length_bits;
+    if (!key_params.GetTagValue(TAG_MIN_MAC_LENGTH, &min_tag_length_bits)) {
+        LOG_E("AES GCM key must have KM_TAG_MIN_MAC_LENGTH", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    if (tag_length_bits % 8 != 0 || tag_length_bits > kMaxGcmTagLength ||
+        tag_length_bits < kMinGcmTagLength) {
+        return KM_ERROR_UNSUPPORTED_MAC_LENGTH;
+    }
+
+    if (tag_length_bits < min_tag_length_bits) {
+        return KM_ERROR_INVALID_MAC_LENGTH;
+    }
+
+    *tag_length = tag_length_bits / 8;
+    return KM_ERROR_OK;
+}
+
+Operation* AesOperationFactory::CreateOperation(const Key& key,
+                                                const AuthorizationSet& begin_params,
+                                                keymaster_error_t* error) {
+    *error = KM_ERROR_OK;
+    const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
+
+    switch (symmetric_key->key_data_size()) {
+    case 16:
+    case 24:
+    case 32:
+        break;
+    default:
+        *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
+        return nullptr;
+    }
+
+    keymaster_block_mode_t block_mode;
+    if (!begin_params.GetTagValue(TAG_BLOCK_MODE, &block_mode)) {
+        LOG_E("%d block modes specified in begin params", begin_params.GetTagCount(TAG_BLOCK_MODE));
+        *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
+        return nullptr;
+    } else if (!supported(block_mode)) {
+        LOG_E("Block mode %d not supported", block_mode);
+        *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
+        return nullptr;
+    } else if (!key.authorizations().Contains(TAG_BLOCK_MODE, block_mode)) {
+        LOG_E("Block mode %d was specified, but not authorized by key", block_mode);
+        *error = KM_ERROR_INCOMPATIBLE_BLOCK_MODE;
+        return nullptr;
+    }
+
+    size_t tag_length = 0;
+    if (block_mode == KM_MODE_GCM) {
+        *error = GetAndValidateGcmTagLength(begin_params, key.authorizations(), &tag_length);
+        if (*error != KM_ERROR_OK) {
+            return nullptr;
+        }
+    }
+
+    keymaster_padding_t padding;
+    if (!GetAndValidatePadding(begin_params, key, &padding, error)) {
+        return nullptr;
+    }
+    if (!allows_padding(block_mode) && padding != KM_PAD_NONE) {
+        LOG_E("Mode does not support padding", 0);
+        *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
+        return nullptr;
+    }
+
+    bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
+
+    Operation* op = nullptr;
+    switch (purpose()) {
+    case KM_PURPOSE_ENCRYPT:
+        op = new (std::nothrow)
+            AesEvpEncryptOperation(block_mode, padding, caller_nonce, tag_length,
+                                   symmetric_key->key_data(), symmetric_key->key_data_size());
+        break;
+    case KM_PURPOSE_DECRYPT:
+        op = new (std::nothrow)
+            AesEvpDecryptOperation(block_mode, padding, tag_length, symmetric_key->key_data(),
+                                   symmetric_key->key_data_size());
+        break;
+    default:
+        *error = KM_ERROR_UNSUPPORTED_PURPOSE;
+        return nullptr;
+    }
+
+    if (!op)
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return op;
+}
+
+static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
+                                                               KM_MODE_CTR, KM_MODE_GCM};
+
+const keymaster_block_mode_t*
+AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
+    *block_mode_count = array_length(supported_block_modes);
+    return supported_block_modes;
+}
+
+static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
+const keymaster_padding_t*
+AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    *padding_mode_count = array_length(supported_padding_modes);
+    return supported_padding_modes;
+}
+
+AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
+                                 keymaster_padding_t padding, bool caller_iv, size_t tag_length,
+                                 const uint8_t* key, size_t key_size)
+    : Operation(purpose), block_mode_(block_mode), caller_iv_(caller_iv), tag_length_(tag_length),
+      data_started_(false), key_size_(key_size), padding_(padding) {
+    memcpy(key_, key, key_size_);
+    EVP_CIPHER_CTX_init(&ctx_);
+}
+
+AesEvpOperation::~AesEvpOperation() {
+    EVP_CIPHER_CTX_cleanup(&ctx_);
+    memset_s(aad_block_buf_.get(), AES_BLOCK_SIZE, 0);
+}
+
+keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& /* input_params */,
+                                         AuthorizationSet* /* output_params */) {
+    if (block_mode_ == KM_MODE_GCM) {
+        aad_block_buf_length_ = 0;
+        aad_block_buf_.reset(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]);
+        if (!aad_block_buf_.get())
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+
+    return InitializeCipher();
+}
+
+keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& additional_params,
+                                          const Buffer& input,
+                                          AuthorizationSet* /* output_params */, Buffer* output,
+                                          size_t* input_consumed) {
+    keymaster_error_t error;
+    if (block_mode_ == KM_MODE_GCM)
+        if (!HandleAad(additional_params, input, &error))
+            return error;
+
+    if (!InternalUpdate(input.peek_read(), input.available_read(), output, &error))
+        return error;
+    *input_consumed = input.available_read();
+
+    return KM_ERROR_OK;
+}
+
+inline bool is_bad_decrypt(unsigned long error) {
+    return (ERR_GET_LIB(error) == ERR_LIB_CIPHER &&  //
+            ERR_GET_REASON(error) == CIPHER_R_BAD_DECRYPT);
+}
+
+keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& additional_params,
+                                          const Buffer& input, const Buffer& /* signature */,
+                                          AuthorizationSet* output_params, Buffer* output) {
+    keymaster_error_t error;
+    if (!UpdateForFinish(additional_params, input, output_params, output, &error))
+        return error;
+
+    if (!output->reserve(AES_BLOCK_SIZE))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (block_mode_ == KM_MODE_GCM && aad_block_buf_length_ > 0 && !ProcessBufferedAadBlock(&error))
+        return error;
+
+    int output_written = -1;
+    if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
+        if (tag_length_ > 0)
+            return KM_ERROR_VERIFICATION_FAILED;
+        LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
+        return TranslateLastOpenSslError();
+    }
+
+    assert(output_written <= AES_BLOCK_SIZE);
+    if (!output->advance_write(output_written))
+        return KM_ERROR_UNKNOWN_ERROR;
+    return KM_ERROR_OK;
+}
+
+bool AesEvpOperation::need_iv() const {
+    switch (block_mode_) {
+    case KM_MODE_CBC:
+    case KM_MODE_CTR:
+    case KM_MODE_GCM:
+        return true;
+    case KM_MODE_ECB:
+        return false;
+    default:
+        // Shouldn't get here.
+        assert(false);
+        return false;
+    }
+}
+
+keymaster_error_t AesEvpOperation::InitializeCipher() {
+    const EVP_CIPHER* cipher;
+    switch (block_mode_) {
+    case KM_MODE_ECB:
+        switch (key_size_) {
+        case 16:
+            cipher = EVP_aes_128_ecb();
+            break;
+        case 24:
+            cipher = EVP_aes_192_ecb();
+            break;
+        case 32:
+            cipher = EVP_aes_256_ecb();
+            break;
+        default:
+            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+        }
+        break;
+    case KM_MODE_CBC:
+        switch (key_size_) {
+        case 16:
+            cipher = EVP_aes_128_cbc();
+            break;
+        case 24:
+            cipher = EVP_aes_192_cbc();
+            break;
+        case 32:
+            cipher = EVP_aes_256_cbc();
+            break;
+        default:
+            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+        }
+        break;
+    case KM_MODE_CTR:
+        switch (key_size_) {
+        case 16:
+            cipher = EVP_aes_128_ctr();
+            break;
+        case 24:
+            cipher = EVP_aes_192_ctr();
+            break;
+        case 32:
+            cipher = EVP_aes_256_ctr();
+            break;
+        default:
+            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+        }
+        break;
+    case KM_MODE_GCM:
+        switch (key_size_) {
+        case 16:
+            cipher = EVP_aes_128_gcm();
+            break;
+        case 24:
+            cipher = EVP_aes_192_gcm();
+            break;
+        case 32:
+            cipher = EVP_aes_256_gcm();
+            break;
+        default:
+            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+        }
+        break;
+    default:
+        return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
+    }
+
+    if (!EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode()))
+        return TranslateLastOpenSslError();
+
+    switch (padding_) {
+    case KM_PAD_NONE:
+        EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
+        break;
+    case KM_PAD_PKCS7:
+        // This is the default for OpenSSL EVP cipher operations.
+        break;
+    default:
+        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
+    }
+
+    if (block_mode_ == KM_MODE_GCM) {
+        aad_block_buf_length_ = 0;
+        aad_block_buf_.reset(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]);
+        if (!aad_block_buf_.get())
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
+    keymaster_blob_t iv_blob;
+    if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
+        LOG_E("No IV provided", 0);
+        return KM_ERROR_INVALID_ARGUMENT;
+    }
+    if (block_mode_ != KM_MODE_GCM && iv_blob.data_length != AES_BLOCK_SIZE) {
+        LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
+              iv_blob.data_length);
+        return KM_ERROR_INVALID_NONCE;
+    }
+    if (block_mode_ == KM_MODE_GCM && iv_blob.data_length != GCM_NONCE_SIZE) {
+        LOG_E("Expected %d-byte nonce for AES-GCM operation, but got %d bytes", GCM_NONCE_SIZE,
+              iv_blob.data_length);
+        return KM_ERROR_INVALID_NONCE;
+    }
+    iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
+    if (!iv_.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    iv_length_ = iv_blob.data_length;
+    return KM_ERROR_OK;
+}
+
+/*
+ * Process Incoming Associated Authentication Data.
+ *
+ * This method is more complex than might be expected, because the underlying library silently does
+ * the wrong thing when given partial AAD blocks, so we have to take care to process AAD in
+ * AES_BLOCK_SIZE increments, buffering (in aad_block_buf_) when given smaller amounts of data.
+ */
+bool AesEvpOperation::HandleAad(const AuthorizationSet& input_params, const Buffer& input,
+                                keymaster_error_t* error) {
+    assert(tag_length_ > 0);
+    assert(error);
+
+    keymaster_blob_t aad;
+    if (input_params.GetTagValue(TAG_ASSOCIATED_DATA, &aad)) {
+        if (data_started_) {
+            *error = KM_ERROR_INVALID_TAG;
+            return false;
+        }
+
+        if (aad_block_buf_length_ > 0) {
+            FillBufferedAadBlock(&aad);
+            if (aad_block_buf_length_ == AES_BLOCK_SIZE && !ProcessBufferedAadBlock(error))
+                return false;
+        }
+
+        size_t blocks_to_process = aad.data_length / AES_BLOCK_SIZE;
+        if (blocks_to_process && !ProcessAadBlocks(aad.data, blocks_to_process, error))
+            return false;
+        aad.data += blocks_to_process * AES_BLOCK_SIZE;
+        aad.data_length -= blocks_to_process * AES_BLOCK_SIZE;
+
+        FillBufferedAadBlock(&aad);
+        assert(aad.data_length == 0);
+    }
+
+    if (input.available_read()) {
+        data_started_ = true;
+        // Data has begun, no more AAD is allowed.  Process any buffered AAD.
+        if (aad_block_buf_length_ > 0 && !ProcessBufferedAadBlock(error))
+            return false;
+    }
+
+    return true;
+}
+
+bool AesEvpOperation::ProcessBufferedAadBlock(keymaster_error_t* error) {
+    int output_written;
+    if (EVP_CipherUpdate(&ctx_, nullptr /* out */, &output_written, aad_block_buf_.get(),
+                         aad_block_buf_length_)) {
+        aad_block_buf_length_ = 0;
+        return true;
+    }
+    *error = TranslateLastOpenSslError();
+    return false;
+}
+
+bool AesEvpOperation::ProcessAadBlocks(const uint8_t* data, size_t blocks,
+                                       keymaster_error_t* error) {
+    int output_written;
+    if (EVP_CipherUpdate(&ctx_, nullptr /* out */, &output_written, data, blocks * AES_BLOCK_SIZE))
+        return true;
+    *error = TranslateLastOpenSslError();
+    return false;
+}
+
+inline size_t min(size_t a, size_t b) {
+    return (a < b) ? a : b;
+}
+
+void AesEvpOperation::FillBufferedAadBlock(keymaster_blob_t* aad) {
+    size_t to_buffer = min(AES_BLOCK_SIZE - aad_block_buf_length_, aad->data_length);
+    memcpy(aad_block_buf_.get() + aad_block_buf_length_, aad->data, to_buffer);
+    aad->data += to_buffer;
+    aad->data_length -= to_buffer;
+    aad_block_buf_length_ += to_buffer;
+}
+
+bool AesEvpOperation::InternalUpdate(const uint8_t* input, size_t input_length, Buffer* output,
+                                     keymaster_error_t* error) {
+    assert(output);
+    assert(error);
+
+    if (!input_length)
+        return true;
+
+    if (!output->reserve(input_length + AES_BLOCK_SIZE)) {
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        return false;
+    }
+
+    int output_written = -1;
+    if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input, input_length)) {
+        *error = TranslateLastOpenSslError();
+        return false;
+    }
+    return output->advance_write(output_written);
+}
+
+bool AesEvpOperation::UpdateForFinish(const AuthorizationSet& additional_params,
+                                      const Buffer& input, AuthorizationSet* output_params,
+                                      Buffer* output, keymaster_error_t* error) {
+    if (input.available_read() || !additional_params.empty()) {
+        size_t input_consumed;
+        *error = Update(additional_params, input, output_params, output, &input_consumed);
+        if (*error != KM_ERROR_OK)
+            return false;
+        if (input_consumed != input.available_read()) {
+            *error = KM_ERROR_INVALID_INPUT_LENGTH;
+            return false;
+        }
+    }
+
+    return true;
+}
+
+keymaster_error_t AesEvpEncryptOperation::Begin(const AuthorizationSet& input_params,
+                                                AuthorizationSet* output_params) {
+    if (!output_params)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    if (need_iv()) {
+        keymaster_error_t error = KM_ERROR_OK;
+        if (input_params.find(TAG_NONCE) == -1)
+            error = GenerateIv();
+        else if (caller_iv_)
+            error = GetIv(input_params);
+        else
+            error = KM_ERROR_CALLER_NONCE_PROHIBITED;
+
+        if (error == KM_ERROR_OK)
+            output_params->push_back(TAG_NONCE, iv_.get(), iv_length_);
+        else
+            return error;
+    }
+
+    return AesEvpOperation::Begin(input_params, output_params);
+}
+
+keymaster_error_t AesEvpEncryptOperation::Finish(const AuthorizationSet& additional_params,
+                                                 const Buffer& input, const Buffer& signature,
+                                                 AuthorizationSet* output_params, Buffer* output) {
+    if (!output->reserve(input.available_read() + AES_BLOCK_SIZE + tag_length_))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    keymaster_error_t error =
+        AesEvpOperation::Finish(additional_params, input, signature, output_params, output);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (tag_length_ > 0) {
+        if (!output->reserve(tag_length_))
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+        if (!EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_GET_TAG, tag_length_, output->peek_write()))
+            return TranslateLastOpenSslError();
+        if (!output->advance_write(tag_length_))
+            return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t AesEvpEncryptOperation::GenerateIv() {
+    iv_length_ = (block_mode_ == KM_MODE_GCM) ? GCM_NONCE_SIZE : AES_BLOCK_SIZE;
+    iv_.reset(new (std::nothrow) uint8_t[iv_length_]);
+    if (!iv_.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    if (RAND_bytes(iv_.get(), iv_length_) != 1)
+        return TranslateLastOpenSslError();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t AesEvpDecryptOperation::Begin(const AuthorizationSet& input_params,
+                                                AuthorizationSet* output_params) {
+    if (need_iv()) {
+        keymaster_error_t error = GetIv(input_params);
+        if (error != KM_ERROR_OK)
+            return error;
+    }
+
+    if (tag_length_ > 0) {
+        tag_buf_length_ = 0;
+        tag_buf_.reset(new (std::nothrow) uint8_t[tag_length_]);
+        if (!tag_buf_.get())
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+
+    return AesEvpOperation::Begin(input_params, output_params);
+}
+
+keymaster_error_t AesEvpDecryptOperation::Update(const AuthorizationSet& additional_params,
+                                                 const Buffer& input,
+                                                 AuthorizationSet* /* output_params */,
+                                                 Buffer* output, size_t* input_consumed) {
+    if (!output || !input_consumed)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    // Barring error, we'll consume it all.
+    *input_consumed = input.available_read();
+
+    keymaster_error_t error;
+    if (block_mode_ == KM_MODE_GCM) {
+        if (!HandleAad(additional_params, input, &error))
+            return error;
+        return ProcessAllButTagLengthBytes(input, output);
+    }
+
+    if (!InternalUpdate(input.peek_read(), input.available_read(), output, &error))
+        return error;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t AesEvpDecryptOperation::ProcessAllButTagLengthBytes(const Buffer& input,
+                                                                      Buffer* output) {
+    if (input.available_read() <= tag_buf_unused()) {
+        BufferCandidateTagData(input.peek_read(), input.available_read());
+        return KM_ERROR_OK;
+    }
+
+    const size_t data_available = tag_buf_length_ + input.available_read();
+
+    const size_t to_process = data_available - tag_length_;
+    const size_t to_process_from_tag_buf = min(to_process, tag_buf_length_);
+    const size_t to_process_from_input = to_process - to_process_from_tag_buf;
+
+    if (!output->reserve(to_process + AES_BLOCK_SIZE))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    keymaster_error_t error;
+    if (!ProcessTagBufContentsAsData(to_process_from_tag_buf, output, &error))
+        return error;
+
+    if (!InternalUpdate(input.peek_read(), to_process_from_input, output, &error))
+        return error;
+
+    BufferCandidateTagData(input.peek_read() + to_process_from_input,
+                           input.available_read() - to_process_from_input);
+    assert(tag_buf_unused() == 0);
+
+    return KM_ERROR_OK;
+}
+
+bool AesEvpDecryptOperation::ProcessTagBufContentsAsData(size_t to_process, Buffer* output,
+                                                         keymaster_error_t* error) {
+    assert(to_process <= tag_buf_length_);
+    if (!InternalUpdate(tag_buf_.get(), to_process, output, error))
+        return false;
+    if (to_process < tag_buf_length_)
+        memmove(tag_buf_.get(), tag_buf_.get() + to_process, tag_buf_length_ - to_process);
+    tag_buf_length_ -= to_process;
+    return true;
+}
+
+void AesEvpDecryptOperation::BufferCandidateTagData(const uint8_t* data, size_t data_length) {
+    assert(data_length <= tag_length_ - tag_buf_length_);
+    memcpy(tag_buf_.get() + tag_buf_length_, data, data_length);
+    tag_buf_length_ += data_length;
+}
+
+keymaster_error_t AesEvpDecryptOperation::Finish(const AuthorizationSet& additional_params,
+                                                 const Buffer& input, const Buffer& signature,
+                                                 AuthorizationSet* output_params, Buffer* output) {
+    keymaster_error_t error;
+    if (!UpdateForFinish(additional_params, input, output_params, output, &error))
+        return error;
+
+    if (tag_buf_length_ < tag_length_)
+        return KM_ERROR_INVALID_INPUT_LENGTH;
+    else if (tag_length_ > 0 &&
+             !EVP_CIPHER_CTX_ctrl(&ctx_, EVP_CTRL_GCM_SET_TAG, tag_length_, tag_buf_.get()))
+        return TranslateLastOpenSslError();
+
+    AuthorizationSet empty_params;
+    Buffer empty_input;
+    return AesEvpOperation::Finish(empty_params, empty_input, signature, output_params, output);
+}
+
+keymaster_error_t AesEvpOperation::Abort() {
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/aes_operation.h b/keymaster/aes_operation.h
new file mode 100644
index 0000000..1a296bb
--- /dev/null
+++ b/keymaster/aes_operation.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_AES_OPERATION_H_
+#define SYSTEM_KEYMASTER_AES_OPERATION_H_
+
+#include <openssl/evp.h>
+
+#include "ocb_utils.h"
+#include "operation.h"
+
+namespace keymaster {
+
+/**
+ * Abstract base for AES operation factories.  This class does all of the work to create
+ * AES operations.
+ */
+class AesOperationFactory : public OperationFactory {
+  public:
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_AES, purpose()); }
+
+    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                               keymaster_error_t* error) override;
+    const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const override;
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const override;
+
+    virtual keymaster_purpose_t purpose() const = 0;
+};
+
+/**
+ * Concrete factory for AES encryption operations.
+ */
+class AesEncryptionOperationFactory : public AesOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_ENCRYPT; }
+};
+
+/**
+ * Concrete factory for AES decryption operations.
+ */
+class AesDecryptionOperationFactory : public AesOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_DECRYPT; }
+};
+
+static const size_t MAX_EVP_KEY_SIZE = 32;
+
+class AesEvpOperation : public Operation {
+  public:
+    AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
+                    keymaster_padding_t padding, bool caller_iv, size_t tag_length,
+                    const uint8_t* key, size_t key_size);
+    ~AesEvpOperation();
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+    keymaster_error_t Abort() override;
+
+    virtual int evp_encrypt_mode() = 0;
+
+  protected:
+    bool need_iv() const;
+    keymaster_error_t InitializeCipher();
+    keymaster_error_t GetIv(const AuthorizationSet& input_params);
+    bool HandleAad(const AuthorizationSet& input_params, const Buffer& input,
+                   keymaster_error_t* error);
+    bool ProcessAadBlocks(const uint8_t* data, size_t blocks, keymaster_error_t* error);
+    void FillBufferedAadBlock(keymaster_blob_t* aad);
+    bool ProcessBufferedAadBlock(keymaster_error_t* error);
+    bool InternalUpdate(const uint8_t* input, size_t input_length, Buffer* output,
+                        keymaster_error_t* error);
+    bool UpdateForFinish(const AuthorizationSet& additional_params, const Buffer& input,
+                         AuthorizationSet* output_params, Buffer* output, keymaster_error_t* error);
+
+    const keymaster_block_mode_t block_mode_;
+    EVP_CIPHER_CTX ctx_;
+    UniquePtr<uint8_t[]> iv_;
+    size_t iv_length_;
+    const bool caller_iv_;
+    size_t tag_length_;
+    UniquePtr<uint8_t[]> aad_block_buf_;
+    size_t aad_block_buf_length_;
+
+  private:
+    bool data_started_;
+    const size_t key_size_;
+    const keymaster_padding_t padding_;
+    uint8_t key_[MAX_EVP_KEY_SIZE];
+};
+
+class AesEvpEncryptOperation : public AesEvpOperation {
+  public:
+    AesEvpEncryptOperation(keymaster_block_mode_t block_mode, keymaster_padding_t padding,
+                           bool caller_iv, size_t tag_length, const uint8_t* key, size_t key_size)
+        : AesEvpOperation(KM_PURPOSE_ENCRYPT, block_mode, padding, caller_iv, tag_length, key,
+                          key_size) {}
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+
+    int evp_encrypt_mode() override { return 1; }
+
+  private:
+    keymaster_error_t GenerateIv();
+};
+
+class AesEvpDecryptOperation : public AesEvpOperation {
+  public:
+    AesEvpDecryptOperation(keymaster_block_mode_t block_mode, keymaster_padding_t padding,
+                           size_t tag_length, const uint8_t* key, size_t key_size)
+        : AesEvpOperation(KM_PURPOSE_DECRYPT, block_mode, padding,
+                          false /* caller_iv -- don't care */, tag_length, key, key_size) {}
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+
+    int evp_encrypt_mode() override { return 0; }
+
+  private:
+    size_t tag_buf_unused() { return tag_length_ - tag_buf_length_; }
+
+    keymaster_error_t ProcessAllButTagLengthBytes(const Buffer& input, Buffer* output);
+    bool ProcessTagBufContentsAsData(size_t to_process, Buffer* output, keymaster_error_t* error);
+    void BufferCandidateTagData(const uint8_t* data, size_t data_length);
+
+    UniquePtr<uint8_t[]> tag_buf_;
+    size_t tag_buf_length_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_AES_OPERATION_H_
diff --git a/keymaster/android_keymaster.cpp b/keymaster/android_keymaster.cpp
new file mode 100644
index 0000000..3a53394
--- /dev/null
+++ b/keymaster/android_keymaster.cpp
@@ -0,0 +1,440 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/android_keymaster.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <cstddef>
+
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+
+#include <UniquePtr.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/key_factory.h>
+#include <keymaster/keymaster_context.h>
+
+#include "ae.h"
+#include "key.h"
+#include "openssl_err.h"
+#include "operation.h"
+#include "operation_table.h"
+
+namespace keymaster {
+
+const uint8_t MAJOR_VER = 1;
+const uint8_t MINOR_VER = 1;
+const uint8_t SUBMINOR_VER = 0;
+
+AndroidKeymaster::AndroidKeymaster(KeymasterContext* context, size_t operation_table_size)
+    : context_(context), operation_table_(new OperationTable(operation_table_size)) {}
+
+AndroidKeymaster::~AndroidKeymaster() {}
+
+struct AE_CTX_Delete {
+    void operator()(ae_ctx* ctx) const { ae_free(ctx); }
+};
+typedef UniquePtr<ae_ctx, AE_CTX_Delete> Unique_ae_ctx;
+
+// TODO(swillden): Unify support analysis.  Right now, we have per-keytype methods that determine if
+// specific modes, padding, etc. are supported for that key type, and AndroidKeymaster also has
+// methods that return the same information.  They'll get out of sync.  Best to put the knowledge in
+// the keytypes and provide some mechanism for AndroidKeymaster to query the keytypes for the
+// information.
+
+template <typename T>
+bool check_supported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
+                     SupportedResponse<T>* response) {
+    if (context.GetKeyFactory(algorithm) == NULL) {
+        response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+        return false;
+    }
+    return true;
+}
+
+void AndroidKeymaster::GetVersion(const GetVersionRequest&, GetVersionResponse* rsp) {
+    if (rsp == NULL)
+        return;
+
+    rsp->major_ver = MAJOR_VER;
+    rsp->minor_ver = MINOR_VER;
+    rsp->subminor_ver = SUBMINOR_VER;
+    rsp->error = KM_ERROR_OK;
+}
+
+void AndroidKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& /* request */,
+                                           SupportedAlgorithmsResponse* response) {
+    if (response == NULL)
+        return;
+
+    response->error = KM_ERROR_OK;
+
+    size_t algorithm_count = 0;
+    const keymaster_algorithm_t* algorithms = context_->GetSupportedAlgorithms(&algorithm_count);
+    if (algorithm_count == 0)
+        return;
+    response->results_length = algorithm_count;
+    response->results = dup_array(algorithms, algorithm_count);
+    if (!response->results)
+        response->error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+}
+
+template <typename T>
+void GetSupported(const KeymasterContext& context, keymaster_algorithm_t algorithm,
+                  keymaster_purpose_t purpose,
+                  const T* (OperationFactory::*get_supported_method)(size_t* count) const,
+                  SupportedResponse<T>* response) {
+    if (response == NULL || !check_supported(context, algorithm, response))
+        return;
+
+    const OperationFactory* factory = context.GetOperationFactory(algorithm, purpose);
+    if (!factory) {
+        response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
+        return;
+    }
+
+    size_t count;
+    const T* supported = (factory->*get_supported_method)(&count);
+    response->SetResults(supported, count);
+}
+
+void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
+                                           SupportedBlockModesResponse* response) {
+    GetSupported(*context_, request.algorithm, request.purpose,
+                 &OperationFactory::SupportedBlockModes, response);
+}
+
+void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
+                                             SupportedPaddingModesResponse* response) {
+    GetSupported(*context_, request.algorithm, request.purpose,
+                 &OperationFactory::SupportedPaddingModes, response);
+}
+
+void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
+                                        SupportedDigestsResponse* response) {
+    GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
+                 response);
+}
+
+void AndroidKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
+                                              SupportedImportFormatsResponse* response) {
+    if (response == NULL || !check_supported(*context_, request.algorithm, response))
+        return;
+
+    size_t count;
+    const keymaster_key_format_t* formats =
+        context_->GetKeyFactory(request.algorithm)->SupportedImportFormats(&count);
+    response->SetResults(formats, count);
+}
+
+void AndroidKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
+                                              SupportedExportFormatsResponse* response) {
+    if (response == NULL || !check_supported(*context_, request.algorithm, response))
+        return;
+
+    size_t count;
+    const keymaster_key_format_t* formats =
+        context_->GetKeyFactory(request.algorithm)->SupportedExportFormats(&count);
+    response->SetResults(formats, count);
+}
+
+void AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request,
+                                     AddEntropyResponse* response) {
+    response->error = context_->AddRngEntropy(request.random_data.peek_read(),
+                                              request.random_data.available_read());
+}
+
+void AndroidKeymaster::GenerateKey(const GenerateKeyRequest& request,
+                                   GenerateKeyResponse* response) {
+    if (response == NULL)
+        return;
+
+    keymaster_algorithm_t algorithm;
+    KeyFactory* factory = 0;
+    UniquePtr<Key> key;
+    if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
+        !(factory = context_->GetKeyFactory(algorithm)))
+        response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+    else {
+        KeymasterKeyBlob key_blob;
+        response->enforced.Clear();
+        response->unenforced.Clear();
+        response->error = factory->GenerateKey(request.key_description, &key_blob,
+                                               &response->enforced, &response->unenforced);
+        if (response->error == KM_ERROR_OK)
+            response->key_blob = key_blob.release();
+    }
+}
+
+void AndroidKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
+                                             GetKeyCharacteristicsResponse* response) {
+    if (response == NULL)
+        return;
+
+    KeymasterKeyBlob key_material;
+    response->error =
+        context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
+                               &key_material, &response->enforced, &response->unenforced);
+    if (response->error != KM_ERROR_OK)
+        return;
+}
+
+static KeyFactory* GetKeyFactory(const KeymasterContext& context,
+                                 const AuthorizationSet& hw_enforced,
+                                 const AuthorizationSet& sw_enforced,
+                                 keymaster_algorithm_t* algorithm, keymaster_error_t* error) {
+    *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+    if (!hw_enforced.GetTagValue(TAG_ALGORITHM, algorithm) &&
+        !sw_enforced.GetTagValue(TAG_ALGORITHM, algorithm))
+        return nullptr;
+    KeyFactory* factory = context.GetKeyFactory(*algorithm);
+    if (factory)
+        *error = KM_ERROR_OK;
+    return factory;
+}
+
+void AndroidKeymaster::BeginOperation(const BeginOperationRequest& request,
+                                      BeginOperationResponse* response) {
+    if (response == NULL)
+        return;
+    response->op_handle = 0;
+
+    AuthorizationSet hw_enforced;
+    AuthorizationSet sw_enforced;
+    const KeyFactory* key_factory;
+    UniquePtr<Key> key;
+    response->error = LoadKey(request.key_blob, request.additional_params, &hw_enforced,
+                              &sw_enforced, &key_factory, &key);
+    if (response->error != KM_ERROR_OK)
+        return;
+
+    response->error = KM_ERROR_UNKNOWN_ERROR;
+    keymaster_algorithm_t key_algorithm;
+    if (!key->authorizations().GetTagValue(TAG_ALGORITHM, &key_algorithm))
+        return;
+
+    response->error = KM_ERROR_UNSUPPORTED_PURPOSE;
+    OperationFactory* factory = key_factory->GetOperationFactory(request.purpose);
+    if (!factory)
+        return;
+
+    UniquePtr<Operation> operation(
+        factory->CreateOperation(*key, request.additional_params, &response->error));
+    if (operation.get() == NULL)
+        return;
+
+    if (context_->enforcement_policy()) {
+        km_id_t key_id;
+        response->error = KM_ERROR_UNKNOWN_ERROR;
+        if (!context_->enforcement_policy()->CreateKeyId(request.key_blob, &key_id))
+            return;
+        operation->set_key_id(key_id);
+        response->error = context_->enforcement_policy()->AuthorizeOperation(
+            request.purpose, key_id, key->authorizations(), request.additional_params,
+            0 /* op_handle */, true /* is_begin_operation */);
+        if (response->error != KM_ERROR_OK)
+            return;
+    }
+
+    response->output_params.Clear();
+    response->error = operation->Begin(request.additional_params, &response->output_params);
+    if (response->error != KM_ERROR_OK)
+        return;
+
+    operation->SetAuthorizations(key->authorizations());
+    response->error = operation_table_->Add(operation.release(), &response->op_handle);
+}
+
+void AndroidKeymaster::UpdateOperation(const UpdateOperationRequest& request,
+                                       UpdateOperationResponse* response) {
+    if (response == NULL)
+        return;
+
+    response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
+    Operation* operation = operation_table_->Find(request.op_handle);
+    if (operation == NULL)
+        return;
+
+    if (context_->enforcement_policy()) {
+        response->error = context_->enforcement_policy()->AuthorizeOperation(
+            operation->purpose(), operation->key_id(), operation->authorizations(),
+            request.additional_params, request.op_handle, false /* is_begin_operation */);
+        if (response->error != KM_ERROR_OK) {
+            operation_table_->Delete(request.op_handle);
+            return;
+        }
+    }
+
+    response->error =
+        operation->Update(request.additional_params, request.input, &response->output_params,
+                          &response->output, &response->input_consumed);
+    if (response->error != KM_ERROR_OK) {
+        // Any error invalidates the operation.
+        operation_table_->Delete(request.op_handle);
+    }
+}
+
+void AndroidKeymaster::FinishOperation(const FinishOperationRequest& request,
+                                       FinishOperationResponse* response) {
+    if (response == NULL)
+        return;
+
+    response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
+    Operation* operation = operation_table_->Find(request.op_handle);
+    if (operation == NULL)
+        return;
+
+    if (context_->enforcement_policy()) {
+        response->error = context_->enforcement_policy()->AuthorizeOperation(
+            operation->purpose(), operation->key_id(), operation->authorizations(),
+            request.additional_params, request.op_handle, false /* is_begin_operation */);
+        if (response->error != KM_ERROR_OK) {
+            operation_table_->Delete(request.op_handle);
+            return;
+        }
+    }
+
+    response->error = operation->Finish(request.additional_params, request.input, request.signature,
+                                        &response->output_params, &response->output);
+    operation_table_->Delete(request.op_handle);
+}
+
+void AndroidKeymaster::AbortOperation(const AbortOperationRequest& request,
+                                      AbortOperationResponse* response) {
+    if (!response)
+        return;
+
+    Operation* operation = operation_table_->Find(request.op_handle);
+    if (!operation) {
+        response->error = KM_ERROR_INVALID_OPERATION_HANDLE;
+        return;
+    }
+
+    response->error = operation->Abort();
+    operation_table_->Delete(request.op_handle);
+}
+
+void AndroidKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
+    if (response == NULL)
+        return;
+
+    AuthorizationSet hw_enforced;
+    AuthorizationSet sw_enforced;
+    KeymasterKeyBlob key_material;
+    response->error =
+        context_->ParseKeyBlob(KeymasterKeyBlob(request.key_blob), request.additional_params,
+                               &key_material, &hw_enforced, &sw_enforced);
+    if (response->error != KM_ERROR_OK)
+        return;
+
+    keymaster_algorithm_t algorithm;
+    KeyFactory* key_factory =
+        GetKeyFactory(*context_, hw_enforced, sw_enforced, &algorithm, &response->error);
+    if (!key_factory)
+        return;
+
+    UniquePtr<Key> key;
+    response->error = key_factory->LoadKey(key_material, request.additional_params, hw_enforced,
+                                           sw_enforced, &key);
+    if (response->error != KM_ERROR_OK)
+        return;
+
+    UniquePtr<uint8_t[]> out_key;
+    size_t size;
+    response->error = key->formatted_key_material(request.key_format, &out_key, &size);
+    if (response->error == KM_ERROR_OK) {
+        response->key_data = out_key.release();
+        response->key_data_length = size;
+    }
+}
+
+void AndroidKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) {
+    if (!response)
+        return;
+
+    AuthorizationSet tee_enforced;
+    AuthorizationSet sw_enforced;
+    const KeyFactory* key_factory;
+    UniquePtr<Key> key;
+    response->error = LoadKey(request.key_blob, request.attest_params, &tee_enforced, &sw_enforced,
+                              &key_factory, &key);
+    if (response->error != KM_ERROR_OK)
+        return;
+
+    response->error = key->GenerateAttestation(*context_, request.attest_params, tee_enforced,
+                                               sw_enforced, &response->certificate_chain);
+}
+
+void AndroidKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
+    if (response == NULL)
+        return;
+
+    keymaster_algorithm_t algorithm;
+    KeyFactory* factory = 0;
+    UniquePtr<Key> key;
+    if (!request.key_description.GetTagValue(TAG_ALGORITHM, &algorithm) ||
+        !(factory = context_->GetKeyFactory(algorithm)))
+        response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+    else {
+        keymaster_key_blob_t key_material = {request.key_data, request.key_data_length};
+        KeymasterKeyBlob key_blob;
+        response->error = factory->ImportKey(request.key_description, request.key_format,
+                                             KeymasterKeyBlob(key_material), &key_blob,
+                                             &response->enforced, &response->unenforced);
+        if (response->error == KM_ERROR_OK)
+            response->key_blob = key_blob.release();
+    }
+}
+
+void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
+    if (!response)
+        return;
+    response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
+}
+
+void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
+    if (!response)
+        return;
+    response->error = context_->DeleteAllKeys();
+}
+
+bool AndroidKeymaster::has_operation(keymaster_operation_handle_t op_handle) const {
+    return operation_table_->Find(op_handle) != nullptr;
+}
+
+keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
+                                            const AuthorizationSet& additional_params,
+                                            AuthorizationSet* hw_enforced,
+                                            AuthorizationSet* sw_enforced,
+                                            const KeyFactory** factory, UniquePtr<Key>* key) {
+    KeymasterKeyBlob key_material;
+    keymaster_error_t error = context_->ParseKeyBlob(KeymasterKeyBlob(key_blob), additional_params,
+                                                     &key_material, hw_enforced, sw_enforced);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    keymaster_algorithm_t algorithm;
+    *factory = GetKeyFactory(*context_, *hw_enforced, *sw_enforced, &algorithm, &error);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return (*factory)->LoadKey(key_material, additional_params, *hw_enforced, *sw_enforced, key);
+}
+
+}  // namespace keymaster
diff --git a/keymaster/android_keymaster_messages.cpp b/keymaster/android_keymaster_messages.cpp
new file mode 100644
index 0000000..1b8f36e
--- /dev/null
+++ b/keymaster/android_keymaster_messages.cpp
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/android_keymaster_messages.h>
+#include <keymaster/android_keymaster_utils.h>
+
+namespace keymaster {
+
+/*
+ * Helper functions for working with key blobs.
+ */
+
+static void set_key_blob(keymaster_key_blob_t* key_blob, const void* key_material, size_t length) {
+    delete[] key_blob->key_material;
+    key_blob->key_material = dup_buffer(key_material, length);
+    key_blob->key_material_size = length;
+}
+
+static size_t key_blob_size(const keymaster_key_blob_t& key_blob) {
+    return sizeof(uint32_t) /* key size */ + key_blob.key_material_size;
+}
+
+static uint8_t* serialize_key_blob(const keymaster_key_blob_t& key_blob, uint8_t* buf,
+                                   const uint8_t* end) {
+    return append_size_and_data_to_buf(buf, end, key_blob.key_material, key_blob.key_material_size);
+}
+
+static bool deserialize_key_blob(keymaster_key_blob_t* key_blob, const uint8_t** buf_ptr,
+                                 const uint8_t* end) {
+    delete[] key_blob->key_material;
+    key_blob->key_material = 0;
+    UniquePtr<uint8_t[]> deserialized_key_material;
+    if (!copy_size_and_data_from_buf(buf_ptr, end, &key_blob->key_material_size,
+                                     &deserialized_key_material))
+        return false;
+    key_blob->key_material = deserialized_key_material.release();
+    return true;
+}
+
+size_t KeymasterResponse::SerializedSize() const {
+    if (error != KM_ERROR_OK)
+        return sizeof(int32_t);
+    else
+        return sizeof(int32_t) + NonErrorSerializedSize();
+}
+
+uint8_t* KeymasterResponse::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_uint32_to_buf(buf, end, static_cast<uint32_t>(error));
+    if (error == KM_ERROR_OK)
+        buf = NonErrorSerialize(buf, end);
+    return buf;
+}
+
+bool KeymasterResponse::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    if (!copy_uint32_from_buf(buf_ptr, end, &error))
+        return false;
+    if (error != KM_ERROR_OK)
+        return true;
+    return NonErrorDeserialize(buf_ptr, end);
+}
+
+GenerateKeyResponse::~GenerateKeyResponse() {
+    delete[] key_blob.key_material;
+}
+
+size_t GenerateKeyResponse::NonErrorSerializedSize() const {
+    return key_blob_size(key_blob) + enforced.SerializedSize() + unenforced.SerializedSize();
+}
+
+uint8_t* GenerateKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = serialize_key_blob(key_blob, buf, end);
+    buf = enforced.Serialize(buf, end);
+    return unenforced.Serialize(buf, end);
+}
+
+bool GenerateKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return deserialize_key_blob(&key_blob, buf_ptr, end) && enforced.Deserialize(buf_ptr, end) &&
+           unenforced.Deserialize(buf_ptr, end);
+}
+
+GetKeyCharacteristicsRequest::~GetKeyCharacteristicsRequest() {
+    delete[] key_blob.key_material;
+}
+
+void GetKeyCharacteristicsRequest::SetKeyMaterial(const void* key_material, size_t length) {
+    set_key_blob(&key_blob, key_material, length);
+}
+
+size_t GetKeyCharacteristicsRequest::SerializedSize() const {
+    return key_blob_size(key_blob) + additional_params.SerializedSize();
+}
+
+uint8_t* GetKeyCharacteristicsRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = serialize_key_blob(key_blob, buf, end);
+    return additional_params.Serialize(buf, end);
+}
+
+bool GetKeyCharacteristicsRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return deserialize_key_blob(&key_blob, buf_ptr, end) &&
+           additional_params.Deserialize(buf_ptr, end);
+}
+
+size_t GetKeyCharacteristicsResponse::NonErrorSerializedSize() const {
+    return enforced.SerializedSize() + unenforced.SerializedSize();
+}
+
+uint8_t* GetKeyCharacteristicsResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = enforced.Serialize(buf, end);
+    return unenforced.Serialize(buf, end);
+}
+
+bool GetKeyCharacteristicsResponse::NonErrorDeserialize(const uint8_t** buf_ptr,
+                                                        const uint8_t* end) {
+    return enforced.Deserialize(buf_ptr, end) && unenforced.Deserialize(buf_ptr, end);
+}
+
+void BeginOperationRequest::SetKeyMaterial(const void* key_material, size_t length) {
+    set_key_blob(&key_blob, key_material, length);
+}
+
+size_t BeginOperationRequest::SerializedSize() const {
+    return sizeof(uint32_t) /* purpose */ + key_blob_size(key_blob) +
+           additional_params.SerializedSize();
+}
+
+uint8_t* BeginOperationRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_uint32_to_buf(buf, end, purpose);
+    buf = serialize_key_blob(key_blob, buf, end);
+    return additional_params.Serialize(buf, end);
+}
+
+bool BeginOperationRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return copy_uint32_from_buf(buf_ptr, end, &purpose) &&
+           deserialize_key_blob(&key_blob, buf_ptr, end) &&
+           additional_params.Deserialize(buf_ptr, end);
+}
+
+size_t BeginOperationResponse::NonErrorSerializedSize() const {
+    if (message_version == 0)
+        return sizeof(op_handle);
+    else
+        return sizeof(op_handle) + output_params.SerializedSize();
+}
+
+uint8_t* BeginOperationResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_uint64_to_buf(buf, end, op_handle);
+    if (message_version > 0)
+        buf = output_params.Serialize(buf, end);
+    return buf;
+}
+
+bool BeginOperationResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    bool retval = copy_uint64_from_buf(buf_ptr, end, &op_handle);
+    if (retval && message_version > 0)
+        retval = output_params.Deserialize(buf_ptr, end);
+    return retval;
+}
+
+size_t UpdateOperationRequest::SerializedSize() const {
+    if (message_version == 0)
+        return sizeof(op_handle) + input.SerializedSize();
+    else
+        return sizeof(op_handle) + input.SerializedSize() + additional_params.SerializedSize();
+}
+
+uint8_t* UpdateOperationRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_uint64_to_buf(buf, end, op_handle);
+    buf = input.Serialize(buf, end);
+    if (message_version > 0)
+        buf = additional_params.Serialize(buf, end);
+    return buf;
+}
+
+bool UpdateOperationRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    bool retval = copy_uint64_from_buf(buf_ptr, end, &op_handle) && input.Deserialize(buf_ptr, end);
+    if (retval && message_version > 0)
+        retval = additional_params.Deserialize(buf_ptr, end);
+    return retval;
+}
+
+size_t UpdateOperationResponse::NonErrorSerializedSize() const {
+    size_t size = 0;
+    switch (message_version) {
+    case 3:
+    case 2:
+        size += output_params.SerializedSize();
+        ; /* falls through */
+    case 1:
+        size += sizeof(uint32_t);
+        ; /* falls through */
+    case 0:
+        size += output.SerializedSize();
+        break;
+
+    default:
+        assert(false);
+    }
+
+    return size;
+}
+
+uint8_t* UpdateOperationResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = output.Serialize(buf, end);
+    if (message_version > 0)
+        buf = append_uint32_to_buf(buf, end, input_consumed);
+    if (message_version > 1)
+        buf = output_params.Serialize(buf, end);
+    return buf;
+}
+
+bool UpdateOperationResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    bool retval = output.Deserialize(buf_ptr, end);
+    if (retval && message_version > 0)
+        retval = copy_uint32_from_buf(buf_ptr, end, &input_consumed);
+    if (retval && message_version > 1)
+        retval = output_params.Deserialize(buf_ptr, end);
+    return retval;
+}
+
+size_t FinishOperationRequest::SerializedSize() const {
+    size_t size = 0;
+    switch (message_version) {
+    case 3:
+        size += input.SerializedSize();
+        ; /* falls through */
+    case 2:
+    case 1:
+        size += additional_params.SerializedSize();
+        ; /* falls through */
+    case 0:
+        size += sizeof(op_handle) + signature.SerializedSize();
+        break;
+
+    default:
+        assert(false);  // Should never get here.
+    }
+
+    return size;
+}
+
+uint8_t* FinishOperationRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_uint64_to_buf(buf, end, op_handle);
+    buf = signature.Serialize(buf, end);
+    if (message_version > 0)
+        buf = additional_params.Serialize(buf, end);
+    if (message_version > 2)
+        buf = input.Serialize(buf, end);
+    return buf;
+}
+
+bool FinishOperationRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    bool retval =
+        copy_uint64_from_buf(buf_ptr, end, &op_handle) && signature.Deserialize(buf_ptr, end);
+    if (retval && message_version > 0)
+        retval = additional_params.Deserialize(buf_ptr, end);
+    if (retval && message_version > 2)
+        retval = input.Deserialize(buf_ptr, end);
+    return retval;
+}
+
+size_t FinishOperationResponse::NonErrorSerializedSize() const {
+    if (message_version < 2)
+        return output.SerializedSize();
+    else
+        return output.SerializedSize() + output_params.SerializedSize();
+}
+
+uint8_t* FinishOperationResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = output.Serialize(buf, end);
+    if (message_version > 1)
+        buf = output_params.Serialize(buf, end);
+    return buf;
+}
+
+bool FinishOperationResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    bool retval = output.Deserialize(buf_ptr, end);
+    if (retval && message_version > 1)
+        retval = output_params.Deserialize(buf_ptr, end);
+    return retval;
+}
+
+size_t AddEntropyRequest::SerializedSize() const {
+    return random_data.SerializedSize();
+}
+
+uint8_t* AddEntropyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    return random_data.Serialize(buf, end);
+}
+
+bool AddEntropyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return random_data.Deserialize(buf_ptr, end);
+}
+
+void ImportKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
+    delete[] key_data;
+    key_data = dup_buffer(key_material, length);
+    key_data_length = length;
+}
+
+size_t ImportKeyRequest::SerializedSize() const {
+    return key_description.SerializedSize() + sizeof(uint32_t) /* key_format */ +
+           sizeof(uint32_t) /* key_data_length */ + key_data_length;
+}
+
+uint8_t* ImportKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = key_description.Serialize(buf, end);
+    buf = append_uint32_to_buf(buf, end, key_format);
+    return append_size_and_data_to_buf(buf, end, key_data, key_data_length);
+}
+
+bool ImportKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    delete[] key_data;
+    key_data = NULL;
+    UniquePtr<uint8_t[]> deserialized_key_material;
+    if (!key_description.Deserialize(buf_ptr, end) ||
+        !copy_uint32_from_buf(buf_ptr, end, &key_format) ||
+        !copy_size_and_data_from_buf(buf_ptr, end, &key_data_length, &deserialized_key_material))
+        return false;
+    key_data = deserialized_key_material.release();
+    return true;
+}
+
+void ImportKeyResponse::SetKeyMaterial(const void* key_material, size_t length) {
+    set_key_blob(&key_blob, key_material, length);
+}
+
+size_t ImportKeyResponse::NonErrorSerializedSize() const {
+    return key_blob_size(key_blob) + enforced.SerializedSize() + unenforced.SerializedSize();
+}
+
+uint8_t* ImportKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = serialize_key_blob(key_blob, buf, end);
+    buf = enforced.Serialize(buf, end);
+    return unenforced.Serialize(buf, end);
+}
+
+bool ImportKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return deserialize_key_blob(&key_blob, buf_ptr, end) && enforced.Deserialize(buf_ptr, end) &&
+           unenforced.Deserialize(buf_ptr, end);
+}
+
+void ExportKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
+    set_key_blob(&key_blob, key_material, length);
+}
+
+size_t ExportKeyRequest::SerializedSize() const {
+    return additional_params.SerializedSize() + sizeof(uint32_t) /* key_format */ +
+           key_blob_size(key_blob);
+}
+
+uint8_t* ExportKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = additional_params.Serialize(buf, end);
+    buf = append_uint32_to_buf(buf, end, key_format);
+    return serialize_key_blob(key_blob, buf, end);
+}
+
+bool ExportKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return additional_params.Deserialize(buf_ptr, end) &&
+           copy_uint32_from_buf(buf_ptr, end, &key_format) &&
+           deserialize_key_blob(&key_blob, buf_ptr, end);
+}
+
+void ExportKeyResponse::SetKeyMaterial(const void* key_material, size_t length) {
+    delete[] key_data;
+    key_data = dup_buffer(key_material, length);
+    key_data_length = length;
+}
+
+size_t ExportKeyResponse::NonErrorSerializedSize() const {
+    return sizeof(uint32_t) /* key_data_length */ + key_data_length;
+}
+
+uint8_t* ExportKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    return append_size_and_data_to_buf(buf, end, key_data, key_data_length);
+}
+
+bool ExportKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    delete[] key_data;
+    key_data = NULL;
+    UniquePtr<uint8_t[]> deserialized_key_material;
+    if (!copy_size_and_data_from_buf(buf_ptr, end, &key_data_length, &deserialized_key_material))
+        return false;
+    key_data = deserialized_key_material.release();
+    return true;
+}
+
+void DeleteKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
+    set_key_blob(&key_blob, key_material, length);
+}
+
+size_t DeleteKeyRequest::SerializedSize() const {
+    return key_blob_size(key_blob);
+}
+
+uint8_t* DeleteKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    return serialize_key_blob(key_blob, buf, end);
+}
+
+bool DeleteKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return deserialize_key_blob(&key_blob, buf_ptr, end);
+}
+
+size_t GetVersionResponse::NonErrorSerializedSize() const {
+    return sizeof(major_ver) + sizeof(minor_ver) + sizeof(subminor_ver);
+}
+
+uint8_t* GetVersionResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    if (buf + NonErrorSerializedSize() <= end) {
+        *buf++ = major_ver;
+        *buf++ = minor_ver;
+        *buf++ = subminor_ver;
+    } else {
+        buf += NonErrorSerializedSize();
+    }
+    return buf;
+}
+
+bool GetVersionResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    if (*buf_ptr + NonErrorSerializedSize() > end)
+        return false;
+    const uint8_t* tmp = *buf_ptr;
+    major_ver = *tmp++;
+    minor_ver = *tmp++;
+    subminor_ver = *tmp++;
+    *buf_ptr = tmp;
+    return true;
+}
+
+AttestKeyRequest::~AttestKeyRequest() {
+    delete[] key_blob.key_material;
+}
+
+void AttestKeyRequest::SetKeyMaterial(const void* key_material, size_t length) {
+    set_key_blob(&key_blob, key_material, length);
+}
+
+size_t AttestKeyRequest::SerializedSize() const {
+    return key_blob_size(key_blob) + attest_params.SerializedSize();
+}
+
+uint8_t* AttestKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = serialize_key_blob(key_blob, buf, end);
+    return attest_params.Serialize(buf, end);
+}
+
+bool AttestKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    return deserialize_key_blob(&key_blob, buf_ptr, end) && attest_params.Deserialize(buf_ptr, end);
+}
+
+AttestKeyResponse::~AttestKeyResponse() {
+    for (size_t i = 0; i < certificate_chain.entry_count; ++i)
+        delete[] certificate_chain.entries[i].data;
+    delete[] certificate_chain.entries;
+}
+
+const size_t kMaxChainEntryCount = 10;
+bool AttestKeyResponse::AllocateChain(size_t entry_count) {
+    if (entry_count > kMaxChainEntryCount)
+        return false;
+
+    if (certificate_chain.entries) {
+        for (size_t i = 0; i < certificate_chain.entry_count; ++i)
+            delete[] certificate_chain.entries[i].data;
+        delete[] certificate_chain.entries;
+    }
+
+    certificate_chain.entry_count = entry_count;
+    certificate_chain.entries = new keymaster_blob_t[entry_count];
+    if (!certificate_chain.entries) {
+        certificate_chain.entry_count = 0;
+        return false;
+    }
+
+    memset(certificate_chain.entries, 0, sizeof(certificate_chain.entries[0]) * entry_count);
+    return true;
+}
+
+size_t AttestKeyResponse::NonErrorSerializedSize() const {
+    size_t result = sizeof(uint32_t); /* certificate_chain.entry_count */
+    for (size_t i = 0; i < certificate_chain.entry_count; ++i) {
+        result += sizeof(uint32_t); /* certificate_chain.entries[i].data_length */
+        result += certificate_chain.entries[i].data_length;
+    }
+    return result;
+}
+
+uint8_t* AttestKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_uint32_to_buf(buf, end, certificate_chain.entry_count);
+    for (size_t i = 0; i < certificate_chain.entry_count; ++i) {
+        buf = append_size_and_data_to_buf(buf, end, certificate_chain.entries[i].data,
+                                          certificate_chain.entries[i].data_length);
+    }
+    return buf;
+}
+
+bool AttestKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    size_t entry_count;
+    if (!copy_uint32_from_buf(buf_ptr, end, &entry_count) || !AllocateChain(entry_count))
+        return false;
+
+    for (size_t i = 0; i < certificate_chain.entry_count; ++i) {
+        UniquePtr<uint8_t[]> data;
+        size_t data_length;
+        if (!copy_size_and_data_from_buf(buf_ptr, end, &data_length, &data))
+            return false;
+        certificate_chain.entries[i].data = data.release();
+        certificate_chain.entries[i].data_length = data_length;
+    }
+
+    return true;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/android_keymaster_messages_test.cpp b/keymaster/android_keymaster_messages_test.cpp
new file mode 100644
index 0000000..1ec5894
--- /dev/null
+++ b/keymaster/android_keymaster_messages_test.cpp
@@ -0,0 +1,683 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <UniquePtr.h>
+
+#include <gtest/gtest.h>
+
+#include <keymaster/android_keymaster.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/keymaster_tags.h>
+
+#include "android_keymaster_test_utils.h"
+
+namespace keymaster {
+namespace test {
+
+/**
+ * Serialize and deserialize a message.
+ */
+template <typename Message>
+Message* round_trip(int32_t ver, const Message& message, size_t expected_size) {
+    size_t size = message.SerializedSize();
+    EXPECT_EQ(expected_size, size);
+    if (size == 0)
+        return NULL;
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, message.Serialize(buf.get(), buf.get() + size));
+
+    Message* deserialized = new Message(ver);
+    const uint8_t* p = buf.get();
+    EXPECT_TRUE(deserialized->Deserialize(&p, p + size));
+    EXPECT_EQ((ptrdiff_t)size, p - buf.get());
+    return deserialized;
+}
+
+struct EmptyKeymasterResponse : public KeymasterResponse {
+    explicit EmptyKeymasterResponse(int32_t ver) : KeymasterResponse(ver) {}
+    size_t NonErrorSerializedSize() const { return 1; }
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* /* end */) const {
+        *buf++ = 0;
+        return buf;
+    }
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+        if (*buf_ptr >= end)
+            return false;
+        EXPECT_EQ(0, **buf_ptr);
+        (*buf_ptr)++;
+        return true;
+    }
+};
+
+TEST(RoundTrip, EmptyKeymasterResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        EmptyKeymasterResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+
+        UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(ver, msg, 5));
+    }
+}
+
+TEST(RoundTrip, EmptyKeymasterResponseError) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        EmptyKeymasterResponse msg(ver);
+        msg.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+        UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(ver, msg, 4));
+    }
+}
+
+TEST(RoundTrip, SupportedByAlgorithmRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        SupportedByAlgorithmRequest req(ver);
+        req.algorithm = KM_ALGORITHM_EC;
+
+        UniquePtr<SupportedByAlgorithmRequest> deserialized(round_trip(ver, req, 4));
+        EXPECT_EQ(KM_ALGORITHM_EC, deserialized->algorithm);
+    }
+}
+
+TEST(RoundTrip, SupportedByAlgorithmAndPurposeRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        SupportedByAlgorithmAndPurposeRequest req(ver);
+        req.algorithm = KM_ALGORITHM_EC;
+        req.purpose = KM_PURPOSE_DECRYPT;
+
+        UniquePtr<SupportedByAlgorithmAndPurposeRequest> deserialized(round_trip(ver, req, 8));
+        EXPECT_EQ(KM_ALGORITHM_EC, deserialized->algorithm);
+        EXPECT_EQ(KM_PURPOSE_DECRYPT, deserialized->purpose);
+    }
+}
+
+TEST(RoundTrip, SupportedResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        SupportedResponse<keymaster_digest_t> rsp(ver);
+        keymaster_digest_t digests[] = {KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1};
+        rsp.error = KM_ERROR_OK;
+        rsp.SetResults(digests);
+
+        UniquePtr<SupportedResponse<keymaster_digest_t>> deserialized(round_trip(ver, rsp, 20));
+        EXPECT_EQ(array_length(digests), deserialized->results_length);
+        EXPECT_EQ(0, memcmp(deserialized->results, digests, array_size(digests)));
+    }
+}
+
+static keymaster_key_param_t params[] = {
+    Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+    Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+    Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
+    Authorization(TAG_USER_ID, 7),
+    Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD),
+    Authorization(TAG_APPLICATION_ID, "app_id", 6),
+    Authorization(TAG_AUTH_TIMEOUT, 300),
+};
+uint8_t TEST_DATA[] = "a key blob";
+
+TEST(RoundTrip, GenerateKeyRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        GenerateKeyRequest req(ver);
+        req.key_description.Reinitialize(params, array_length(params));
+        UniquePtr<GenerateKeyRequest> deserialized(round_trip(ver, req, 78));
+        EXPECT_EQ(deserialized->key_description, req.key_description);
+    }
+}
+
+TEST(RoundTrip, GenerateKeyResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        GenerateKeyResponse rsp(ver);
+        rsp.error = KM_ERROR_OK;
+        rsp.key_blob.key_material = dup_array(TEST_DATA);
+        rsp.key_blob.key_material_size = array_length(TEST_DATA);
+        rsp.enforced.Reinitialize(params, array_length(params));
+
+        UniquePtr<GenerateKeyResponse> deserialized(round_trip(ver, rsp, 109));
+        EXPECT_EQ(KM_ERROR_OK, deserialized->error);
+        EXPECT_EQ(deserialized->enforced, rsp.enforced);
+        EXPECT_EQ(deserialized->unenforced, rsp.unenforced);
+    }
+}
+
+TEST(RoundTrip, GenerateKeyResponseTestError) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        GenerateKeyResponse rsp(ver);
+        rsp.error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+        rsp.key_blob.key_material = dup_array(TEST_DATA);
+        rsp.key_blob.key_material_size = array_length(TEST_DATA);
+        rsp.enforced.Reinitialize(params, array_length(params));
+
+        UniquePtr<GenerateKeyResponse> deserialized(round_trip(ver, rsp, 4));
+        EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, deserialized->error);
+        EXPECT_EQ(0U, deserialized->enforced.size());
+        EXPECT_EQ(0U, deserialized->unenforced.size());
+        EXPECT_EQ(0U, deserialized->key_blob.key_material_size);
+    }
+}
+
+TEST(RoundTrip, GetKeyCharacteristicsRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        GetKeyCharacteristicsRequest req(ver);
+        req.additional_params.Reinitialize(params, array_length(params));
+        req.SetKeyMaterial("foo", 3);
+
+        UniquePtr<GetKeyCharacteristicsRequest> deserialized(round_trip(ver, req, 85));
+        EXPECT_EQ(7U, deserialized->additional_params.size());
+        EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
+        EXPECT_EQ(0, memcmp(deserialized->key_blob.key_material, "foo", 3));
+    }
+}
+
+TEST(RoundTrip, GetKeyCharacteristicsResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        GetKeyCharacteristicsResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        msg.enforced.Reinitialize(params, array_length(params));
+        msg.unenforced.Reinitialize(params, array_length(params));
+
+        UniquePtr<GetKeyCharacteristicsResponse> deserialized(round_trip(ver, msg, 160));
+        EXPECT_EQ(msg.enforced, deserialized->enforced);
+        EXPECT_EQ(msg.unenforced, deserialized->unenforced);
+    }
+}
+
+TEST(RoundTrip, BeginOperationRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        BeginOperationRequest msg(ver);
+        msg.purpose = KM_PURPOSE_SIGN;
+        msg.SetKeyMaterial("foo", 3);
+        msg.additional_params.Reinitialize(params, array_length(params));
+
+        UniquePtr<BeginOperationRequest> deserialized(round_trip(ver, msg, 89));
+        EXPECT_EQ(KM_PURPOSE_SIGN, deserialized->purpose);
+        EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
+        EXPECT_EQ(0, memcmp(deserialized->key_blob.key_material, "foo", 3));
+        EXPECT_EQ(msg.additional_params, deserialized->additional_params);
+    }
+}
+
+TEST(RoundTrip, BeginOperationResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        BeginOperationResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        msg.op_handle = 0xDEADBEEF;
+        msg.output_params.push_back(Authorization(TAG_NONCE, "foo", 3));
+
+        UniquePtr<BeginOperationResponse> deserialized;
+        switch (ver) {
+        case 0:
+            deserialized.reset(round_trip(ver, msg, 12));
+            break;
+        case 1:
+        case 2:
+        case 3:
+            deserialized.reset(round_trip(ver, msg, 39));
+            break;
+        default:
+            FAIL();
+        }
+
+        EXPECT_EQ(KM_ERROR_OK, deserialized->error);
+        EXPECT_EQ(0xDEADBEEF, deserialized->op_handle);
+
+        switch (ver) {
+        case 0:
+            EXPECT_EQ(0U, deserialized->output_params.size());
+            break;
+        case 1:
+        case 2:
+        case 3:
+            EXPECT_EQ(msg.output_params, deserialized->output_params);
+            break;
+        default:
+            FAIL();
+        }
+    }
+}
+
+TEST(RoundTrip, BeginOperationResponseError) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        BeginOperationResponse msg(ver);
+        msg.error = KM_ERROR_INVALID_OPERATION_HANDLE;
+        msg.op_handle = 0xDEADBEEF;
+
+        UniquePtr<BeginOperationResponse> deserialized(round_trip(ver, msg, 4));
+        EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, deserialized->error);
+    }
+}
+
+TEST(RoundTrip, UpdateOperationRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        UpdateOperationRequest msg(ver);
+        msg.op_handle = 0xDEADBEEF;
+        msg.input.Reinitialize("foo", 3);
+
+        UniquePtr<UpdateOperationRequest> deserialized;
+        switch (ver) {
+        case 0:
+            deserialized.reset(round_trip(ver, msg, 15));
+            break;
+        case 1:
+        case 2:
+        case 3:
+            deserialized.reset(round_trip(ver, msg, 27));
+            break;
+        default:
+            FAIL();
+        }
+        EXPECT_EQ(3U, deserialized->input.available_read());
+        EXPECT_EQ(0, memcmp(deserialized->input.peek_read(), "foo", 3));
+    }
+}
+
+TEST(RoundTrip, UpdateOperationResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        UpdateOperationResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        msg.output.Reinitialize("foo", 3);
+        msg.input_consumed = 99;
+        msg.output_params.push_back(TAG_APPLICATION_ID, "bar", 3);
+
+        UniquePtr<UpdateOperationResponse> deserialized;
+        switch (ver) {
+        case 0:
+            deserialized.reset(round_trip(ver, msg, 11));
+            break;
+        case 1:
+            deserialized.reset(round_trip(ver, msg, 15));
+            break;
+        case 2:
+        case 3:
+            deserialized.reset(round_trip(ver, msg, 42));
+            break;
+        default:
+            FAIL();
+        }
+        EXPECT_EQ(KM_ERROR_OK, deserialized->error);
+        EXPECT_EQ(3U, deserialized->output.available_read());
+        EXPECT_EQ(0, memcmp(deserialized->output.peek_read(), "foo", 3));
+
+        switch (ver) {
+        case 0:
+            EXPECT_EQ(0U, deserialized->input_consumed);
+            break;
+        case 1:
+            EXPECT_EQ(99U, deserialized->input_consumed);
+            break;
+        case 2:
+        case 3:
+            EXPECT_EQ(99U, deserialized->input_consumed);
+            EXPECT_EQ(1U, deserialized->output_params.size());
+            break;
+        default:
+            FAIL();
+        }
+    }
+}
+
+TEST(RoundTrip, FinishOperationRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        FinishOperationRequest msg(ver);
+        msg.op_handle = 0xDEADBEEF;
+        msg.signature.Reinitialize("bar", 3);
+        msg.input.Reinitialize("baz", 3);
+
+        UniquePtr<FinishOperationRequest> deserialized;
+        switch (ver) {
+        case 0:
+            deserialized.reset(round_trip(ver, msg, 15));
+            break;
+        case 1:
+        case 2:
+            deserialized.reset(round_trip(ver, msg, 27));
+            break;
+        case 3:
+            deserialized.reset(round_trip(ver, msg, 34));
+            break;
+        default:
+            FAIL();
+        }
+        EXPECT_EQ(0xDEADBEEF, deserialized->op_handle);
+        EXPECT_EQ(3U, deserialized->signature.available_read());
+        EXPECT_EQ(0, memcmp(deserialized->signature.peek_read(), "bar", 3));
+    }
+}
+
+TEST(Round_Trip, FinishOperationResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        FinishOperationResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        msg.output.Reinitialize("foo", 3);
+
+        UniquePtr<FinishOperationResponse> deserialized;
+        switch (ver) {
+        case 0:
+        case 1:
+            deserialized.reset(round_trip(ver, msg, 11));
+            break;
+        case 2:
+        case 3:
+            deserialized.reset(round_trip(ver, msg, 23));
+            break;
+        default:
+            FAIL();
+        }
+        EXPECT_EQ(msg.error, deserialized->error);
+        EXPECT_EQ(msg.output.available_read(), deserialized->output.available_read());
+        EXPECT_EQ(0, memcmp(msg.output.peek_read(), deserialized->output.peek_read(),
+                            msg.output.available_read()));
+    }
+}
+
+TEST(RoundTrip, ImportKeyRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        ImportKeyRequest msg(ver);
+        msg.key_description.Reinitialize(params, array_length(params));
+        msg.key_format = KM_KEY_FORMAT_X509;
+        msg.SetKeyMaterial("foo", 3);
+
+        UniquePtr<ImportKeyRequest> deserialized(round_trip(ver, msg, 89));
+        EXPECT_EQ(msg.key_description, deserialized->key_description);
+        EXPECT_EQ(msg.key_format, deserialized->key_format);
+        EXPECT_EQ(msg.key_data_length, deserialized->key_data_length);
+        EXPECT_EQ(0, memcmp(msg.key_data, deserialized->key_data, msg.key_data_length));
+    }
+}
+
+TEST(RoundTrip, ImportKeyResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        ImportKeyResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        msg.SetKeyMaterial("foo", 3);
+        msg.enforced.Reinitialize(params, array_length(params));
+        msg.unenforced.Reinitialize(params, array_length(params));
+
+        UniquePtr<ImportKeyResponse> deserialized(round_trip(ver, msg, 167));
+        EXPECT_EQ(msg.error, deserialized->error);
+        EXPECT_EQ(msg.key_blob.key_material_size, deserialized->key_blob.key_material_size);
+        EXPECT_EQ(0, memcmp(msg.key_blob.key_material, deserialized->key_blob.key_material,
+                            msg.key_blob.key_material_size));
+        EXPECT_EQ(msg.enforced, deserialized->enforced);
+        EXPECT_EQ(msg.unenforced, deserialized->unenforced);
+    }
+}
+
+TEST(RoundTrip, ExportKeyRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        ExportKeyRequest msg(ver);
+        msg.additional_params.Reinitialize(params, array_length(params));
+        msg.key_format = KM_KEY_FORMAT_X509;
+        msg.SetKeyMaterial("foo", 3);
+
+        UniquePtr<ExportKeyRequest> deserialized(round_trip(ver, msg, 89));
+        EXPECT_EQ(msg.additional_params, deserialized->additional_params);
+        EXPECT_EQ(msg.key_format, deserialized->key_format);
+        EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
+        EXPECT_EQ(0, memcmp("foo", deserialized->key_blob.key_material, 3));
+    }
+}
+
+TEST(RoundTrip, ExportKeyResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        ExportKeyResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        msg.SetKeyMaterial("foo", 3);
+
+        UniquePtr<ExportKeyResponse> deserialized(round_trip(ver, msg, 11));
+        EXPECT_EQ(3U, deserialized->key_data_length);
+        EXPECT_EQ(0, memcmp("foo", deserialized->key_data, 3));
+    }
+}
+
+TEST(RoundTrip, DeleteKeyRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        DeleteKeyRequest msg(ver);
+        msg.SetKeyMaterial("foo", 3);
+
+        UniquePtr<DeleteKeyRequest> deserialized(round_trip(ver, msg, 7));
+        EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
+        EXPECT_EQ(0, memcmp("foo", deserialized->key_blob.key_material, 3));
+    }
+}
+
+TEST(RoundTrip, DeleteKeyResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        DeleteKeyResponse msg(ver);
+        UniquePtr<DeleteKeyResponse> deserialized(round_trip(ver, msg, 4));
+    }
+}
+
+TEST(RoundTrip, DeleteAllKeysRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        DeleteAllKeysRequest msg(ver);
+        UniquePtr<DeleteAllKeysRequest> deserialized(round_trip(ver, msg, 0));
+    }
+}
+
+TEST(RoundTrip, DeleteAllKeysResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        DeleteAllKeysResponse msg(ver);
+        UniquePtr<DeleteAllKeysResponse> deserialized(round_trip(ver, msg, 4));
+    }
+}
+
+TEST(RoundTrip, GetVersionRequest) {
+    GetVersionRequest msg;
+
+    size_t size = msg.SerializedSize();
+    ASSERT_EQ(0U, size);
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, msg.Serialize(buf.get(), buf.get() + size));
+
+    GetVersionRequest deserialized;
+    const uint8_t* p = buf.get();
+    EXPECT_TRUE(deserialized.Deserialize(&p, p + size));
+    EXPECT_EQ((ptrdiff_t)size, p - buf.get());
+}
+
+TEST(RoundTrip, GetVersionResponse) {
+    GetVersionResponse msg;
+    msg.error = KM_ERROR_OK;
+    msg.major_ver = 9;
+    msg.minor_ver = 98;
+    msg.subminor_ver = 38;
+
+    size_t size = msg.SerializedSize();
+    ASSERT_EQ(7U, size);
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, msg.Serialize(buf.get(), buf.get() + size));
+
+    GetVersionResponse deserialized;
+    const uint8_t* p = buf.get();
+    EXPECT_TRUE(deserialized.Deserialize(&p, p + size));
+    EXPECT_EQ((ptrdiff_t)size, p - buf.get());
+    EXPECT_EQ(9U, msg.major_ver);
+    EXPECT_EQ(98U, msg.minor_ver);
+    EXPECT_EQ(38U, msg.subminor_ver);
+}
+
+TEST(RoundTrip, AddEntropyRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        AddEntropyRequest msg(ver);
+        msg.random_data.Reinitialize("foo", 3);
+
+        UniquePtr<AddEntropyRequest> deserialized(round_trip(ver, msg, 7));
+        EXPECT_EQ(3U, deserialized->random_data.available_read());
+        EXPECT_EQ(0, memcmp("foo", deserialized->random_data.peek_read(), 3));
+    }
+}
+
+TEST(RoundTrip, AddEntropyResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        AddEntropyResponse msg(ver);
+        UniquePtr<AddEntropyResponse> deserialized(round_trip(ver, msg, 4));
+    }
+}
+
+TEST(RoundTrip, AbortOperationRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        AbortOperationRequest msg(ver);
+        UniquePtr<AbortOperationRequest> deserialized(round_trip(ver, msg, 8));
+    }
+}
+
+TEST(RoundTrip, AbortOperationResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        AbortOperationResponse msg(ver);
+        UniquePtr<AbortOperationResponse> deserialized(round_trip(ver, msg, 4));
+    }
+}
+
+TEST(RoundTrip, AttestKeyRequest) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        AttestKeyRequest msg(ver);
+        msg.SetKeyMaterial("foo", 3);
+        msg.attest_params.Reinitialize(params, array_length(params));
+
+        UniquePtr<AttestKeyRequest> deserialized(round_trip(ver, msg, 85));
+        EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
+        EXPECT_EQ(0, memcmp("foo", deserialized->key_blob.key_material, 3));
+        EXPECT_EQ(msg.attest_params, deserialized->attest_params);
+    }
+}
+
+TEST(RoundTrip, AttestKeyResponse) {
+    for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        AttestKeyResponse msg(ver);
+        msg.error = KM_ERROR_OK;
+        EXPECT_TRUE(msg.AllocateChain(3));
+        msg.certificate_chain.entries[0] = {dup_buffer("foo", 3), 3};
+        msg.certificate_chain.entries[1] = {dup_buffer("bar", 3), 3};
+        msg.certificate_chain.entries[2] = {dup_buffer("baz", 3), 3};
+
+        UniquePtr<AttestKeyResponse> deserialized(round_trip(ver, msg, 29));
+        keymaster_cert_chain_t* chain = &deserialized->certificate_chain;
+
+        EXPECT_NE(nullptr, chain->entries);
+        EXPECT_EQ(3U, chain->entry_count);
+        EXPECT_EQ(3U, chain->entries[0].data_length);
+        EXPECT_EQ(0, memcmp("foo", chain->entries[0].data, 3));
+        EXPECT_EQ(3U, chain->entries[1].data_length);
+        EXPECT_EQ(0, memcmp("bar", chain->entries[1].data, 3));
+        EXPECT_EQ(3U, chain->entries[2].data_length);
+        EXPECT_EQ(0, memcmp("baz", chain->entries[2].data, 3));
+    }
+}
+
+uint8_t msgbuf[] = {
+    220, 88,  183, 255, 71,  1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   173, 0,   0,   0,   228, 174, 98,  187, 191, 135, 253, 200, 51,  230, 114, 247, 151, 109,
+    237, 79,  87,  32,  94,  5,   204, 46,  154, 30,  91,  6,   103, 148, 254, 129, 65,  171, 228,
+    167, 224, 163, 9,   15,  206, 90,  58,  11,  205, 55,  211, 33,  87,  178, 149, 91,  28,  236,
+    218, 112, 231, 34,  82,  82,  134, 103, 137, 115, 27,  156, 102, 159, 220, 226, 89,  42,  25,
+    37,  9,   84,  239, 76,  161, 198, 72,  167, 163, 39,  91,  148, 191, 17,  191, 87,  169, 179,
+    136, 10,  194, 154, 4,   40,  107, 109, 61,  161, 20,  176, 247, 13,  214, 106, 229, 45,  17,
+    5,   60,  189, 64,  39,  166, 208, 14,  57,  25,  140, 148, 25,  177, 246, 189, 43,  181, 88,
+    204, 29,  126, 224, 100, 143, 93,  60,  57,  249, 55,  0,   87,  83,  227, 224, 166, 59,  214,
+    81,  144, 129, 58,  6,   57,  46,  254, 232, 41,  220, 209, 230, 167, 138, 158, 94,  180, 125,
+    247, 26,  162, 116, 238, 202, 187, 100, 65,  13,  180, 44,  245, 159, 83,  161, 176, 58,  72,
+    236, 109, 105, 160, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    0,   11,  0,   0,   0,   98,  0,   0,   0,   1,   0,   0,   32,  2,   0,   0,   0,   1,   0,
+    0,   32,  3,   0,   0,   0,   2,   0,   0,   16,  1,   0,   0,   0,   3,   0,   0,   48,  0,
+    1,   0,   0,   200, 0,   0,   80,  3,   0,   0,   0,   0,   0,   0,   0,   244, 1,   0,   112,
+    1,   246, 1,   0,   112, 1,   189, 2,   0,   96,  144, 178, 236, 250, 255, 255, 255, 255, 145,
+    1,   0,   96,  144, 226, 33,  60,  222, 2,   0,   0,   189, 2,   0,   96,  0,   0,   0,   0,
+    0,   0,   0,   0,   190, 2,   0,   16,  1,   0,   0,   0,   12,  0,   0,   0,   0,   0,   0,
+    0,   0,   0,   0,   0,   0,   0,   0,   0,   110, 0,   0,   0,   0,   0,   0,   0,   11,  0,
+    0,   0,   98,  0,   0,   0,   1,   0,   0,   32,  2,   0,   0,   0,   1,   0,   0,   32,  3,
+    0,   0,   0,   2,   0,   0,   16,  1,   0,   0,   0,   3,   0,   0,   48,  0,   1,   0,   0,
+    200, 0,   0,   80,  3,   0,   0,   0,   0,   0,   0,   0,   244, 1,   0,   112, 1,   246, 1,
+    0,   112, 1,   189, 2,   0,   96,  144, 178, 236, 250, 255, 255, 255, 255, 145, 1,   0,   96,
+    144, 226, 33,  60,  222, 2,   0,   0,   189, 2,   0,   96,  0,   0,   0,   0,   0,   0,   0,
+    0,   190, 2,   0,   16,  1,   0,   0,   0,
+};
+
+/*
+ * These tests don't have any assertions or expectations. They just try to parse garbage, to see if
+ * the result will be a crash.  This is especially informative when run under Valgrind memcheck.
+ */
+
+template <typename Message> void parse_garbage() {
+    for (int32_t ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
+        Message msg(ver);
+        const uint8_t* end = msgbuf + array_length(msgbuf);
+        for (size_t i = 0; i < array_length(msgbuf); ++i) {
+            const uint8_t* begin = msgbuf + i;
+            const uint8_t* p = begin;
+            msg.Deserialize(&p, end);
+        }
+    }
+
+    time_t now = time(NULL);
+    std::cout << "Seeding rand() with " << now << " for fuzz test." << std::endl;
+    srand(now);
+
+    // Fill large buffer with random bytes.
+    const int kBufSize = 10000;
+    UniquePtr<uint8_t[]> buf(new uint8_t[kBufSize]);
+    for (size_t i = 0; i < kBufSize; ++i)
+        buf[i] = static_cast<uint8_t>(rand());
+
+    for (uint32_t ver = 0; ver < MAX_MESSAGE_VERSION; ++ver) {
+        Message msg(ver);
+        const uint8_t* end = buf.get() + kBufSize;
+        for (size_t i = 0; i < kBufSize; ++i) {
+            const uint8_t* begin = buf.get() + i;
+            const uint8_t* p = begin;
+            msg.Deserialize(&p, end);
+        }
+    }
+}
+
+#define GARBAGE_TEST(Message)                                                                      \
+    TEST(GarbageTest, Message) { parse_garbage<Message>(); }
+
+GARBAGE_TEST(AbortOperationRequest);
+GARBAGE_TEST(AbortOperationResponse);
+GARBAGE_TEST(AddEntropyRequest);
+GARBAGE_TEST(AddEntropyResponse);
+GARBAGE_TEST(BeginOperationRequest);
+GARBAGE_TEST(BeginOperationResponse);
+GARBAGE_TEST(DeleteAllKeysRequest);
+GARBAGE_TEST(DeleteAllKeysResponse);
+GARBAGE_TEST(DeleteKeyRequest);
+GARBAGE_TEST(DeleteKeyResponse);
+GARBAGE_TEST(ExportKeyRequest);
+GARBAGE_TEST(ExportKeyResponse);
+GARBAGE_TEST(FinishOperationRequest);
+GARBAGE_TEST(FinishOperationResponse);
+GARBAGE_TEST(GenerateKeyRequest);
+GARBAGE_TEST(GenerateKeyResponse);
+GARBAGE_TEST(GetKeyCharacteristicsRequest);
+GARBAGE_TEST(GetKeyCharacteristicsResponse);
+GARBAGE_TEST(ImportKeyRequest);
+GARBAGE_TEST(ImportKeyResponse);
+GARBAGE_TEST(SupportedByAlgorithmAndPurposeRequest)
+GARBAGE_TEST(SupportedByAlgorithmRequest)
+GARBAGE_TEST(UpdateOperationRequest);
+GARBAGE_TEST(UpdateOperationResponse);
+GARBAGE_TEST(AttestKeyRequest);
+GARBAGE_TEST(AttestKeyResponse);
+
+// The macro doesn't work on this one.
+TEST(GarbageTest, SupportedResponse) {
+    parse_garbage<SupportedResponse<keymaster_digest_t>>();
+}
+
+}  // namespace test
+
+}  // namespace keymaster
diff --git a/keymaster/android_keymaster_test.cpp b/keymaster/android_keymaster_test.cpp
new file mode 100644
index 0000000..ddc9783
--- /dev/null
+++ b/keymaster/android_keymaster_test.cpp
@@ -0,0 +1,3599 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#include <hardware/keymaster0.h>
+#include <keymaster/key_factory.h>
+#include <keymaster/soft_keymaster_context.h>
+#include <keymaster/soft_keymaster_device.h>
+#include <keymaster/softkeymaster.h>
+
+#include "android_keymaster_test_utils.h"
+#include "attestation_record.h"
+#include "keymaster0_engine.h"
+#include "openssl_utils.h"
+
+using std::ifstream;
+using std::istreambuf_iterator;
+using std::ofstream;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+extern "C" {
+int __android_log_print(int prio, const char* tag, const char* fmt);
+int __android_log_print(int prio, const char* tag, const char* fmt) {
+    (void)prio, (void)tag, (void)fmt;
+    return 0;
+}
+}  // extern "C"
+
+namespace keymaster {
+namespace test {
+
+StdoutLogger logger;
+
+template <typename T> vector<T> make_vector(const T* array, size_t len) {
+    return vector<T>(array, array + len);
+}
+
+/**
+ * KeymasterEnforcement class for use in testing.  It's permissive in the sense that it doesn't
+ * check cryptoperiods, but restrictive in the sense that the clock never advances (so rate-limited
+ * keys will only work once).
+ */
+class TestKeymasterEnforcement : public KeymasterEnforcement {
+  public:
+    TestKeymasterEnforcement() : KeymasterEnforcement(3, 3) {}
+
+    virtual bool activation_date_valid(uint64_t /* activation_date */) const { return true; }
+    virtual bool expiration_date_passed(uint64_t /* expiration_date */) const { return false; }
+    virtual bool auth_token_timed_out(const hw_auth_token_t& /* token */,
+                                      uint32_t /* timeout */) const {
+        return false;
+    }
+    virtual uint32_t get_current_time() const { return 0; }
+    virtual bool ValidateTokenSignature(const hw_auth_token_t& /* token */) const { return true; }
+};
+
+/**
+ * Variant of SoftKeymasterContext that provides a TestKeymasterEnforcement.
+ */
+class TestKeymasterContext : public SoftKeymasterContext {
+  public:
+    TestKeymasterContext() {}
+    explicit TestKeymasterContext(const string& root_of_trust) : SoftKeymasterContext(root_of_trust) {}
+
+    KeymasterEnforcement* enforcement_policy() override { return &test_policy_; }
+
+  private:
+    TestKeymasterEnforcement test_policy_;
+};
+
+/**
+ * Test instance creator that builds a pure software keymaster1 implementations.
+ */
+class SoftKeymasterTestInstanceCreator : public Keymaster2TestInstanceCreator {
+  public:
+    keymaster2_device_t* CreateDevice() const override {
+        std::cerr << "Creating software-only device" << std::endl;
+        SoftKeymasterDevice* device = new SoftKeymasterDevice(new TestKeymasterContext);
+        return device->keymaster2_device();
+    }
+
+    bool algorithm_in_km0_hardware(keymaster_algorithm_t) const override { return false; }
+    int keymaster0_calls() const override { return 0; }
+};
+
+/**
+ * Test instance creator that builds keymaster1 instances which wrap a faked hardware keymaster0
+ * instance, with or without EC support.
+ */
+class Keymaster0AdapterTestInstanceCreator : public Keymaster2TestInstanceCreator {
+  public:
+    explicit Keymaster0AdapterTestInstanceCreator(bool support_ec) : support_ec_(support_ec) {}
+
+    keymaster2_device_t* CreateDevice() const {
+        std::cerr << "Creating keymaster0-backed device (with ec: " << std::boolalpha << support_ec_
+                  << ")." << std::endl;
+        hw_device_t* softkeymaster_device;
+        EXPECT_EQ(0, openssl_open(&softkeymaster_module.common, KEYSTORE_KEYMASTER,
+                                  &softkeymaster_device));
+        // Make the software device pretend to be hardware
+        keymaster0_device_t* keymaster0_device =
+            reinterpret_cast<keymaster0_device_t*>(softkeymaster_device);
+        keymaster0_device->flags &= ~KEYMASTER_SOFTWARE_ONLY;
+
+        if (!support_ec_) {
+            // Make the software device pretend not to support EC
+            keymaster0_device->flags &= ~KEYMASTER_SUPPORTS_EC;
+        }
+
+        counting_keymaster0_device_ = new Keymaster0CountingWrapper(keymaster0_device);
+
+        SoftKeymasterDevice* keymaster = new SoftKeymasterDevice(new TestKeymasterContext);
+        keymaster->SetHardwareDevice(counting_keymaster0_device_);
+        return keymaster->keymaster2_device();
+    }
+
+    bool algorithm_in_km0_hardware(keymaster_algorithm_t algorithm) const override {
+        switch (algorithm) {
+        case KM_ALGORITHM_RSA:
+            return true;
+        case KM_ALGORITHM_EC:
+            return support_ec_;
+        default:
+            return false;
+        }
+    }
+    int keymaster0_calls() const override { return counting_keymaster0_device_->count(); }
+
+  private:
+    mutable Keymaster0CountingWrapper* counting_keymaster0_device_;
+    bool support_ec_;
+};
+
+/**
+ * Test instance creator that builds a SoftKeymasterDevice which wraps a fake hardware keymaster1
+ * instance, with minimal digest support.
+ */
+class Sha256OnlyKeymaster1TestInstanceCreator : public Keymaster2TestInstanceCreator {
+    keymaster2_device_t* CreateDevice() const {
+        std::cerr << "Creating keymaster1-backed device that supports only SHA256";
+
+        // fake_device doesn't leak because device (below) takes ownership of it.
+        keymaster1_device_t* fake_device = make_device_sha256_only(
+            (new SoftKeymasterDevice(new TestKeymasterContext("PseudoHW")))->keymaster_device());
+
+        // device doesn't leak; it's cleaned up by device->keymaster_device()->common.close().
+        SoftKeymasterDevice* device = new SoftKeymasterDevice(new TestKeymasterContext);
+        device->SetHardwareDevice(fake_device);
+
+        return device->keymaster2_device();
+    }
+
+    bool algorithm_in_km0_hardware(keymaster_algorithm_t) const override { return false; }
+    int keymaster0_calls() const override { return 0; }
+    int minimal_digest_set() const override { return true; }
+};
+
+static auto test_params = testing::Values(
+    InstanceCreatorPtr(new SoftKeymasterTestInstanceCreator),
+    InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(true /* support_ec */)),
+    InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(false /* support_ec */)),
+    InstanceCreatorPtr(new Sha256OnlyKeymaster1TestInstanceCreator));
+
+class NewKeyGeneration : public Keymaster2Test {
+  protected:
+    void CheckBaseParams() {
+        AuthorizationSet auths = sw_enforced();
+        EXPECT_GT(auths.SerializedSize(), 12U);
+
+        EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
+        EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
+        EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
+        EXPECT_TRUE(contains(auths, TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
+        EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
+
+        // Verify that App ID, App data and ROT are NOT included.
+        EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
+        EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
+        EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
+
+        // Just for giggles, check that some unexpected tags/values are NOT present.
+        EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
+        EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
+        EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
+
+        // Now check that unspecified, defaulted tags are correct.
+        EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
+    }
+};
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, NewKeyGeneration, test_params);
+
+TEST_P(NewKeyGeneration, Rsa) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    CheckBaseParams();
+
+    // Check specified tags are all present, and in the right set.
+    AuthorizationSet crypto_params;
+    AuthorizationSet non_crypto_params;
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA)) {
+        EXPECT_NE(0U, hw_enforced().size());
+        EXPECT_NE(0U, sw_enforced().size());
+        crypto_params.push_back(hw_enforced());
+        non_crypto_params.push_back(sw_enforced());
+    } else {
+        EXPECT_EQ(0U, hw_enforced().size());
+        EXPECT_NE(0U, sw_enforced().size());
+        crypto_params.push_back(sw_enforced());
+    }
+
+    EXPECT_TRUE(contains(crypto_params, TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_FALSE(contains(non_crypto_params, TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_TRUE(contains(crypto_params, TAG_KEY_SIZE, 256));
+    EXPECT_FALSE(contains(non_crypto_params, TAG_KEY_SIZE, 256));
+    EXPECT_TRUE(contains(crypto_params, TAG_RSA_PUBLIC_EXPONENT, 3));
+    EXPECT_FALSE(contains(non_crypto_params, TAG_RSA_PUBLIC_EXPONENT, 3));
+
+    EXPECT_EQ(KM_ERROR_OK, DeleteKey());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, RsaDefaultSize) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
+              GenerateKey(AuthorizationSetBuilder()
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                              .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)
+                              .SigningKey()));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, Ecdsa) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(KM_DIGEST_NONE)));
+    CheckBaseParams();
+
+    // Check specified tags are all present, and in the right set.
+    AuthorizationSet crypto_params;
+    AuthorizationSet non_crypto_params;
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC)) {
+        EXPECT_NE(0U, hw_enforced().size());
+        EXPECT_NE(0U, sw_enforced().size());
+        crypto_params.push_back(hw_enforced());
+        non_crypto_params.push_back(sw_enforced());
+    } else {
+        EXPECT_EQ(0U, hw_enforced().size());
+        EXPECT_NE(0U, sw_enforced().size());
+        crypto_params.push_back(sw_enforced());
+    }
+
+    EXPECT_TRUE(contains(crypto_params, TAG_ALGORITHM, KM_ALGORITHM_EC));
+    EXPECT_FALSE(contains(non_crypto_params, TAG_ALGORITHM, KM_ALGORITHM_EC));
+    EXPECT_TRUE(contains(crypto_params, TAG_KEY_SIZE, 224));
+    EXPECT_FALSE(contains(non_crypto_params, TAG_KEY_SIZE, 224));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(1, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, EcdsaDefaultSize) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
+              GenerateKey(AuthorizationSetBuilder()
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC)
+                              .SigningKey()
+                              .Digest(KM_DIGEST_NONE)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, EcdsaInvalidSize) {
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        ASSERT_EQ(
+            KM_ERROR_UNKNOWN_ERROR,
+            GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(190).Digest(KM_DIGEST_NONE)));
+    else
+        ASSERT_EQ(
+            KM_ERROR_UNSUPPORTED_KEY_SIZE,
+            GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(190).Digest(KM_DIGEST_NONE)));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(1, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, EcdsaAllValidSizes) {
+    size_t valid_sizes[] = {224, 256, 384, 521};
+    for (size_t size : valid_sizes) {
+        EXPECT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(size).Digest(
+                                   KM_DIGEST_NONE)))
+            << "Failed to generate size: " << size;
+    }
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, HmacSha256) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 256)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, HmacMultipleDigests) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
+              GenerateKey(AuthorizationSetBuilder()
+                              .HmacKey(128)
+                              .Digest(KM_DIGEST_SHA1)
+                              .Digest(KM_DIGEST_SHA_2_256)
+                              .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, HmacDigestNone) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
+              GenerateKey(AuthorizationSetBuilder()
+                              .HmacKey(128)
+                              .Digest(KM_DIGEST_NONE)
+                              .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, HmacSha256TooShortMacLength) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH,
+              GenerateKey(AuthorizationSetBuilder()
+                              .HmacKey(128)
+                              .Digest(KM_DIGEST_SHA_2_256)
+                              .Authorization(TAG_MIN_MAC_LENGTH, 48)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, HmacSha256NonIntegralOctetMacLength) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH,
+              GenerateKey(AuthorizationSetBuilder()
+                              .HmacKey(128)
+                              .Digest(KM_DIGEST_SHA_2_256)
+                              .Authorization(TAG_MIN_MAC_LENGTH, 130)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(NewKeyGeneration, HmacSha256TooLongMacLength) {
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH,
+              GenerateKey(AuthorizationSetBuilder()
+                              .HmacKey(128)
+                              .Digest(KM_DIGEST_SHA_2_256)
+                              .Authorization(TAG_MIN_MAC_LENGTH, 384)));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test GetKeyCharacteristics;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, GetKeyCharacteristics, test_params);
+
+TEST_P(GetKeyCharacteristics, SimpleRsa) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    AuthorizationSet original(sw_enforced());
+
+    ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
+    EXPECT_EQ(original, sw_enforced());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(1, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test SigningOperationsTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, SigningOperationsTest, test_params);
+
+TEST_P(SigningOperationsTest, RsaSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaPssSha256Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_RSA_PSS)));
+    // Use large message, which won't work without digesting.
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaPkcs1Sha256Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaPkcs1NoDigestSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+    string message(53, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaPkcs1NoDigestTooLarge) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+    string message(54, 'a');
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    string signature;
+    EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&signature));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaPssSha256TooSmallKey) {
+    // Key must be at least 10 bytes larger than hash, to provide eight bytes of random salt, so
+    // verify that nine bytes larger than hash won't work.
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256 + 9 * 8, 3)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_RSA_PSS)));
+    string message(1024, 'a');
+    string signature;
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PSS);
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+}
+
+TEST_P(SigningOperationsTest, RsaNoPaddingHugeData) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+    string message(64 * 1024, 'a');
+    string signature;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, UpdateOperation(message, &result, &input_consumed));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaAbort) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, AbortOperation());
+    // Another abort should fail
+    EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaUnsupportedPadding) {
+    GenerateKey(AuthorizationSetBuilder()
+                    .RsaSigningKey(256, 3)
+                    .Digest(KM_DIGEST_SHA_2_256 /* supported digest */)
+                    .Padding(KM_PAD_PKCS7));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaNoDigest) {
+    // PSS requires a digest.
+    GenerateKey(AuthorizationSetBuilder()
+                    .RsaSigningKey(256, 3)
+                    .Digest(KM_DIGEST_NONE)
+                    .Padding(KM_PAD_RSA_PSS));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PSS);
+    ASSERT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaNoPadding) {
+    // Padding must be specified
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaKey(256, 3).SigningKey().Digest(
+                               KM_DIGEST_NONE)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaTooShortMessage) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string message = "1234567890123456789012345678901";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaSignWithEncryptionKey) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, RsaSignTooLargeMessage) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string message(256 / 8, static_cast<char>(0xff));
+    string signature;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+    string result;
+    size_t input_consumed;
+    ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    ASSERT_EQ(message.size(), input_consumed);
+    string output;
+    ASSERT_EQ(KM_ERROR_INVALID_ARGUMENT, FinishOperation(&output));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, EcdsaSuccess) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(KM_DIGEST_NONE)));
+    string message(224 / 8, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, EcdsaSha256Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(
+                               KM_DIGEST_SHA_2_256)));
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, EcdsaSha384Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(
+                               KM_DIGEST_SHA_2_384)));
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_384);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, EcdsaNoPaddingHugeData) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(KM_DIGEST_NONE)));
+    string message(64 * 1024, 'a');
+    string signature;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params));
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, EcdsaAllSizesAndHashes) {
+    vector<int> key_sizes = {224, 256, 384, 521};
+    vector<keymaster_digest_t> digests = {
+        KM_DIGEST_SHA1,      KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256,
+        KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+    };
+
+    for (int key_size : key_sizes) {
+        for (keymaster_digest_t digest : digests) {
+            ASSERT_EQ(
+                KM_ERROR_OK,
+                GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(key_size).Digest(digest)));
+
+            string message(1024, 'a');
+            string signature;
+            if (digest == KM_DIGEST_NONE)
+                message.resize(key_size / 8);
+            SignMessage(message, &signature, digest);
+        }
+    }
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(digests.size() * key_sizes.size() * 3,
+                  static_cast<size_t>(GetParam()->keymaster0_calls()));
+}
+
+TEST_P(SigningOperationsTest, AesEcbSign) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().AesEncryptionKey(128).Authorization(
+                  TAG_BLOCK_MODE, KM_MODE_ECB)));
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_SIGN));
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_VERIFY));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha1Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate other digests for HMAC.
+        return;
+
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA1)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 160));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    MacMessage(message, &signature, 160);
+    ASSERT_EQ(20U, signature.size());
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha224Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate other digests for HMAC.
+        return;
+
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_224)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 160)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    MacMessage(message, &signature, 224);
+    ASSERT_EQ(28U, signature.size());
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha256Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate other digests for HMAC.
+        return;
+
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 256)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    MacMessage(message, &signature, 256);
+    ASSERT_EQ(32U, signature.size());
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha384Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate other digests for HMAC.
+        return;
+
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_384)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 384)));
+
+    string message = "12345678901234567890123456789012";
+    string signature;
+    MacMessage(message, &signature, 384);
+    ASSERT_EQ(48U, signature.size());
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha512Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate other digests for HMAC.
+        return;
+
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_512)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 384)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    MacMessage(message, &signature, 512);
+    ASSERT_EQ(64U, signature.size());
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacLengthInKey) {
+    // TODO(swillden): unified API should generate an error on key generation.
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    MacMessage(message, &signature, 160);
+    ASSERT_EQ(20U, signature.size());
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase1) {
+    uint8_t key_data[] = {
+        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+    };
+    string message = "Hi There";
+    uint8_t sha_224_expected[] = {
+        0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19, 0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d,
+        0xf3, 0x3f, 0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f, 0x53, 0x68, 0x4b, 0x22,
+    };
+    uint8_t sha_256_expected[] = {
+        0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf,
+        0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83,
+        0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7,
+    };
+    uint8_t sha_384_expected[] = {
+        0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, 0x6b, 0x08, 0x25, 0xf4,
+        0xab, 0x46, 0x90, 0x7f, 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
+        0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c, 0xfa, 0xea, 0x9e, 0xa9,
+        0x07, 0x6e, 0xde, 0x7f, 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6,
+    };
+    uint8_t sha_512_expected[] = {
+        0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, 0x4f, 0xf0, 0xb4, 0x24, 0x1a,
+        0x1d, 0x6c, 0xb0, 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, 0x7a, 0xd0,
+        0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde, 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7,
+        0x02, 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, 0xbe, 0x9d, 0x91, 0x4e,
+        0xeb, 0x61, 0xf1, 0x70, 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54,
+    };
+
+    string key = make_string(key_data);
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase2) {
+    string key = "Jefe";
+    string message = "what do ya want for nothing?";
+    uint8_t sha_224_expected[] = {
+        0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf, 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e,
+        0x6d, 0x0f, 0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00, 0x8f, 0xd0, 0x5e, 0x44,
+    };
+    uint8_t sha_256_expected[] = {
+        0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24,
+        0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27,
+        0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43,
+    };
+    uint8_t sha_384_expected[] = {
+        0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, 0x61, 0x7f, 0x78, 0xd2,
+        0xb5, 0x8a, 0x6b, 0x1b, 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
+        0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e, 0x8e, 0x22, 0x40, 0xca,
+        0x5e, 0x69, 0xe2, 0xc7, 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49,
+    };
+    uint8_t sha_512_expected[] = {
+        0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95, 0xfb, 0xe7, 0x3b,
+        0x56, 0xe0, 0xa3, 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, 0x10, 0x27,
+        0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54, 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99,
+        0x4a, 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, 0xca, 0xea, 0xb1, 0xa3,
+        0x4d, 0x4a, 0x6b, 0x4b, 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37,
+    };
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase3) {
+    string key(20, 0xaa);
+    string message(50, 0xdd);
+    uint8_t sha_224_expected[] = {
+        0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6, 0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a,
+        0xd2, 0x64, 0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1, 0xec, 0x83, 0x33, 0xea,
+    };
+    uint8_t sha_256_expected[] = {
+        0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8,
+        0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8,
+        0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe,
+    };
+    uint8_t sha_384_expected[] = {
+        0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, 0x0a, 0xa2, 0xac, 0xe0,
+        0x14, 0xc8, 0xa8, 0x6f, 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
+        0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b, 0x2a, 0x5a, 0xb3, 0x9d,
+        0xc1, 0x38, 0x14, 0xb9, 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27,
+    };
+    uint8_t sha_512_expected[] = {
+        0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, 0xef, 0xb0, 0xf0, 0x75, 0x6c,
+        0x89, 0x0b, 0xe9, 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36, 0x55, 0xf8,
+        0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39, 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22,
+        0xc8, 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07, 0xb9, 0x46, 0xa3, 0x37,
+        0xbe, 0xe8, 0x94, 0x26, 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb,
+    };
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase4) {
+    uint8_t key_data[25] = {
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+        0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+    };
+    string key = make_string(key_data);
+    string message(50, 0xcd);
+    uint8_t sha_224_expected[] = {
+        0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac, 0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82,
+        0x62, 0x7c, 0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d, 0xe7, 0xaf, 0xec, 0x5a,
+    };
+    uint8_t sha_256_expected[] = {
+        0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81,
+        0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78,
+        0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b,
+    };
+    uint8_t sha_384_expected[] = {
+        0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85, 0x19, 0x33, 0xab, 0x62,
+        0x90, 0xaf, 0x6c, 0xa7, 0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
+        0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e, 0x68, 0x01, 0xdd, 0x23,
+        0xc4, 0xa7, 0xd6, 0x79, 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb,
+    };
+    uint8_t sha_512_expected[] = {
+        0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69, 0x90, 0xe5, 0xa8, 0xc5, 0xf6,
+        0x1d, 0x4a, 0xf7, 0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d, 0xe7, 0x6f,
+        0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb, 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e,
+        0xb4, 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63, 0xa5, 0xf1, 0x97, 0x41,
+        0x12, 0x0c, 0x4f, 0x2d, 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd,
+    };
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase5) {
+    string key(20, 0x0c);
+    string message = "Test With Truncation";
+
+    uint8_t sha_224_expected[] = {
+        0x0e, 0x2a, 0xea, 0x68, 0xa9, 0x0c, 0x8d, 0x37,
+        0xc9, 0x88, 0xbc, 0xdb, 0x9f, 0xca, 0x6f, 0xa8,
+    };
+    uint8_t sha_256_expected[] = {
+        0xa3, 0xb6, 0x16, 0x74, 0x73, 0x10, 0x0e, 0xe0,
+        0x6e, 0x0c, 0x79, 0x6c, 0x29, 0x55, 0x55, 0x2b,
+    };
+    uint8_t sha_384_expected[] = {
+        0x3a, 0xbf, 0x34, 0xc3, 0x50, 0x3b, 0x2a, 0x23,
+        0xa4, 0x6e, 0xfc, 0x61, 0x9b, 0xae, 0xf8, 0x97,
+    };
+    uint8_t sha_512_expected[] = {
+        0x41, 0x5f, 0xad, 0x62, 0x71, 0x58, 0x0a, 0x53,
+        0x1d, 0x41, 0x79, 0xbc, 0x89, 0x1d, 0x87, 0xa6,
+    };
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase6) {
+    string key(131, 0xaa);
+    string message = "Test Using Larger Than Block-Size Key - Hash Key First";
+
+    uint8_t sha_224_expected[] = {
+        0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad, 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d,
+        0xbc, 0xe2, 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27, 0x3f, 0xa6, 0x87, 0x0e,
+    };
+    uint8_t sha_256_expected[] = {
+        0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26,
+        0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28,
+        0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54,
+    };
+    uint8_t sha_384_expected[] = {
+        0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, 0x88, 0xd2, 0xc6, 0x3a,
+        0x04, 0x1b, 0xc5, 0xb4, 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
+        0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6, 0x0c, 0x2e, 0xf6, 0xab,
+        0x40, 0x30, 0xfe, 0x82, 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52,
+    };
+    uint8_t sha_512_expected[] = {
+        0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, 0xb7, 0x14, 0x93, 0xc1, 0xdd,
+        0x7b, 0xe8, 0xb4, 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, 0x12, 0x1b,
+        0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52, 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25,
+        0x98, 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, 0x95, 0xe6, 0x4f, 0x73,
+        0xf6, 0x3f, 0x0a, 0xec, 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98,
+    };
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacRfc4231TestCase7) {
+    string key(131, 0xaa);
+    string message = "This is a test using a larger than block-size key and a larger than "
+                     "block-size data. The key needs to be hashed before being used by the HMAC "
+                     "algorithm.";
+
+    uint8_t sha_224_expected[] = {
+        0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02, 0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3,
+        0x9d, 0xbd, 0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9, 0xf6, 0xf5, 0x65, 0xd1,
+    };
+    uint8_t sha_256_expected[] = {
+        0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f,
+        0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07,
+        0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2,
+    };
+    uint8_t sha_384_expected[] = {
+        0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, 0x35, 0x1e, 0x2f, 0x25,
+        0x4e, 0x8f, 0xd3, 0x2c, 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
+        0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5, 0xa6, 0x78, 0xcc, 0x31,
+        0xe7, 0x99, 0x17, 0x6d, 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e,
+    };
+    uint8_t sha_512_expected[] = {
+        0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, 0xa4, 0xdf, 0xa9, 0xf9, 0x6e,
+        0x5e, 0x3f, 0xfd, 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86, 0x5d, 0xf5,
+        0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44, 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82,
+        0xb1, 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, 0x13, 0x46, 0x76, 0xfb,
+        0x6d, 0xe0, 0x44, 0x60, 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58,
+    };
+
+    CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_256, make_string(sha_256_expected));
+    if (!GetParam()->minimal_digest_set()) {
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_224, make_string(sha_224_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_384, make_string(sha_384_expected));
+        CheckHmacTestVector(key, message, KM_DIGEST_SHA_2_512, make_string(sha_512_expected));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha256TooLargeMacLength) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 256)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_MAC_LENGTH, 264);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH,
+              BeginOperation(KM_PURPOSE_SIGN, begin_params, nullptr /* output_params */));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(SigningOperationsTest, HmacSha256TooSmallMacLength) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_MAC_LENGTH, 120);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    ASSERT_EQ(KM_ERROR_INVALID_MAC_LENGTH,
+              BeginOperation(KM_PURPOSE_SIGN, begin_params, nullptr /* output_params */));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+// TODO(swillden): Add more verification failure tests.
+
+typedef Keymaster2Test VerificationOperationsTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, VerificationOperationsTest, test_params);
+
+TEST_P(VerificationOperationsTest, RsaSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaPssSha256Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_RSA_PSS)));
+    // Use large message, which won't work without digesting.
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
+    VerifyMessage(message, signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaPssSha224Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_224)
+                                           .Padding(KM_PAD_RSA_PSS)));
+    // Use large message, which won't work without digesting.
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PSS);
+    VerifyMessage(message, signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PSS);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+    // Verify with OpenSSL.
+    string pubkey;
+    EXPECT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &pubkey));
+
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(pubkey.data());
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        d2i_PUBKEY(nullptr /* alloc new */, &p, pubkey.size()));
+    ASSERT_TRUE(pkey.get());
+
+    EVP_MD_CTX digest_ctx;
+    EVP_MD_CTX_init(&digest_ctx);
+    EVP_PKEY_CTX* pkey_ctx;
+    EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, EVP_sha224(), nullptr /* engine */,
+                                      pkey.get()));
+    EXPECT_EQ(1, EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING));
+    EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), message.size()));
+    EXPECT_EQ(1,
+              EVP_DigestVerifyFinal(&digest_ctx, reinterpret_cast<const uint8_t*>(signature.data()),
+                                    signature.size()));
+    EVP_MD_CTX_cleanup(&digest_ctx);
+}
+
+TEST_P(VerificationOperationsTest, RsaPssSha256CorruptSignature) {
+    GenerateKey(AuthorizationSetBuilder()
+                    .RsaSigningKey(512, 3)
+                    .Digest(KM_DIGEST_SHA_2_256)
+                    .Padding(KM_PAD_RSA_PSS));
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
+    ++signature[signature.size() / 2];
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PSS);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaPssSha256CorruptInput) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_RSA_PSS)));
+    // Use large message, which won't work without digesting.
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS);
+    ++message[message.size() / 2];
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PSS);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaPkcs1Sha256Success) {
+    GenerateKey(AuthorizationSetBuilder()
+                    .RsaSigningKey(512, 3)
+                    .Digest(KM_DIGEST_SHA_2_256)
+                    .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN));
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    VerifyMessage(message, signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaPks1Sha224Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_224)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+    // Use large message, which won't work without digesting.
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    VerifyMessage(message, signature, KM_DIGEST_SHA_2_224, KM_PAD_RSA_PKCS1_1_5_SIGN);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+    // Verify with OpenSSL.
+    string pubkey;
+    EXPECT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &pubkey));
+
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(pubkey.data());
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        d2i_PUBKEY(nullptr /* alloc new */, &p, pubkey.size()));
+    ASSERT_TRUE(pkey.get());
+
+    EVP_MD_CTX digest_ctx;
+    EVP_MD_CTX_init(&digest_ctx);
+    EVP_PKEY_CTX* pkey_ctx;
+    EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, EVP_sha224(), nullptr /* engine */,
+                                      pkey.get()));
+    EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), message.size()));
+    EXPECT_EQ(1,
+              EVP_DigestVerifyFinal(&digest_ctx, reinterpret_cast<const uint8_t*>(signature.data()),
+                                    signature.size()));
+    EVP_MD_CTX_cleanup(&digest_ctx);
+}
+
+TEST_P(VerificationOperationsTest, RsaPkcs1Sha256CorruptSignature) {
+    GenerateKey(AuthorizationSetBuilder()
+                    .RsaSigningKey(512, 3)
+                    .Digest(KM_DIGEST_SHA_2_256)
+                    .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN));
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    ++signature[signature.size() / 2];
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaPkcs1Sha256CorruptInput) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(512, 3)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)));
+    // Use large message, which won't work without digesting.
+    string message(1024, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    ++message[message.size() / 2];
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, RsaAllDigestAndPadCombinations) {
+    vector<keymaster_digest_t> digests = {
+        KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,      KM_DIGEST_SHA_2_224,
+        KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+    };
+
+    vector<keymaster_padding_t> padding_modes{
+        KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN, KM_PAD_RSA_PSS,
+    };
+
+    int trial_count = 0;
+    for (keymaster_padding_t padding_mode : padding_modes) {
+        for (keymaster_digest_t digest : digests) {
+            if (digest != KM_DIGEST_NONE && padding_mode == KM_PAD_NONE)
+                // Digesting requires padding
+                continue;
+
+            // Compute key & message size that will work.
+            size_t key_bits = 0;
+            size_t message_len = 1000;
+
+            if (digest == KM_DIGEST_NONE) {
+                key_bits = 256;
+                switch (padding_mode) {
+                case KM_PAD_NONE:
+                    // Match key size.
+                    message_len = key_bits / 8;
+                    break;
+                case KM_PAD_RSA_PKCS1_1_5_SIGN:
+                    message_len = key_bits / 8 - 11;
+                    break;
+                case KM_PAD_RSA_PSS:
+                    // PSS requires a digest.
+                    continue;
+                default:
+                    FAIL() << "Missing padding";
+                    break;
+                }
+            } else {
+                size_t digest_bits;
+                switch (digest) {
+                case KM_DIGEST_MD5:
+                    digest_bits = 128;
+                    break;
+                case KM_DIGEST_SHA1:
+                    digest_bits = 160;
+                    break;
+                case KM_DIGEST_SHA_2_224:
+                    digest_bits = 224;
+                    break;
+                case KM_DIGEST_SHA_2_256:
+                    digest_bits = 256;
+                    break;
+                case KM_DIGEST_SHA_2_384:
+                    digest_bits = 384;
+                    break;
+                case KM_DIGEST_SHA_2_512:
+                    digest_bits = 512;
+                    break;
+                default:
+                    FAIL() << "Missing digest";
+                }
+
+                switch (padding_mode) {
+                case KM_PAD_RSA_PKCS1_1_5_SIGN:
+                    key_bits = digest_bits + 8 * (11 + 19);
+                    break;
+                case KM_PAD_RSA_PSS:
+                    key_bits = digest_bits + 22 * 8;
+                    break;
+                default:
+                    FAIL() << "Missing padding";
+                    break;
+                }
+            }
+
+            GenerateKey(AuthorizationSetBuilder()
+                            .RsaSigningKey(key_bits, 3)
+                            .Digest(digest)
+                            .Padding(padding_mode));
+            string message(message_len, 'a');
+            string signature;
+            SignMessage(message, &signature, digest, padding_mode);
+            VerifyMessage(message, signature, digest, padding_mode);
+            ++trial_count;
+        }
+    }
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(trial_count * 4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, EcdsaSuccess) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(KM_DIGEST_NONE)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, EcdsaTooShort) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(KM_DIGEST_NONE)));
+    string message = "12345678901234567890";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, EcdsaSlightlyTooLong) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(521).Digest(KM_DIGEST_NONE)));
+
+    string message(66, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE);
+
+    // Modifying low-order bits doesn't matter, because they didn't get signed.  Ugh.
+    message[65] ^= 7;
+    VerifyMessage(message, signature, KM_DIGEST_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(5, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, EcdsaSha256Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .EcdsaSigningKey(256)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Digest(KM_DIGEST_NONE)));
+    string message = "12345678901234567890123456789012";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_256);
+    VerifyMessage(message, signature, KM_DIGEST_SHA_2_256);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+    // Just for giggles, try verifying with the wrong digest.
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+}
+
+TEST_P(VerificationOperationsTest, EcdsaSha224Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(
+                               KM_DIGEST_SHA_2_224)));
+
+    string message = "12345678901234567890123456789012";
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_SHA_2_224);
+    VerifyMessage(message, signature, KM_DIGEST_SHA_2_224);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+
+    // Just for giggles, try verifying with the wrong digest.
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
+}
+
+TEST_P(VerificationOperationsTest, EcdsaAllDigestsAndKeySizes) {
+    keymaster_digest_t digests[] = {
+        KM_DIGEST_SHA1,      KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256,
+        KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+    };
+    size_t key_sizes[] = {224, 256, 384, 521};
+
+    string message = "1234567890";
+    string signature;
+
+    for (auto key_size : key_sizes) {
+        AuthorizationSetBuilder builder;
+        builder.EcdsaSigningKey(key_size);
+        for (auto digest : digests)
+            builder.Digest(digest);
+        ASSERT_EQ(KM_ERROR_OK, GenerateKey(builder));
+
+        for (auto digest : digests) {
+            SignMessage(message, &signature, digest);
+            VerifyMessage(message, signature, digest);
+        }
+    }
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(static_cast<int>(array_length(key_sizes) * (1 + 3 * array_length(digests))),
+                  GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, HmacSha1Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate missing digests for HMAC.
+        return;
+
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA1)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 128));
+    string message = "123456789012345678901234567890123456789012345678";
+    string signature;
+    MacMessage(message, &signature, 160);
+    VerifyMac(message, signature);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, HmacSha224Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate missing digests for HMAC.
+        return;
+
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA_2_224)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 128));
+    string message = "123456789012345678901234567890123456789012345678";
+    string signature;
+    MacMessage(message, &signature, 224);
+    VerifyMac(message, signature);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, HmacSha256Success) {
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA_2_256)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 128));
+    string message = "123456789012345678901234567890123456789012345678";
+    string signature;
+    MacMessage(message, &signature, 256);
+    VerifyMac(message, signature);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, HmacSha256TooShortMac) {
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA_2_256)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 128));
+    string message = "123456789012345678901234567890123456789012345678";
+    string signature;
+    MacMessage(message, &signature, 256);
+
+    // Shorten to 128 bits, should still work.
+    signature.resize(128 / 8);
+    VerifyMac(message, signature);
+
+    // Drop one more byte.
+    signature.resize(signature.length() - 1);
+
+    AuthorizationSet begin_params(client_params());
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, begin_params));
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_INVALID_MAC_LENGTH, FinishOperation(signature, &result));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, HmacSha384Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate missing digests for HMAC.
+        return;
+
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA_2_384)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 128));
+    string message = "123456789012345678901234567890123456789012345678";
+    string signature;
+    MacMessage(message, &signature, 384);
+    VerifyMac(message, signature);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(VerificationOperationsTest, HmacSha512Success) {
+    if (GetParam()->minimal_digest_set())
+        // Can't emulate missing digests for HMAC.
+        return;
+
+    GenerateKey(AuthorizationSetBuilder()
+                    .HmacKey(128)
+                    .Digest(KM_DIGEST_SHA_2_512)
+                    .Authorization(TAG_MIN_MAC_LENGTH, 128));
+    string message = "123456789012345678901234567890123456789012345678";
+    string signature;
+    MacMessage(message, &signature, 512);
+    VerifyMac(message, signature);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test ExportKeyTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, ExportKeyTest, test_params);
+
+TEST_P(ExportKeyTest, RsaSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string export_data;
+    ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
+    EXPECT_GT(export_data.length(), 0U);
+
+    // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ExportKeyTest, EcdsaSuccess) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(KM_DIGEST_NONE)));
+    string export_data;
+    ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
+    EXPECT_GT(export_data.length(), 0U);
+
+    // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ExportKeyTest, RsaUnsupportedKeyFormat) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    string export_data;
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ExportKeyTest, RsaCorruptedKeyBlob) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+    corrupt_key_blob();
+    string export_data;
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ExportKeyTest, AesKeyExportFails) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().AesEncryptionKey(128)));
+    string export_data;
+
+    EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_X509, &export_data));
+    EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
+    EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_RAW, &export_data));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+static string read_file(const string& file_name) {
+    ifstream file_stream(file_name, std::ios::binary);
+    istreambuf_iterator<char> file_begin(file_stream);
+    istreambuf_iterator<char> file_end;
+    return string(file_begin, file_end);
+}
+
+typedef Keymaster2Test ImportKeyTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, ImportKeyTest, test_params);
+
+TEST_P(ImportKeyTest, RsaSuccess) {
+    string pk8_key = read_file("rsa_privkey_pk8.der");
+    ASSERT_EQ(633U, pk8_key.size());
+
+    ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
+                                         .RsaSigningKey(1024, 65537)
+                                         .Digest(KM_DIGEST_NONE)
+                                         .Padding(KM_PAD_NONE),
+                                     KM_KEY_FORMAT_PKCS8, pk8_key));
+
+    // Check values derived from the key.
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
+                                                                                 : sw_enforced(),
+                         TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
+                                                                                 : sw_enforced(),
+                         TAG_KEY_SIZE, 1024));
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA) ? hw_enforced()
+                                                                                 : sw_enforced(),
+                         TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+    // And values provided by AndroidKeymaster
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_TRUE(contains(hw_enforced(), TAG_ORIGIN, KM_ORIGIN_UNKNOWN));
+    else
+        EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
+    EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
+
+    string message(1024 / 8, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, RsaKeySizeMismatch) {
+    string pk8_key = read_file("rsa_privkey_pk8.der");
+    ASSERT_EQ(633U, pk8_key.size());
+    ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
+              ImportKey(AuthorizationSetBuilder()
+                            .RsaSigningKey(2048 /* Doesn't match key */, 3)
+                            .Digest(KM_DIGEST_NONE)
+                            .Padding(KM_PAD_NONE),
+                        KM_KEY_FORMAT_PKCS8, pk8_key));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, RsaPublicExponenMismatch) {
+    string pk8_key = read_file("rsa_privkey_pk8.der");
+    ASSERT_EQ(633U, pk8_key.size());
+    ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
+              ImportKey(AuthorizationSetBuilder()
+                            .RsaSigningKey(256, 3 /* Doesnt' match key */)
+                            .Digest(KM_DIGEST_NONE)
+                            .Padding(KM_PAD_NONE),
+                        KM_KEY_FORMAT_PKCS8, pk8_key));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, EcdsaSuccess) {
+    string pk8_key = read_file("ec_privkey_pk8.der");
+    ASSERT_EQ(138U, pk8_key.size());
+
+    ASSERT_EQ(KM_ERROR_OK,
+              ImportKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(KM_DIGEST_NONE),
+                        KM_KEY_FORMAT_PKCS8, pk8_key));
+
+    // Check values derived from the key.
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+                                                                                : sw_enforced(),
+                         TAG_ALGORITHM, KM_ALGORITHM_EC));
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+                                                                                : sw_enforced(),
+                         TAG_KEY_SIZE, 256));
+
+    // And values provided by AndroidKeymaster
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_TRUE(contains(hw_enforced(), TAG_ORIGIN, KM_ORIGIN_UNKNOWN));
+    else
+        EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
+    EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
+
+    string message(32, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, EcdsaSizeSpecified) {
+    string pk8_key = read_file("ec_privkey_pk8.der");
+    ASSERT_EQ(138U, pk8_key.size());
+
+    ASSERT_EQ(KM_ERROR_OK,
+              ImportKey(AuthorizationSetBuilder().EcdsaSigningKey(256).Digest(KM_DIGEST_NONE),
+                        KM_KEY_FORMAT_PKCS8, pk8_key));
+
+    // Check values derived from the key.
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+                                                                                : sw_enforced(),
+                         TAG_ALGORITHM, KM_ALGORITHM_EC));
+    EXPECT_TRUE(contains(GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC) ? hw_enforced()
+                                                                                : sw_enforced(),
+                         TAG_KEY_SIZE, 256));
+
+    // And values provided by AndroidKeymaster
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_TRUE(contains(hw_enforced(), TAG_ORIGIN, KM_ORIGIN_UNKNOWN));
+    else
+        EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
+    EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
+
+    string message(32, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, EcdsaSizeMismatch) {
+    string pk8_key = read_file("ec_privkey_pk8.der");
+    ASSERT_EQ(138U, pk8_key.size());
+    ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
+              ImportKey(AuthorizationSetBuilder()
+                            .EcdsaSigningKey(224 /* Doesn't match key */)
+                            .Digest(KM_DIGEST_NONE),
+                        KM_KEY_FORMAT_PKCS8, pk8_key));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, AesKeySuccess) {
+    char key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    string key(key_data, sizeof(key_data));
+    ASSERT_EQ(KM_ERROR_OK,
+              ImportKey(AuthorizationSetBuilder().AesEncryptionKey(128).EcbMode().Authorization(
+                            TAG_PADDING, KM_PAD_PKCS7),
+                        KM_KEY_FORMAT_RAW, key));
+
+    EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
+    EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
+
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(message, KM_MODE_ECB, KM_PAD_PKCS7);
+    string plaintext = DecryptMessage(ciphertext, KM_MODE_ECB, KM_PAD_PKCS7);
+    EXPECT_EQ(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(ImportKeyTest, HmacSha256KeySuccess) {
+    char key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    string key(key_data, sizeof(key_data));
+    ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
+                                         .HmacKey(sizeof(key_data) * 8)
+                                         .Digest(KM_DIGEST_SHA_2_256)
+                                         .Authorization(TAG_MIN_MAC_LENGTH, 256),
+                                     KM_KEY_FORMAT_RAW, key));
+
+    EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
+    EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
+
+    string message = "Hello World!";
+    string signature;
+    MacMessage(message, &signature, 256);
+    VerifyMac(message, signature);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test EncryptionOperationsTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, EncryptionOperationsTest, test_params);
+
+TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(256, 3).Padding(KM_PAD_NONE)));
+
+    string message = "12345678901234567890123456789012";
+    string ciphertext1 = EncryptMessage(string(message), KM_PAD_NONE);
+    EXPECT_EQ(256U / 8, ciphertext1.size());
+
+    string ciphertext2 = EncryptMessage(string(message), KM_PAD_NONE);
+    EXPECT_EQ(256U / 8, ciphertext2.size());
+
+    // Unpadded RSA is deterministic
+    EXPECT_EQ(ciphertext1, ciphertext2);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaNoPaddingTooShort) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(256, 3).Padding(KM_PAD_NONE)));
+
+    string message = "1";
+
+    string ciphertext = EncryptMessage(message, KM_PAD_NONE);
+    EXPECT_EQ(256U / 8, ciphertext.size());
+
+    string expected_plaintext = string(256 / 8 - 1, 0) + message;
+    string plaintext = DecryptMessage(ciphertext, KM_PAD_NONE);
+
+    EXPECT_EQ(expected_plaintext, plaintext);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLong) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(256, 3).Padding(KM_PAD_NONE)));
+
+    string message = "123456789012345678901234567890123";
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, UpdateOperation(message, &result, &input_consumed));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaNoPaddingLargerThanModulus) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(256, 3).Padding(KM_PAD_NONE)));
+
+    string exported;
+    ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &exported));
+
+    const uint8_t* p = reinterpret_cast<const uint8_t*>(exported.data());
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        d2i_PUBKEY(nullptr /* alloc new */, &p, exported.size()));
+    unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(pkey.get()));
+
+    size_t modulus_len = BN_num_bytes(rsa->n);
+    ASSERT_EQ(256U / 8, modulus_len);
+    unique_ptr<uint8_t[]> modulus_buf(new uint8_t[modulus_len]);
+    BN_bn2bin(rsa->n, modulus_buf.get());
+
+    // The modulus is too big to encrypt.
+    string message(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, FinishOperation(&result));
+
+    // One smaller than the modulus is okay.
+    BN_sub(rsa->n, rsa->n, BN_value_one());
+    modulus_len = BN_num_bytes(rsa->n);
+    ASSERT_EQ(256U / 8, modulus_len);
+    BN_bn2bin(rsa->n, modulus_buf.get());
+    message = string(reinterpret_cast<const char*>(modulus_buf.get()), modulus_len);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepSuccess) {
+    size_t key_size = 768;
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(key_size, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_256)));
+
+    string message = "Hello";
+    string ciphertext1 = EncryptMessage(string(message), KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext1.size());
+
+    string ciphertext2 = EncryptMessage(string(message), KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext2.size());
+
+    // OAEP randomizes padding so every result should be different.
+    EXPECT_NE(ciphertext1, ciphertext2);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepSha224Success) {
+    size_t key_size = 768;
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(key_size, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_224)));
+
+    string message = "Hello";
+    string ciphertext1 = EncryptMessage(string(message), KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext1.size());
+
+    string ciphertext2 = EncryptMessage(string(message), KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext2.size());
+
+    // OAEP randomizes padding so every result should be different.
+    EXPECT_NE(ciphertext1, ciphertext2);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepRoundTrip) {
+    size_t key_size = 768;
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(key_size, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_256)));
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(string(message), KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    string plaintext = DecryptMessage(ciphertext, KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(message, plaintext);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepSha224RoundTrip) {
+    size_t key_size = 768;
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(key_size, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_224)));
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(string(message), KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    string plaintext = DecryptMessage(ciphertext, KM_DIGEST_SHA_2_224, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(message, plaintext);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepInvalidDigest) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(512, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_NONE)));
+    string message = "Hello World!";
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepUnauthorizedDigest) {
+    if (GetParam()->minimal_digest_set())
+        // We don't have two supported digests, so we can't try authorizing one and using another.
+        return;
+
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(512, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_256)));
+    string message = "Hello World!";
+    // Works because encryption is a public key operation.
+    EncryptMessage(string(message), KM_DIGEST_SHA1, KM_PAD_RSA_OAEP);
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA1);
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
+    if (GetParam()->minimal_digest_set())
+        // We don't have two supported digests, so we can't try encrypting with one and decrypting
+        // with another.
+        return;
+
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(768, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Digest(KM_DIGEST_SHA_2_384)));
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(string(message), KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
+
+    string result;
+    size_t input_consumed;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
+    EXPECT_EQ(0U, result.size());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepTooLarge) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(512, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA1)));
+    string message = "12345678901234567890123";
+    string result;
+    size_t input_consumed;
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA1);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
+    EXPECT_EQ(0U, result.size());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
+    size_t key_size = 768;
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(768, 3)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_SHA_2_256)));
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(string(message), KM_DIGEST_SHA_2_256, KM_PAD_RSA_OAEP);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    // Corrupt the ciphertext
+    ciphertext[key_size / 8 / 2]++;
+
+    string result;
+    size_t input_consumed;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+    begin_params.push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
+    EXPECT_EQ(0U, result.size());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaPkcs1Success) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
+                               KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
+    string message = "Hello World!";
+    string ciphertext1 = EncryptMessage(message, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(512U / 8, ciphertext1.size());
+
+    string ciphertext2 = EncryptMessage(message, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(512U / 8, ciphertext2.size());
+
+    // PKCS1 v1.5 randomizes padding so every result should be different.
+    EXPECT_NE(ciphertext1, ciphertext2);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
+                               KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(message, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(512U / 8, ciphertext.size());
+
+    string plaintext = DecryptMessage(ciphertext, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(message, plaintext);
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaRoundTripAllCombinations) {
+    size_t key_size = 2048;
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaEncryptionKey(key_size, 3)
+                                           .Padding(KM_PAD_RSA_PKCS1_1_5_ENCRYPT)
+                                           .Padding(KM_PAD_RSA_OAEP)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Digest(KM_DIGEST_MD5)
+                                           .Digest(KM_DIGEST_SHA1)
+                                           .Digest(KM_DIGEST_SHA_2_224)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Digest(KM_DIGEST_SHA_2_384)
+                                           .Digest(KM_DIGEST_SHA_2_512)));
+
+    string message = "Hello World!";
+
+    keymaster_padding_t padding_modes[] = {KM_PAD_RSA_OAEP, KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
+    keymaster_digest_t digests[] = {
+        KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,      KM_DIGEST_SHA_2_224,
+        KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512,
+    };
+
+    for (auto padding : padding_modes)
+        for (auto digest : digests) {
+            if (padding == KM_PAD_RSA_OAEP && digest == KM_DIGEST_NONE)
+                // OAEP requires a digest.
+                continue;
+
+            string ciphertext = EncryptMessage(message, digest, padding);
+            EXPECT_EQ(key_size / 8, ciphertext.size());
+
+            string plaintext = DecryptMessage(ciphertext, digest, padding);
+            EXPECT_EQ(message, plaintext);
+        }
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(40, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaPkcs1TooLarge) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
+                               KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
+    string message = "123456789012345678901234567890123456789012345678901234";
+    string result;
+    size_t input_consumed;
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
+    EXPECT_EQ(0U, result.size());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().RsaEncryptionKey(512, 3).Padding(
+                               KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
+    string message = "Hello World!";
+    string ciphertext = EncryptMessage(string(message), KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(512U / 8, ciphertext.size());
+
+    // Corrupt the ciphertext
+    ciphertext[512 / 8 / 2]++;
+
+    string result;
+    size_t input_consumed;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
+    EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
+    EXPECT_EQ(0U, result.size());
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(4, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, RsaEncryptWithSigningKey) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().RsaSigningKey(256, 3).Padding(KM_PAD_NONE)));
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    ASSERT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA))
+        EXPECT_EQ(2, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, EcdsaEncrypt) {
+    ASSERT_EQ(KM_ERROR_OK,
+              GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(KM_DIGEST_NONE)));
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_ENCRYPT));
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_DECRYPT));
+
+    if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_EC))
+        EXPECT_EQ(3, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, HmacEncrypt) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .HmacKey(128)
+                                           .Digest(KM_DIGEST_SHA_2_256)
+                                           .Padding(KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_ENCRYPT));
+    ASSERT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE, BeginOperation(KM_PURPOSE_DECRYPT));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesEcbRoundTripSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB)
+                                           .Padding(KM_PAD_NONE)));
+    // Two-block message.
+    string message = "12345678901234567890123456789012";
+    string ciphertext1 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+    EXPECT_EQ(message.size(), ciphertext1.size());
+
+    string ciphertext2 = EncryptMessage(string(message), KM_MODE_ECB, KM_PAD_NONE);
+    EXPECT_EQ(message.size(), ciphertext2.size());
+
+    // ECB is deterministic.
+    EXPECT_EQ(ciphertext1, ciphertext2);
+
+    string plaintext = DecryptMessage(ciphertext1, KM_MODE_ECB, KM_PAD_NONE);
+    EXPECT_EQ(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesEcbNotAuthorized) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+                                           .Padding(KM_PAD_NONE)));
+    // Two-block message.
+    string message = "12345678901234567890123456789012";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB)
+                                           .Padding(KM_PAD_NONE)));
+    // Message is slightly shorter than two blocks.
+    string message = "1234567890123456789012345678901";
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+    string ciphertext;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &ciphertext, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&ciphertext));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7Padding) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB)
+                                           .Authorization(TAG_PADDING, KM_PAD_PKCS7)));
+
+    // Try various message lengths; all should work.
+    for (size_t i = 0; i < 32; ++i) {
+        string message(i, 'a');
+        string ciphertext = EncryptMessage(message, KM_MODE_ECB, KM_PAD_PKCS7);
+        EXPECT_EQ(i + 16 - (i % 16), ciphertext.size());
+        string plaintext = DecryptMessage(ciphertext, KM_MODE_ECB, KM_PAD_PKCS7);
+        EXPECT_EQ(message, plaintext);
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesEcbNoPaddingKeyWithPkcs7Padding) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)));
+
+    // Try various message lengths; all should fail.
+    for (size_t i = 0; i < 32; ++i) {
+        AuthorizationSet begin_params(client_params());
+        begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB);
+        begin_params.push_back(TAG_PADDING, KM_PAD_PKCS7);
+        EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PADDING_MODE,
+                  BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB)
+                                           .Authorization(TAG_PADDING, KM_PAD_PKCS7)));
+
+    string message = "a";
+    string ciphertext = EncryptMessage(message, KM_MODE_ECB, KM_PAD_PKCS7);
+    EXPECT_EQ(16U, ciphertext.size());
+    EXPECT_NE(ciphertext, message);
+    ++ciphertext[ciphertext.size() / 2];
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB);
+    begin_params.push_back(TAG_PADDING, KM_PAD_PKCS7);
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    string plaintext;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, FinishOperation(&plaintext));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCtrRoundTripSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
+                                           .Padding(KM_PAD_NONE)));
+    string message = "123";
+    string iv1;
+    string ciphertext1 = EncryptMessage(message, KM_MODE_CTR, KM_PAD_NONE, &iv1);
+    EXPECT_EQ(message.size(), ciphertext1.size());
+    EXPECT_EQ(16U, iv1.size());
+
+    string iv2;
+    string ciphertext2 = EncryptMessage(message, KM_MODE_CTR, KM_PAD_NONE, &iv2);
+    EXPECT_EQ(message.size(), ciphertext2.size());
+    EXPECT_EQ(16U, iv2.size());
+
+    // IVs should be random, so ciphertexts should differ.
+    EXPECT_NE(iv1, iv2);
+    EXPECT_NE(ciphertext1, ciphertext2);
+
+    string plaintext = DecryptMessage(ciphertext1, KM_MODE_CTR, KM_PAD_NONE, iv1);
+    EXPECT_EQ(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCtrIncremental) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
+                                           .Padding(KM_PAD_NONE)));
+
+    int increment = 15;
+    string message(239, 'a');
+    AuthorizationSet input_params(client_params());
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CTR);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    AuthorizationSet output_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, input_params, &output_params));
+
+    string ciphertext;
+    size_t input_consumed;
+    for (size_t i = 0; i < message.size(); i += increment)
+        EXPECT_EQ(KM_ERROR_OK,
+                  UpdateOperation(message.substr(i, increment), &ciphertext, &input_consumed));
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+    EXPECT_EQ(message.size(), ciphertext.size());
+
+    // Move TAG_NONCE into input_params
+    input_params.Reinitialize(output_params);
+    input_params.push_back(client_params());
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CTR);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    output_params.Clear();
+
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, input_params, &output_params));
+    string plaintext;
+    for (size_t i = 0; i < ciphertext.size(); i += increment)
+        EXPECT_EQ(KM_ERROR_OK,
+                  UpdateOperation(ciphertext.substr(i, increment), &plaintext, &input_consumed));
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+    EXPECT_EQ(ciphertext.size(), plaintext.size());
+    EXPECT_EQ(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+struct AesCtrSp80038aTestVector {
+    const char* key;
+    const char* nonce;
+    const char* plaintext;
+    const char* ciphertext;
+};
+
+// These test vectors are taken from
+// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, section F.5.
+static const AesCtrSp80038aTestVector kAesCtrSp80038aTestVectors[] = {
+    // AES-128
+    {
+        "2b7e151628aed2a6abf7158809cf4f3c", "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+        "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"
+        "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+        "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff"
+        "5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
+    },
+    // AES-192
+    {
+        "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+        "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"
+        "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+        "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e94"
+        "1e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050",
+    },
+    // AES-256
+    {
+        "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
+        "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+        "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"
+        "30c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+        "601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c5"
+        "2b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6",
+    },
+};
+
+TEST_P(EncryptionOperationsTest, AesCtrSp80038aTestVector) {
+    for (size_t i = 0; i < 3; i++) {
+        const AesCtrSp80038aTestVector& test(kAesCtrSp80038aTestVectors[i]);
+        const string key = hex2str(test.key);
+        const string nonce = hex2str(test.nonce);
+        const string plaintext = hex2str(test.plaintext);
+        const string ciphertext = hex2str(test.ciphertext);
+        CheckAesCtrTestVector(key, nonce, plaintext, ciphertext);
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCtrInvalidPaddingMode) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
+                                           .Authorization(TAG_PADDING, KM_PAD_PKCS7)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_CTR);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCtrInvalidCallerNonce) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
+                                           .Authorization(TAG_CALLER_NONCE)
+                                           .Padding(KM_PAD_NONE)));
+
+    AuthorizationSet input_params(client_params());
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CTR);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    input_params.push_back(TAG_NONCE, "123", 3);
+    EXPECT_EQ(KM_ERROR_INVALID_NONCE, BeginOperation(KM_PURPOSE_ENCRYPT, input_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCbcRoundTripSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+                                           .Padding(KM_PAD_NONE)));
+    // Two-block message.
+    string message = "12345678901234567890123456789012";
+    string iv1;
+    string ciphertext1 = EncryptMessage(message, KM_MODE_CBC, KM_PAD_NONE, &iv1);
+    EXPECT_EQ(message.size(), ciphertext1.size());
+
+    string iv2;
+    string ciphertext2 = EncryptMessage(message, KM_MODE_CBC, KM_PAD_NONE, &iv2);
+    EXPECT_EQ(message.size(), ciphertext2.size());
+
+    // IVs should be random, so ciphertexts should differ.
+    EXPECT_NE(iv1, iv2);
+    EXPECT_NE(ciphertext1, ciphertext2);
+
+    string plaintext = DecryptMessage(ciphertext1, KM_MODE_CBC, KM_PAD_NONE, iv1);
+    EXPECT_EQ(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCallerNonce) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+                                           .Authorization(TAG_CALLER_NONCE)
+                                           .Padding(KM_PAD_NONE)));
+    string message = "12345678901234567890123456789012";
+    string iv1;
+    // Don't specify nonce, should get a random one.
+    string ciphertext1 = EncryptMessage(message, KM_MODE_CBC, KM_PAD_NONE, &iv1);
+    EXPECT_EQ(message.size(), ciphertext1.size());
+    EXPECT_EQ(16U, iv1.size());
+
+    string plaintext = DecryptMessage(ciphertext1, KM_MODE_CBC, KM_PAD_NONE, iv1);
+    EXPECT_EQ(message, plaintext);
+
+    // Now specify a nonce, should also work.
+    AuthorizationSet input_params(client_params());
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    input_params.push_back(TAG_NONCE, "abcdefghijklmnop", 16);
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CBC);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    string ciphertext2 =
+        ProcessMessage(KM_PURPOSE_ENCRYPT, message, input_params, update_params, &output_params);
+
+    // Decrypt with correct nonce.
+    plaintext = ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext2, input_params, update_params,
+                               &output_params);
+    EXPECT_EQ(message, plaintext);
+
+    // Now try with wrong nonce.
+    input_params.Reinitialize(client_params());
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CBC);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    input_params.push_back(TAG_NONCE, "aaaaaaaaaaaaaaaa", 16);
+    plaintext = ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext2, input_params, update_params,
+                               &output_params);
+    EXPECT_NE(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCallerNonceProhibited) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+                                           .Padding(KM_PAD_NONE)));
+
+    string message = "12345678901234567890123456789012";
+    string iv1;
+    // Don't specify nonce, should get a random one.
+    string ciphertext1 = EncryptMessage(message, KM_MODE_CBC, KM_PAD_NONE, &iv1);
+    EXPECT_EQ(message.size(), ciphertext1.size());
+    EXPECT_EQ(16U, iv1.size());
+
+    string plaintext = DecryptMessage(ciphertext1, KM_MODE_CBC, KM_PAD_NONE, iv1);
+    EXPECT_EQ(message, plaintext);
+
+    // Now specify a nonce, should fail.
+    AuthorizationSet input_params(client_params());
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    input_params.push_back(TAG_NONCE, "abcdefghijklmnop", 16);
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CBC);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+
+    EXPECT_EQ(KM_ERROR_CALLER_NONCE_PROHIBITED,
+              BeginOperation(KM_PURPOSE_ENCRYPT, input_params, &output_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCbcIncrementalNoPadding) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+                                           .Padding(KM_PAD_NONE)));
+
+    int increment = 15;
+    string message(240, 'a');
+    AuthorizationSet input_params(client_params());
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CBC);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    AuthorizationSet output_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, input_params, &output_params));
+
+    string ciphertext;
+    size_t input_consumed;
+    for (size_t i = 0; i < message.size(); i += increment)
+        EXPECT_EQ(KM_ERROR_OK,
+                  UpdateOperation(message.substr(i, increment), &ciphertext, &input_consumed));
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+    EXPECT_EQ(message.size(), ciphertext.size());
+
+    // Move TAG_NONCE into input_params
+    input_params.Reinitialize(output_params);
+    input_params.push_back(client_params());
+    input_params.push_back(TAG_BLOCK_MODE, KM_MODE_CBC);
+    input_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    output_params.Clear();
+
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, input_params, &output_params));
+    string plaintext;
+    for (size_t i = 0; i < ciphertext.size(); i += increment)
+        EXPECT_EQ(KM_ERROR_OK,
+                  UpdateOperation(ciphertext.substr(i, increment), &plaintext, &input_consumed));
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+    EXPECT_EQ(ciphertext.size(), plaintext.size());
+    EXPECT_EQ(message, plaintext);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesCbcPkcs7Padding) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_CBC)
+                                           .Authorization(TAG_PADDING, KM_PAD_PKCS7)));
+
+    // Try various message lengths; all should work.
+    for (size_t i = 0; i < 32; ++i) {
+        string message(i, 'a');
+        string iv;
+        string ciphertext = EncryptMessage(message, KM_MODE_CBC, KM_PAD_PKCS7, &iv);
+        EXPECT_EQ(i + 16 - (i % 16), ciphertext.size());
+        string plaintext = DecryptMessage(ciphertext, KM_MODE_CBC, KM_PAD_PKCS7, iv);
+        EXPECT_EQ(message, plaintext);
+    }
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmRoundTripSuccess) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string aad = "foobar";
+    string message = "123456789012345678901234567890123456";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
+
+    // Encrypt
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    string ciphertext;
+    size_t input_consumed;
+    AuthorizationSet update_out_params;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &update_out_params, &ciphertext,
+                                           &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    // Grab nonce
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.push_back(begin_out_params);
+
+    // Decrypt.
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    string plaintext;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, ciphertext, &update_out_params,
+                                           &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+
+    EXPECT_EQ(message, plaintext);
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmTooShortTag) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string aad = "foobar";
+    string message = "123456789012345678901234567890123456";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 96);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
+
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_INVALID_MAC_LENGTH,
+              BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmTooShortTagOnDecrypt) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string aad = "foobar";
+    string message = "123456789012345678901234567890123456";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
+
+    // Encrypt
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    string ciphertext;
+    size_t input_consumed;
+    AuthorizationSet update_out_params;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &update_out_params, &ciphertext,
+                                           &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    // Grab nonce
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.Reinitialize(client_params());
+    begin_params.push_back(begin_out_params);
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 96);
+
+    // Decrypt.
+    EXPECT_EQ(KM_ERROR_INVALID_MAC_LENGTH, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmCorruptKey) {
+    uint8_t nonce[] = {
+        0xb7, 0x94, 0x37, 0xae, 0x08, 0xff, 0x35, 0x5d, 0x7d, 0x8a, 0x4d, 0x0f,
+    };
+    uint8_t ciphertext[] = {
+        0xb3, 0xf6, 0x79, 0x9e, 0x8f, 0x93, 0x26, 0xf2, 0xdf, 0x1e, 0x80, 0xfc, 0xd2, 0xcb, 0x16,
+        0xd7, 0x8c, 0x9d, 0xc7, 0xcc, 0x14, 0xbb, 0x67, 0x78, 0x62, 0xdc, 0x6c, 0x63, 0x9b, 0x3a,
+        0x63, 0x38, 0xd2, 0x4b, 0x31, 0x2d, 0x39, 0x89, 0xe5, 0x92, 0x0b, 0x5d, 0xbf, 0xc9, 0x76,
+        0x76, 0x5e, 0xfb, 0xfe, 0x57, 0xbb, 0x38, 0x59, 0x40, 0xa7, 0xa4, 0x3b, 0xdf, 0x05, 0xbd,
+        0xda, 0xe3, 0xc9, 0xd6, 0xa2, 0xfb, 0xbd, 0xfc, 0xc0, 0xcb, 0xa0,
+    };
+    string ciphertext_str(reinterpret_cast<char*>(ciphertext), sizeof(ciphertext));
+
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+    begin_params.push_back(TAG_NONCE, nonce, sizeof(nonce));
+
+    string plaintext;
+    size_t input_consumed;
+
+    // Import correct key and decrypt
+    uint8_t good_key[] = {
+        0xba, 0x76, 0x35, 0x4f, 0x0a, 0xed, 0x6e, 0x8d,
+        0x91, 0xf4, 0x5c, 0x4f, 0xf5, 0xa0, 0x62, 0xdb,
+    };
+    string good_key_str(reinterpret_cast<char*>(good_key), sizeof(good_key));
+    ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
+                                         .AesEncryptionKey(128)
+                                         .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                         .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                         .Authorization(TAG_CALLER_NONCE)
+                                         .Authorization(TAG_MIN_MAC_LENGTH, 128),
+                                     KM_KEY_FORMAT_RAW, good_key_str));
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext_str, &plaintext, &input_consumed));
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+
+    // Import bad key and decrypt
+    uint8_t bad_key[] = {
+        0xbb, 0x76, 0x35, 0x4f, 0x0a, 0xed, 0x6e, 0x8d,
+        0x91, 0xf4, 0x5c, 0x4f, 0xf5, 0xa0, 0x62, 0xdb,
+    };
+    string bad_key_str(reinterpret_cast<char*>(bad_key), sizeof(bad_key));
+    ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
+                                         .AesEncryptionKey(128)
+                                         .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                         .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                         .Authorization(TAG_MIN_MAC_LENGTH, 128),
+                                     KM_KEY_FORMAT_RAW, bad_key_str));
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext_str, &plaintext, &input_consumed));
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&plaintext));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmAadNoData) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string aad = "123456789012345678";
+    string empty_message;
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
+
+    // Encrypt
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    string ciphertext;
+    size_t input_consumed;
+    AuthorizationSet update_out_params;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, empty_message, &update_out_params,
+                                           &ciphertext, &input_consumed));
+    EXPECT_EQ(0U, input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    // Grab nonce
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.push_back(begin_out_params);
+
+    // Decrypt.
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    string plaintext;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, ciphertext, &update_out_params,
+                                           &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+
+    EXPECT_EQ(empty_message, plaintext);
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmIncremental) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, "b", 1);
+
+    // Encrypt
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    string ciphertext;
+    size_t input_consumed;
+    AuthorizationSet update_out_params;
+
+    // Send AAD, incrementally
+    for (int i = 0; i < 1000; ++i) {
+        EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, "", &update_out_params, &ciphertext,
+                                               &input_consumed));
+        EXPECT_EQ(0U, input_consumed);
+        EXPECT_EQ(0U, ciphertext.size());
+    }
+
+    // Now send data, incrementally, no data.
+    AuthorizationSet empty_params;
+    for (int i = 0; i < 1000; ++i) {
+        EXPECT_EQ(KM_ERROR_OK, UpdateOperation(empty_params, "a", &update_out_params, &ciphertext,
+                                               &input_consumed));
+        EXPECT_EQ(1U, input_consumed);
+    }
+    EXPECT_EQ(1000U, ciphertext.size());
+
+    // And finish.
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+    EXPECT_EQ(1016U, ciphertext.size());
+
+    // Grab nonce
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.push_back(begin_out_params);
+
+    // Decrypt.
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    string plaintext;
+
+    // Send AAD, incrementally, no data
+    for (int i = 0; i < 1000; ++i) {
+        EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, "", &update_out_params, &plaintext,
+                                               &input_consumed));
+        EXPECT_EQ(0U, input_consumed);
+        EXPECT_EQ(0U, plaintext.size());
+    }
+
+    // Now send data, incrementally.
+    for (size_t i = 0; i < ciphertext.length(); ++i) {
+        EXPECT_EQ(KM_ERROR_OK, UpdateOperation(empty_params, string(ciphertext.data() + i, 1),
+                                               &update_out_params, &plaintext, &input_consumed));
+        EXPECT_EQ(1U, input_consumed);
+    }
+    EXPECT_EQ(1000U, plaintext.size());
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmMultiPartAad) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string message = "123456789012345678901234567890123456";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+    AuthorizationSet begin_out_params;
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, "foo", 3);
+
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+
+    // No data, AAD only.
+    string ciphertext;
+    size_t input_consumed;
+    AuthorizationSet update_out_params;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, "" /* message */, &update_out_params,
+                                           &ciphertext, &input_consumed));
+    EXPECT_EQ(0U, input_consumed);
+
+    // AAD and data.
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &update_out_params, &ciphertext,
+                                           &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    // Grab nonce.
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.push_back(begin_out_params);
+
+    // Decrypt
+    update_params.Clear();
+    update_params.push_back(TAG_ASSOCIATED_DATA, "foofoo", 6);
+
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params));
+    string plaintext;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, ciphertext, &update_out_params,
+                                           &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
+
+    EXPECT_EQ(message, plaintext);
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmBadAad) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string message = "12345678901234567890123456789012";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, "foobar", 6);
+
+    AuthorizationSet finish_params;
+    AuthorizationSet finish_out_params;
+
+    // Encrypt
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    AuthorizationSet update_out_params;
+    string ciphertext;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &update_out_params, &ciphertext,
+                                           &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    // Grab nonce
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.push_back(begin_out_params);
+
+    update_params.Clear();
+    update_params.push_back(TAG_ASSOCIATED_DATA, "barfoo" /* Wrong AAD */, 6);
+
+    // Decrypt.
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params, &begin_out_params));
+    string plaintext;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, ciphertext, &update_out_params,
+                                           &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&plaintext));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmWrongNonce) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string message = "12345678901234567890123456789012";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, "foobar", 6);
+
+    // Encrypt
+    AuthorizationSet begin_out_params;
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    AuthorizationSet update_out_params;
+    string ciphertext;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &update_out_params, &ciphertext,
+                                           &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    begin_params.push_back(TAG_NONCE, "123456789012", 12);
+
+    // Decrypt
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params, &begin_out_params));
+    string plaintext;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, ciphertext, &update_out_params,
+                                           &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&plaintext));
+
+    // With wrong nonce, should have gotten garbage plaintext.
+    EXPECT_NE(message, plaintext);
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(EncryptionOperationsTest, AesGcmCorruptTag) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .Authorization(TAG_BLOCK_MODE, KM_MODE_GCM)
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MIN_MAC_LENGTH, 128)));
+    string aad = "foobar";
+    string message = "123456789012345678901234567890123456";
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_GCM);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    begin_params.push_back(TAG_MAC_LENGTH, 128);
+    AuthorizationSet begin_out_params;
+
+    AuthorizationSet update_params;
+    update_params.push_back(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
+
+    // Encrypt
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params, &begin_out_params));
+    AuthorizationSet update_out_params;
+    string ciphertext;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &update_out_params, &ciphertext,
+                                           &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
+
+    // Corrupt tag
+    (*ciphertext.rbegin())++;
+
+    // Grab nonce.
+    EXPECT_NE(-1, begin_out_params.find(TAG_NONCE));
+    begin_params.push_back(begin_out_params);
+
+    // Decrypt.
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, begin_params, &begin_out_params));
+    string plaintext;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, ciphertext, &update_out_params,
+                                           &plaintext, &input_consumed));
+    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&plaintext));
+
+    EXPECT_EQ(message, plaintext);
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test MaxOperationsTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, MaxOperationsTest, test_params);
+
+TEST_P(MaxOperationsTest, TestLimit) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .EcbMode()
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MAX_USES_PER_BOOT, 3)));
+
+    string message = "1234567890123456";
+    string ciphertext1 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+    string ciphertext2 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+    string ciphertext3 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+
+    // Fourth time should fail.
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_KEY_MAX_OPS_EXCEEDED, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(MaxOperationsTest, TestAbort) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .AesEncryptionKey(128)
+                                           .EcbMode()
+                                           .Authorization(TAG_PADDING, KM_PAD_NONE)
+                                           .Authorization(TAG_MAX_USES_PER_BOOT, 3)));
+
+    string message = "1234567890123456";
+    string ciphertext1 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+    string ciphertext2 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+    string ciphertext3 = EncryptMessage(message, KM_MODE_ECB, KM_PAD_NONE);
+
+    // Fourth time should fail.
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    EXPECT_EQ(KM_ERROR_KEY_MAX_OPS_EXCEEDED, BeginOperation(KM_PURPOSE_ENCRYPT, begin_params));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test AddEntropyTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, AddEntropyTest, test_params);
+
+TEST_P(AddEntropyTest, AddEntropy) {
+    // There's no obvious way to test that entropy is actually added, but we can test that the API
+    // doesn't blow up or return an error.
+    EXPECT_EQ(KM_ERROR_OK,
+              device()->add_rng_entropy(device(), reinterpret_cast<const uint8_t*>("foo"), 3));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test Keymaster0AdapterTest;
+INSTANTIATE_TEST_CASE_P(
+    AndroidKeymasterTest, Keymaster0AdapterTest,
+    ::testing::Values(
+        InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(true /* support_ec */)),
+        InstanceCreatorPtr(new Keymaster0AdapterTestInstanceCreator(false /* support_ec */))));
+
+TEST_P(Keymaster0AdapterTest, OldSoftwareKeymaster1RsaBlob) {
+    // Load and use an old-style Keymaster1 software key blob.  These blobs contain OCB-encrypted
+    // key data.
+    string km1_sw = read_file("km1_sw_rsa_512.blob");
+    EXPECT_EQ(486U, km1_sw.length());
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km1_sw.length()));
+    memcpy(key_data, km1_sw.data(), km1_sw.length());
+    set_key_blob(key_data, km1_sw.length());
+
+    string message(64, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(Keymaster0AdapterTest, UnversionedSoftwareKeymaster1RsaBlob) {
+    // Load and use an old-style Keymaster1 software key blob, without the version byte.  These
+    // blobs contain OCB-encrypted key data.
+    string km1_sw = read_file("km1_sw_rsa_512_unversioned.blob");
+    EXPECT_EQ(477U, km1_sw.length());
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km1_sw.length()));
+    memcpy(key_data, km1_sw.data(), km1_sw.length());
+    set_key_blob(key_data, km1_sw.length());
+
+    string message(64, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(Keymaster0AdapterTest, OldSoftwareKeymaster1EcdsaBlob) {
+    // Load and use an old-style Keymaster1 software key blob.  These blobs contain OCB-encrypted
+    // key data.
+    string km1_sw = read_file("km1_sw_ecdsa_256.blob");
+    EXPECT_EQ(270U, km1_sw.length());
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km1_sw.length()));
+    memcpy(key_data, km1_sw.data(), km1_sw.length());
+    set_key_blob(key_data, km1_sw.length());
+
+    string message(32, static_cast<char>(0xFF));
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+struct Malloc_Delete {
+    void operator()(void* p) { free(p); }
+};
+
+TEST_P(Keymaster0AdapterTest, OldSoftwareKeymaster0RsaBlob) {
+    // Load and use an old softkeymaster blob.  These blobs contain PKCS#8 key data.
+    string km0_sw = read_file("km0_sw_rsa_512.blob");
+    EXPECT_EQ(333U, km0_sw.length());
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km0_sw.length()));
+    memcpy(key_data, km0_sw.data(), km0_sw.length());
+    set_key_blob(key_data, km0_sw.length());
+
+    string message(64, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(Keymaster0AdapterTest, OldSwKeymaster0RsaBlobGetCharacteristics) {
+    // Load and use an old softkeymaster blob.  These blobs contain PKCS#8 key data.
+    string km0_sw = read_file("km0_sw_rsa_512.blob");
+    EXPECT_EQ(333U, km0_sw.length());
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km0_sw.length()));
+    memcpy(key_data, km0_sw.data(), km0_sw.length());
+    set_key_blob(key_data, km0_sw.length());
+
+    EXPECT_EQ(KM_ERROR_OK, GetCharacteristics());
+    EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 512));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 3));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_DIGEST, KM_DIGEST_NONE));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_PADDING, KM_PAD_NONE));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_PURPOSE, KM_PURPOSE_SIGN));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_PURPOSE, KM_PURPOSE_VERIFY));
+    EXPECT_TRUE(sw_enforced().GetTagValue(TAG_ALL_USERS));
+    EXPECT_TRUE(sw_enforced().GetTagValue(TAG_NO_AUTH_REQUIRED));
+
+    EXPECT_EQ(0, GetParam()->keymaster0_calls());
+}
+
+TEST_P(Keymaster0AdapterTest, OldHwKeymaster0RsaBlob) {
+    // Load and use an old softkeymaster blob.  These blobs contain PKCS#8 key data.
+    string km0_sw = read_file("km0_sw_rsa_512.blob");
+    EXPECT_EQ(333U, km0_sw.length());
+
+    // The keymaster0 wrapper swaps the old softkeymaster leading 'P' for a 'Q' to make the key not
+    // be recognized as a software key.  Do the same here to pretend this is a hardware key.
+    EXPECT_EQ('P', km0_sw[0]);
+    km0_sw[0] = 'Q';
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km0_sw.length()));
+    memcpy(key_data, km0_sw.data(), km0_sw.length());
+    set_key_blob(key_data, km0_sw.length());
+
+    string message(64, 'a');
+    string signature;
+    SignMessage(message, &signature, KM_DIGEST_NONE, KM_PAD_NONE);
+    VerifyMessage(message, signature, KM_DIGEST_NONE, KM_PAD_NONE);
+
+    EXPECT_EQ(5, GetParam()->keymaster0_calls());
+}
+
+TEST_P(Keymaster0AdapterTest, OldHwKeymaster0RsaBlobGetCharacteristics) {
+    // Load and use an old softkeymaster blob.  These blobs contain PKCS#8 key data.
+    string km0_sw = read_file("km0_sw_rsa_512.blob");
+    EXPECT_EQ(333U, km0_sw.length());
+
+    // The keymaster0 wrapper swaps the old softkeymaster leading 'P' for a 'Q' to make the key not
+    // be recognized as a software key.  Do the same here to pretend this is a hardware key.
+    EXPECT_EQ('P', km0_sw[0]);
+    km0_sw[0] = 'Q';
+
+    uint8_t* key_data = reinterpret_cast<uint8_t*>(malloc(km0_sw.length()));
+    memcpy(key_data, km0_sw.data(), km0_sw.length());
+    set_key_blob(key_data, km0_sw.length());
+
+    EXPECT_EQ(KM_ERROR_OK, GetCharacteristics());
+    EXPECT_TRUE(contains(hw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_KEY_SIZE, 512));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 3));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_NONE));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_MD5));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA1));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_224));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_256));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_384));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_512));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_NONE));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_OAEP));
+    EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_PSS));
+    EXPECT_EQ(15U, hw_enforced().size());
+
+    EXPECT_TRUE(contains(sw_enforced(), TAG_PURPOSE, KM_PURPOSE_SIGN));
+    EXPECT_TRUE(contains(sw_enforced(), TAG_PURPOSE, KM_PURPOSE_VERIFY));
+    EXPECT_TRUE(sw_enforced().GetTagValue(TAG_ALL_USERS));
+    EXPECT_TRUE(sw_enforced().GetTagValue(TAG_NO_AUTH_REQUIRED));
+
+    EXPECT_FALSE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
+    EXPECT_FALSE(contains(sw_enforced(), TAG_KEY_SIZE, 512));
+    EXPECT_FALSE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 3));
+    EXPECT_FALSE(contains(sw_enforced(), TAG_DIGEST, KM_DIGEST_NONE));
+    EXPECT_FALSE(contains(sw_enforced(), TAG_PADDING, KM_PAD_NONE));
+
+    EXPECT_EQ(1, GetParam()->keymaster0_calls());
+}
+
+typedef Keymaster2Test AttestationTest;
+INSTANTIATE_TEST_CASE_P(AndroidKeymasterTest, AttestationTest, test_params);
+
+static X509* parse_cert_blob(const keymaster_blob_t& blob) {
+    const uint8_t* p = blob.data;
+    return d2i_X509(nullptr, &p, blob.data_length);
+}
+
+static bool verify_chain(const keymaster_cert_chain_t& chain) {
+    for (size_t i = 0; i < chain.entry_count - 1; ++i) {
+        keymaster_blob_t& key_cert_blob = chain.entries[i];
+        keymaster_blob_t& signing_cert_blob = chain.entries[i + 1];
+
+        X509_Ptr key_cert(parse_cert_blob(key_cert_blob));
+        X509_Ptr signing_cert(parse_cert_blob(signing_cert_blob));
+        EXPECT_TRUE(!!key_cert.get() && !!signing_cert.get());
+        if (!key_cert.get() || !signing_cert.get())
+            return false;
+
+        EVP_PKEY_Ptr signing_pubkey(X509_get_pubkey(signing_cert.get()));
+        EXPECT_TRUE(!!signing_pubkey.get());
+        if (!signing_pubkey.get())
+            return false;
+
+        EXPECT_EQ(1, X509_verify(key_cert.get(), signing_pubkey.get()))
+            << "Verification of certificate " << i << " failed";
+    }
+
+    return true;
+}
+
+// Extract attestation record from cert. Returned object is still part of cert; don't free it
+// separately.
+static ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
+    ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
+    EXPECT_TRUE(!!oid.get());
+    if (!oid.get())
+        return nullptr;
+
+    int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
+    EXPECT_NE(-1, location);
+    if (location == -1)
+        return nullptr;
+
+    X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
+    EXPECT_TRUE(!!attest_rec_ext);
+    if (!attest_rec_ext)
+        return nullptr;
+
+    ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
+    EXPECT_TRUE(!!attest_rec);
+    return attest_rec;
+}
+
+static bool verify_attestation_record(AuthorizationSet expected_sw_enforced,
+                                      AuthorizationSet expected_tee_enforced,
+                                      const keymaster_blob_t& attestation_cert) {
+
+    X509_Ptr cert(parse_cert_blob(attestation_cert));
+    EXPECT_TRUE(!!cert.get());
+    if (!cert.get())
+        return false;
+
+    ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+    EXPECT_TRUE(!!attest_rec);
+    if (!attest_rec)
+        return false;
+
+    AuthorizationSet att_sw_enforced;
+    AuthorizationSet att_tee_enforced;
+    EXPECT_EQ(KM_ERROR_OK, parse_attestation_record(attest_rec->data, attest_rec->length,
+                                                    &att_sw_enforced, &att_tee_enforced));
+
+    // Add TAG_USER_ID to the attestation sw-enforced list, because user IDs are not included in
+    // attestations, since they're meaningless off-device.
+    uint32_t user_id;
+    if (expected_sw_enforced.GetTagValue(TAG_USER_ID, &user_id))
+        att_sw_enforced.push_back(TAG_USER_ID, user_id);
+    if (expected_tee_enforced.GetTagValue(TAG_USER_ID, &user_id))
+        att_tee_enforced.push_back(TAG_USER_ID, user_id);
+
+    att_sw_enforced.Sort();
+    expected_sw_enforced.Sort();
+    EXPECT_EQ(expected_sw_enforced, att_sw_enforced);
+
+    att_tee_enforced.Sort();
+    expected_tee_enforced.Sort();
+    EXPECT_EQ(expected_tee_enforced, att_tee_enforced);
+
+    return true;
+}
+
+TEST_P(AttestationTest, RsaSignedWithRsa) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+
+    keymaster_cert_chain_t cert_chain;
+    EXPECT_EQ(KM_ERROR_OK, AttestKey(KM_ALGORITHM_RSA, &cert_chain));
+    EXPECT_EQ(3U, cert_chain.entry_count);
+    EXPECT_TRUE(verify_chain(cert_chain));
+    EXPECT_TRUE(verify_attestation_record(sw_enforced(), hw_enforced(), cert_chain.entries[0]));
+
+    keymaster_free_cert_chain(&cert_chain);
+}
+
+TEST_P(AttestationTest, RsaSignedWithEc) {
+    ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder()
+                                           .RsaSigningKey(256, 3)
+                                           .Digest(KM_DIGEST_NONE)
+                                           .Padding(KM_PAD_NONE)));
+
+    keymaster_cert_chain_t cert_chain;
+    EXPECT_EQ(KM_ERROR_OK, AttestKey(KM_ALGORITHM_EC, &cert_chain));
+    EXPECT_EQ(3U, cert_chain.entry_count);
+    EXPECT_TRUE(verify_chain(cert_chain));
+    EXPECT_TRUE(verify_attestation_record(sw_enforced(), hw_enforced(), cert_chain.entries[0]));
+
+    keymaster_free_cert_chain(&cert_chain);
+}
+
+TEST(SoftKeymasterWrapperTest, CheckKeymaster2Device) {
+    // Make a good fake device, and wrap it.
+    SoftKeymasterDevice* good_fake(new SoftKeymasterDevice(new TestKeymasterContext));
+
+    // Wrap it and check it.
+    SoftKeymasterDevice* good_fake_wrapper(new SoftKeymasterDevice(new TestKeymasterContext));
+    good_fake_wrapper->SetHardwareDevice(good_fake->keymaster_device());
+    EXPECT_TRUE(good_fake_wrapper->Keymaster1DeviceIsGood());
+
+    // Close and clean up wrapper and wrapped
+    good_fake_wrapper->keymaster_device()->common.close(good_fake_wrapper->hw_device());
+
+    // Make a "bad" (doesn't support all digests) device;
+    keymaster1_device_t* sha256_only_fake = make_device_sha256_only(
+        (new SoftKeymasterDevice(new TestKeymasterContext("256")))->keymaster_device());
+
+    // Wrap it and check it.
+    SoftKeymasterDevice* sha256_only_fake_wrapper(
+        (new SoftKeymasterDevice(new TestKeymasterContext)));
+    sha256_only_fake_wrapper->SetHardwareDevice(sha256_only_fake);
+    EXPECT_FALSE(sha256_only_fake_wrapper->Keymaster1DeviceIsGood());
+
+    // Close and clean up wrapper and wrapped
+    sha256_only_fake_wrapper->keymaster_device()->common.close(
+        sha256_only_fake_wrapper->hw_device());
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/android_keymaster_test_utils.cpp b/keymaster/android_keymaster_test_utils.cpp
new file mode 100644
index 0000000..346421a
--- /dev/null
+++ b/keymaster/android_keymaster_test_utils.cpp
@@ -0,0 +1,890 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "android_keymaster_test_utils.h"
+
+#include <algorithm>
+
+#include <openssl/rand.h>
+
+#include <keymaster/android_keymaster_messages.h>
+#include <keymaster/android_keymaster_utils.h>
+
+using std::copy_if;
+using std::find_if;
+using std::is_permutation;
+using std::ostream;
+using std::string;
+using std::vector;
+
+#ifndef KEYMASTER_NAME_TAGS
+#error Keymaster test code requires that KEYMASTER_NAME_TAGS is defined
+#endif
+
+std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param) {
+    os << "Tag: " << keymaster::StringifyTag(param.tag);
+    switch (keymaster_tag_get_type(param.tag)) {
+    case KM_INVALID:
+        os << " Invalid";
+        break;
+    case KM_UINT_REP:
+        os << " (Rep)";
+    /* Falls through */
+    case KM_UINT:
+        os << " Int: " << param.integer;
+        break;
+    case KM_ENUM_REP:
+        os << " (Rep)";
+    /* Falls through */
+    case KM_ENUM:
+        os << " Enum: " << param.enumerated;
+        break;
+    case KM_ULONG_REP:
+        os << " (Rep)";
+    /* Falls through */
+    case KM_ULONG:
+        os << " Long: " << param.long_integer;
+        break;
+    case KM_DATE:
+        os << " Date: " << param.date_time;
+        break;
+    case KM_BOOL:
+        os << " Bool: " << param.boolean;
+        break;
+    case KM_BIGNUM:
+        os << " Bignum: ";
+        if (!param.blob.data)
+            os << "(null)";
+        else
+            for (size_t i = 0; i < param.blob.data_length; ++i)
+                os << std::hex << std::setw(2) << static_cast<int>(param.blob.data[i]) << std::dec;
+        break;
+    case KM_BYTES:
+        os << " Bytes: ";
+        if (!param.blob.data)
+            os << "(null)";
+        else
+            for (size_t i = 0; i < param.blob.data_length; ++i)
+                os << std::hex << std::setw(2) << static_cast<int>(param.blob.data[i]) << std::dec;
+        break;
+    }
+    return os;
+}
+
+bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b) {
+    if (a.tag != b.tag) {
+        return false;
+    }
+
+    switch (keymaster_tag_get_type(a.tag)) {
+    case KM_INVALID:
+        return true;
+    case KM_UINT_REP:
+    case KM_UINT:
+        return a.integer == b.integer;
+    case KM_ENUM_REP:
+    case KM_ENUM:
+        return a.enumerated == b.enumerated;
+    case KM_ULONG:
+    case KM_ULONG_REP:
+        return a.long_integer == b.long_integer;
+    case KM_DATE:
+        return a.date_time == b.date_time;
+    case KM_BOOL:
+        return a.boolean == b.boolean;
+    case KM_BIGNUM:
+    case KM_BYTES:
+        if ((a.blob.data == NULL || b.blob.data == NULL) && a.blob.data != b.blob.data)
+            return false;
+        return a.blob.data_length == b.blob.data_length &&
+               (memcmp(a.blob.data, b.blob.data, a.blob.data_length) == 0);
+    }
+
+    return false;
+}
+
+static char hex_value[256] = {
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 1,  2,  3,  4,  5,  6,  7, 8, 9, 0, 0, 0, 0, 0, 0,  // '0'..'9'
+    0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 'A'..'F'
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0,
+    0, 0,  0,  0,  0,  0,  0,  0,  // 'a'..'f'
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,
+    0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0};
+
+string hex2str(string a) {
+    string b;
+    size_t num = a.size() / 2;
+    b.resize(num);
+    for (size_t i = 0; i < num; i++) {
+        b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]);
+    }
+    return b;
+}
+
+namespace keymaster {
+
+bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) {
+    if (a.size() != b.size())
+        return false;
+
+    for (size_t i = 0; i < a.size(); ++i)
+        if (!(a[i] == b[i]))
+            return false;
+    return true;
+}
+
+bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b) {
+    return !(a == b);
+}
+
+std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set) {
+    if (set.size() == 0)
+        os << "(Empty)" << std::endl;
+    else {
+        os << "\n";
+        for (size_t i = 0; i < set.size(); ++i)
+            os << set[i] << std::endl;
+    }
+    return os;
+}
+
+namespace test {
+
+Keymaster2Test::Keymaster2Test() : op_handle_(OP_HANDLE_SENTINEL) {
+    memset(&characteristics_, 0, sizeof(characteristics_));
+    blob_.key_material = nullptr;
+    RAND_seed("foobar", 6);
+    blob_.key_material = 0;
+    device_ = GetParam()->CreateDevice();
+}
+
+Keymaster2Test::~Keymaster2Test() {
+    FreeCharacteristics();
+    FreeKeyBlob();
+    device_->common.close(reinterpret_cast<hw_device_t*>(device_));
+}
+
+keymaster2_device_t* Keymaster2Test::device() {
+    return device_;
+}
+
+keymaster_error_t Keymaster2Test::GenerateKey(const AuthorizationSetBuilder& builder) {
+    AuthorizationSet params(builder.build());
+    params.push_back(UserAuthParams());
+    params.push_back(ClientParams());
+
+    FreeKeyBlob();
+    FreeCharacteristics();
+    return device()->generate_key(device(), &params, &blob_, &characteristics_);
+}
+
+keymaster_error_t Keymaster2Test::DeleteKey() {
+    return device()->delete_key(device(), &blob_);
+}
+
+keymaster_error_t Keymaster2Test::ImportKey(const AuthorizationSetBuilder& builder,
+                                            keymaster_key_format_t format,
+                                            const string& key_material) {
+    AuthorizationSet params(builder.build());
+    params.push_back(UserAuthParams());
+    params.push_back(ClientParams());
+
+    FreeKeyBlob();
+    FreeCharacteristics();
+    keymaster_blob_t key = {reinterpret_cast<const uint8_t*>(key_material.c_str()),
+                            key_material.length()};
+    return device()->import_key(device(), &params, format, &key, &blob_, &characteristics_);
+}
+
+AuthorizationSet Keymaster2Test::UserAuthParams() {
+    AuthorizationSet set;
+    set.push_back(TAG_USER_ID, 7);
+    set.push_back(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD);
+    set.push_back(TAG_AUTH_TIMEOUT, 300);
+    return set;
+}
+
+AuthorizationSet Keymaster2Test::ClientParams() {
+    AuthorizationSet set;
+    set.push_back(TAG_APPLICATION_ID, "app_id", 6);
+    return set;
+}
+
+keymaster_error_t Keymaster2Test::BeginOperation(keymaster_purpose_t purpose) {
+    AuthorizationSet in_params(client_params());
+    keymaster_key_param_set_t out_params;
+    keymaster_error_t error =
+        device()->begin(device(), purpose, &blob_, &in_params, &out_params, &op_handle_);
+    EXPECT_EQ(0U, out_params.length);
+    EXPECT_TRUE(out_params.params == nullptr);
+    return error;
+}
+
+keymaster_error_t Keymaster2Test::BeginOperation(keymaster_purpose_t purpose,
+                                                 const AuthorizationSet& input_set,
+                                                 AuthorizationSet* output_set) {
+    keymaster_key_param_set_t out_params;
+    keymaster_error_t error =
+        device()->begin(device(), purpose, &blob_, &input_set, &out_params, &op_handle_);
+    if (error == KM_ERROR_OK) {
+        if (output_set) {
+            output_set->Reinitialize(out_params);
+        } else {
+            EXPECT_EQ(0U, out_params.length);
+            EXPECT_TRUE(out_params.params == nullptr);
+        }
+        keymaster_free_param_set(&out_params);
+    }
+    return error;
+}
+
+keymaster_error_t Keymaster2Test::UpdateOperation(const string& message, string* output,
+                                                  size_t* input_consumed) {
+    EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
+    keymaster_blob_t input = {reinterpret_cast<const uint8_t*>(message.c_str()), message.length()};
+    keymaster_blob_t out_tmp;
+    keymaster_key_param_set_t out_params;
+    keymaster_error_t error = device()->update(device(), op_handle_, nullptr /* params */, &input,
+                                               input_consumed, &out_params, &out_tmp);
+    if (error == KM_ERROR_OK && out_tmp.data)
+        output->append(reinterpret_cast<const char*>(out_tmp.data), out_tmp.data_length);
+    free(const_cast<uint8_t*>(out_tmp.data));
+    return error;
+}
+
+keymaster_error_t Keymaster2Test::UpdateOperation(const AuthorizationSet& additional_params,
+                                                  const string& message,
+                                                  AuthorizationSet* output_params, string* output,
+                                                  size_t* input_consumed) {
+    EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
+    keymaster_blob_t input = {reinterpret_cast<const uint8_t*>(message.c_str()), message.length()};
+    keymaster_blob_t out_tmp;
+    keymaster_key_param_set_t out_params;
+    keymaster_error_t error = device()->update(device(), op_handle_, &additional_params, &input,
+                                               input_consumed, &out_params, &out_tmp);
+    if (error == KM_ERROR_OK && out_tmp.data)
+        output->append(reinterpret_cast<const char*>(out_tmp.data), out_tmp.data_length);
+    free((void*)out_tmp.data);
+    if (output_params)
+        output_params->Reinitialize(out_params);
+    keymaster_free_param_set(&out_params);
+    return error;
+}
+
+keymaster_error_t Keymaster2Test::FinishOperation(string* output) {
+    return FinishOperation("", output);
+}
+
+keymaster_error_t Keymaster2Test::FinishOperation(const string& signature, string* output) {
+    AuthorizationSet additional_params;
+    AuthorizationSet output_params;
+    return FinishOperation(additional_params, signature, &output_params, output);
+}
+
+keymaster_error_t Keymaster2Test::FinishOperation(const AuthorizationSet& additional_params,
+                                                  const string& signature,
+                                                  AuthorizationSet* output_params, string* output) {
+    keymaster_blob_t sig = {reinterpret_cast<const uint8_t*>(signature.c_str()),
+                            signature.length()};
+    keymaster_blob_t out_tmp;
+    keymaster_key_param_set_t out_params;
+    keymaster_error_t error = device()->finish(device(), op_handle_, &additional_params,
+                                               nullptr /* input */, &sig, &out_params, &out_tmp);
+    if (error != KM_ERROR_OK) {
+        EXPECT_TRUE(out_tmp.data == nullptr);
+        EXPECT_TRUE(out_params.params == nullptr);
+        return error;
+    }
+
+    if (out_tmp.data)
+        output->append(reinterpret_cast<const char*>(out_tmp.data), out_tmp.data_length);
+    free((void*)out_tmp.data);
+    if (output_params)
+        output_params->Reinitialize(out_params);
+    keymaster_free_param_set(&out_params);
+    return error;
+}
+
+keymaster_error_t Keymaster2Test::AbortOperation() {
+    return device()->abort(device(), op_handle_);
+}
+
+keymaster_error_t Keymaster2Test::AttestKey(keymaster_algorithm_t algorithm,
+                                            keymaster_cert_chain_t* cert_chain) {
+    AuthorizationSet attest_params(
+        AuthorizationSetBuilder().Authorization(TAG_ALGORITHM, algorithm));
+    attest_params.push_back(UserAuthParams());
+    attest_params.push_back(ClientParams());
+    return device()->attest_key(device(), &blob_, &attest_params, cert_chain);
+}
+
+string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message) {
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, client_params(), NULL /* output_params */));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
+    return result;
+}
+
+string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
+                                      const AuthorizationSet& begin_params,
+                                      const AuthorizationSet& update_params,
+                                      AuthorizationSet* begin_out_params) {
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, begin_out_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, nullptr /* output_params */,
+                                           &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, "", &result));
+    return result;
+}
+
+string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
+                                      const string& signature, const AuthorizationSet& begin_params,
+                                      const AuthorizationSet& update_params,
+                                      AuthorizationSet* output_params) {
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, output_params));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, nullptr /* output_params */,
+                                           &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, signature, &result));
+    return result;
+}
+
+string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
+                                      const string& signature) {
+    EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, client_params(), NULL /* output_params */));
+
+    string result;
+    size_t input_consumed;
+    EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
+    EXPECT_EQ(message.size(), input_consumed);
+    EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
+    return result;
+}
+
+void Keymaster2Test::SignMessage(const string& message, string* signature,
+                                 keymaster_digest_t digest) {
+    SCOPED_TRACE("SignMessage");
+    AuthorizationSet input_params(AuthorizationSet(client_params_, array_length(client_params_)));
+    input_params.push_back(TAG_DIGEST, digest);
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    *signature =
+        ProcessMessage(KM_PURPOSE_SIGN, message, input_params, update_params, &output_params);
+    EXPECT_GT(signature->size(), 0U);
+}
+
+void Keymaster2Test::SignMessage(const string& message, string* signature,
+                                 keymaster_digest_t digest, keymaster_padding_t padding) {
+    SCOPED_TRACE("SignMessage");
+    AuthorizationSet input_params(AuthorizationSet(client_params_, array_length(client_params_)));
+    input_params.push_back(TAG_DIGEST, digest);
+    input_params.push_back(TAG_PADDING, padding);
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    *signature =
+        ProcessMessage(KM_PURPOSE_SIGN, message, input_params, update_params, &output_params);
+    EXPECT_GT(signature->size(), 0U);
+}
+
+void Keymaster2Test::MacMessage(const string& message, string* signature, size_t mac_length) {
+    SCOPED_TRACE("SignMessage");
+    AuthorizationSet input_params(AuthorizationSet(client_params_, array_length(client_params_)));
+    input_params.push_back(TAG_MAC_LENGTH, mac_length);
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    *signature =
+        ProcessMessage(KM_PURPOSE_SIGN, message, input_params, update_params, &output_params);
+    EXPECT_GT(signature->size(), 0U);
+}
+
+void Keymaster2Test::VerifyMessage(const string& message, const string& signature,
+                                   keymaster_digest_t digest) {
+    SCOPED_TRACE("VerifyMessage");
+    AuthorizationSet input_params(client_params());
+    input_params.push_back(TAG_DIGEST, digest);
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    ProcessMessage(KM_PURPOSE_VERIFY, message, signature, input_params, update_params,
+                   &output_params);
+}
+
+void Keymaster2Test::VerifyMessage(const string& message, const string& signature,
+                                   keymaster_digest_t digest, keymaster_padding_t padding) {
+    SCOPED_TRACE("VerifyMessage");
+    AuthorizationSet input_params(client_params());
+    input_params.push_back(TAG_DIGEST, digest);
+    input_params.push_back(TAG_PADDING, padding);
+    AuthorizationSet update_params;
+    AuthorizationSet output_params;
+    ProcessMessage(KM_PURPOSE_VERIFY, message, signature, input_params, update_params,
+                   &output_params);
+}
+
+void Keymaster2Test::VerifyMac(const string& message, const string& signature) {
+    SCOPED_TRACE("VerifyMac");
+    ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
+}
+
+string Keymaster2Test::EncryptMessage(const string& message, keymaster_padding_t padding,
+                                      string* generated_nonce) {
+    SCOPED_TRACE("EncryptMessage");
+    AuthorizationSet begin_params(client_params()), output_params;
+    begin_params.push_back(TAG_PADDING, padding);
+    AuthorizationSet update_params;
+    string ciphertext =
+        ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
+    if (generated_nonce) {
+        keymaster_blob_t nonce_blob;
+        EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
+        *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
+    } else {
+        EXPECT_EQ(-1, output_params.find(TAG_NONCE));
+    }
+    return ciphertext;
+}
+
+string Keymaster2Test::EncryptMessage(const string& message, keymaster_digest_t digest,
+                                      keymaster_padding_t padding, string* generated_nonce) {
+    AuthorizationSet update_params;
+    return EncryptMessage(update_params, message, digest, padding, generated_nonce);
+}
+
+string Keymaster2Test::EncryptMessage(const string& message, keymaster_block_mode_t block_mode,
+                                      keymaster_padding_t padding, string* generated_nonce) {
+    AuthorizationSet update_params;
+    return EncryptMessage(update_params, message, block_mode, padding, generated_nonce);
+}
+
+string Keymaster2Test::EncryptMessage(const AuthorizationSet& update_params, const string& message,
+                                      keymaster_digest_t digest, keymaster_padding_t padding,
+                                      string* generated_nonce) {
+    SCOPED_TRACE("EncryptMessage");
+    AuthorizationSet begin_params(client_params()), output_params;
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_DIGEST, digest);
+    string ciphertext =
+        ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
+    if (generated_nonce) {
+        keymaster_blob_t nonce_blob;
+        EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
+        *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
+    } else {
+        EXPECT_EQ(-1, output_params.find(TAG_NONCE));
+    }
+    return ciphertext;
+}
+
+string Keymaster2Test::EncryptMessage(const AuthorizationSet& update_params, const string& message,
+                                      keymaster_block_mode_t block_mode,
+                                      keymaster_padding_t padding, string* generated_nonce) {
+    SCOPED_TRACE("EncryptMessage");
+    AuthorizationSet begin_params(client_params()), output_params;
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_BLOCK_MODE, block_mode);
+    string ciphertext =
+        ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
+    if (generated_nonce) {
+        keymaster_blob_t nonce_blob;
+        EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
+        *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
+    } else {
+        EXPECT_EQ(-1, output_params.find(TAG_NONCE));
+    }
+    return ciphertext;
+}
+
+string Keymaster2Test::EncryptMessageWithParams(const string& message,
+                                                const AuthorizationSet& begin_params,
+                                                const AuthorizationSet& update_params,
+                                                AuthorizationSet* output_params) {
+    SCOPED_TRACE("EncryptMessageWithParams");
+    return ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, output_params);
+}
+
+string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_padding_t padding) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, padding);
+    AuthorizationSet update_params;
+    return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
+}
+
+string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_digest_t digest,
+                                      keymaster_padding_t padding) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_DIGEST, digest);
+    AuthorizationSet update_params;
+    return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
+}
+
+string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_block_mode_t block_mode,
+                                      keymaster_padding_t padding) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_BLOCK_MODE, block_mode);
+    AuthorizationSet update_params;
+    return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
+}
+
+string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_digest_t digest,
+                                      keymaster_padding_t padding, const string& nonce) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_DIGEST, digest);
+    begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
+    AuthorizationSet update_params;
+    return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
+}
+
+string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_block_mode_t block_mode,
+                                      keymaster_padding_t padding, const string& nonce) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_BLOCK_MODE, block_mode);
+    begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
+    AuthorizationSet update_params;
+    return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
+}
+
+string Keymaster2Test::DecryptMessage(const AuthorizationSet& update_params,
+                                      const string& ciphertext, keymaster_digest_t digest,
+                                      keymaster_padding_t padding, const string& nonce) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet begin_params(client_params());
+    begin_params.push_back(TAG_PADDING, padding);
+    begin_params.push_back(TAG_DIGEST, digest);
+    begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
+    return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
+}
+
+keymaster_error_t Keymaster2Test::GetCharacteristics() {
+    FreeCharacteristics();
+    return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
+                                             &characteristics_);
+}
+
+keymaster_error_t Keymaster2Test::ExportKey(keymaster_key_format_t format, string* export_data) {
+    keymaster_blob_t export_tmp;
+    keymaster_error_t error = device()->export_key(device(), format, &blob_, &client_id_,
+                                                   NULL /* app_data */, &export_tmp);
+
+    if (error != KM_ERROR_OK)
+        return error;
+
+    *export_data = string(reinterpret_cast<const char*>(export_tmp.data), export_tmp.data_length);
+    free((void*)export_tmp.data);
+    return error;
+}
+
+void Keymaster2Test::CheckHmacTestVector(const string& key, const string& message, keymaster_digest_t digest,
+                                         string expected_mac) {
+    ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
+                                         .HmacKey(key.size() * 8)
+                                         .Authorization(TAG_MIN_MAC_LENGTH, expected_mac.size() * 8)
+                                         .Digest(digest),
+                                     KM_KEY_FORMAT_RAW, key));
+    string signature;
+    MacMessage(message, &signature, expected_mac.size() * 8);
+    EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << (int)digest;
+}
+
+void Keymaster2Test::CheckAesCtrTestVector(const string& key, const string& nonce,
+                                           const string& message,
+                                           const string& expected_ciphertext) {
+    ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
+                                         .AesEncryptionKey(key.size() * 8)
+                                         .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
+                                         .Authorization(TAG_CALLER_NONCE)
+                                         .Padding(KM_PAD_NONE),
+                                     KM_KEY_FORMAT_RAW, key));
+
+    AuthorizationSet begin_params(client_params()), update_params, output_params;
+    begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
+    begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_CTR);
+    begin_params.push_back(TAG_PADDING, KM_PAD_NONE);
+    string ciphertext =
+        EncryptMessageWithParams(message, begin_params, update_params, &output_params);
+    EXPECT_EQ(expected_ciphertext, ciphertext);
+}
+
+AuthorizationSet Keymaster2Test::hw_enforced() {
+    return AuthorizationSet(characteristics_.hw_enforced);
+}
+
+AuthorizationSet Keymaster2Test::sw_enforced() {
+    return AuthorizationSet(characteristics_.sw_enforced);
+}
+
+void Keymaster2Test::FreeCharacteristics() {
+    keymaster_free_characteristics(&characteristics_);
+}
+
+void Keymaster2Test::FreeKeyBlob() {
+    free(const_cast<uint8_t*>(blob_.key_material));
+    blob_.key_material = NULL;
+}
+
+void Keymaster2Test::corrupt_key_blob() {
+    assert(blob_.key_material);
+    uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
+    ++tmp[blob_.key_material_size / 2];
+}
+
+class Sha256OnlyWrapper {
+  public:
+    explicit Sha256OnlyWrapper(const keymaster1_device_t* wrapped_device) : wrapped_device_(wrapped_device) {
+
+        new_module = *wrapped_device_->common.module;
+        new_module_name = std::string("SHA 256-only ") + wrapped_device_->common.module->name;
+        new_module.name = new_module_name.c_str();
+
+        memset(&device_, 0, sizeof(device_));
+        device_.common.module = &new_module;
+
+        device_.common.close = close_device;
+        device_.get_supported_algorithms = get_supported_algorithms;
+        device_.get_supported_block_modes = get_supported_block_modes;
+        device_.get_supported_padding_modes = get_supported_padding_modes;
+        device_.get_supported_digests = get_supported_digests;
+        device_.get_supported_import_formats = get_supported_import_formats;
+        device_.get_supported_export_formats = get_supported_export_formats;
+        device_.add_rng_entropy = add_rng_entropy;
+        device_.generate_key = generate_key;
+        device_.get_key_characteristics = get_key_characteristics;
+        device_.import_key = import_key;
+        device_.export_key = export_key;
+        device_.begin = begin;
+        device_.update = update;
+        device_.finish = finish;
+        device_.abort = abort;
+    }
+
+    keymaster1_device_t* keymaster_device() { return &device_; }
+
+    static bool is_supported(keymaster_digest_t digest) {
+        return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
+    }
+
+    static bool all_digests_supported(const keymaster_key_param_set_t* params) {
+        for (size_t i = 0; i < params->length; ++i)
+            if (params->params[i].tag == TAG_DIGEST)
+                if (!is_supported(static_cast<keymaster_digest_t>(params->params[i].enumerated)))
+                    return false;
+        return true;
+    }
+
+    static const keymaster_key_param_t*
+    get_algorithm_param(const keymaster_key_param_set_t* params) {
+        keymaster_key_param_t* end = params->params + params->length;
+        auto alg_ptr = std::find_if(params->params, end, [](keymaster_key_param_t& p) {
+            return p.tag == KM_TAG_ALGORITHM;
+        });
+        if (alg_ptr == end)
+            return nullptr;
+        return alg_ptr;
+    }
+
+    static int close_device(hw_device_t* dev) {
+        Sha256OnlyWrapper* wrapper = reinterpret_cast<Sha256OnlyWrapper*>(dev);
+        const keymaster1_device_t* wrapped_device = wrapper->wrapped_device_;
+        delete wrapper;
+        return wrapped_device->common.close(const_cast<hw_device_t*>(&wrapped_device->common));
+    }
+
+    static const keymaster1_device_t* unwrap(const keymaster1_device_t* dev) {
+        return reinterpret_cast<const Sha256OnlyWrapper*>(dev)->wrapped_device_;
+    }
+
+    static keymaster_error_t get_supported_algorithms(const struct keymaster1_device* dev,
+                                                      keymaster_algorithm_t** algorithms,
+                                                      size_t* algorithms_length) {
+        return unwrap(dev)->get_supported_algorithms(unwrap(dev), algorithms, algorithms_length);
+    }
+    static keymaster_error_t get_supported_block_modes(const struct keymaster1_device* dev,
+                                                       keymaster_algorithm_t algorithm,
+                                                       keymaster_purpose_t purpose,
+                                                       keymaster_block_mode_t** modes,
+                                                       size_t* modes_length) {
+        return unwrap(dev)->get_supported_block_modes(unwrap(dev), algorithm, purpose, modes,
+                                                      modes_length);
+    }
+    static keymaster_error_t get_supported_padding_modes(const struct keymaster1_device* dev,
+                                                         keymaster_algorithm_t algorithm,
+                                                         keymaster_purpose_t purpose,
+                                                         keymaster_padding_t** modes,
+                                                         size_t* modes_length) {
+        return unwrap(dev)->get_supported_padding_modes(unwrap(dev), algorithm, purpose, modes,
+                                                        modes_length);
+    }
+
+    static keymaster_error_t get_supported_digests(const keymaster1_device_t* dev,
+                                                   keymaster_algorithm_t algorithm,
+                                                   keymaster_purpose_t purpose,
+                                                   keymaster_digest_t** digests,
+                                                   size_t* digests_length) {
+        keymaster_error_t error = unwrap(dev)->get_supported_digests(
+            unwrap(dev), algorithm, purpose, digests, digests_length);
+        if (error != KM_ERROR_OK)
+            return error;
+
+        std::vector<keymaster_digest_t> filtered_digests;
+        std::copy_if(*digests, *digests + *digests_length, std::back_inserter(filtered_digests),
+                     [](keymaster_digest_t digest) { return is_supported(digest); });
+
+        free(*digests);
+        *digests_length = filtered_digests.size();
+        *digests = reinterpret_cast<keymaster_digest_t*>(
+            malloc(*digests_length * sizeof(keymaster_digest_t)));
+        std::copy(filtered_digests.begin(), filtered_digests.end(), *digests);
+
+        return KM_ERROR_OK;
+    }
+
+    static keymaster_error_t get_supported_import_formats(const struct keymaster1_device* dev,
+                                                          keymaster_algorithm_t algorithm,
+                                                          keymaster_key_format_t** formats,
+                                                          size_t* formats_length) {
+        return unwrap(dev)->get_supported_import_formats(unwrap(dev), algorithm, formats,
+                                                         formats_length);
+    }
+    static keymaster_error_t get_supported_export_formats(const struct keymaster1_device* dev,
+                                                          keymaster_algorithm_t algorithm,
+                                                          keymaster_key_format_t** formats,
+                                                          size_t* formats_length) {
+        return unwrap(dev)->get_supported_export_formats(unwrap(dev), algorithm, formats,
+                                                         formats_length);
+    }
+    static keymaster_error_t add_rng_entropy(const struct keymaster1_device* dev,
+                                             const uint8_t* data, size_t data_length) {
+        return unwrap(dev)->add_rng_entropy(unwrap(dev), data, data_length);
+    }
+
+    static keymaster_error_t generate_key(const keymaster1_device_t* dev,
+                                          const keymaster_key_param_set_t* params,
+                                          keymaster_key_blob_t* key_blob,
+                                          keymaster_key_characteristics_t** characteristics) {
+        auto alg_ptr = get_algorithm_param(params);
+        if (!alg_ptr)
+            return KM_ERROR_UNSUPPORTED_ALGORITHM;
+        if (alg_ptr->enumerated == KM_ALGORITHM_HMAC && !all_digests_supported(params))
+            return KM_ERROR_UNSUPPORTED_DIGEST;
+
+        return unwrap(dev)->generate_key(unwrap(dev), params, key_blob, characteristics);
+    }
+
+    static keymaster_error_t
+    get_key_characteristics(const struct keymaster1_device* dev,
+                            const keymaster_key_blob_t* key_blob, const keymaster_blob_t* client_id,
+                            const keymaster_blob_t* app_data,
+                            keymaster_key_characteristics_t** characteristics) {
+        return unwrap(dev)->get_key_characteristics(unwrap(dev), key_blob, client_id, app_data,
+                                                    characteristics);
+    }
+
+    static keymaster_error_t
+    import_key(const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
+               keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
+               keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
+        auto alg_ptr = get_algorithm_param(params);
+        if (!alg_ptr)
+            return KM_ERROR_UNSUPPORTED_ALGORITHM;
+        if (alg_ptr->enumerated == KM_ALGORITHM_HMAC && !all_digests_supported(params))
+            return KM_ERROR_UNSUPPORTED_DIGEST;
+
+        return unwrap(dev)->import_key(unwrap(dev), params, key_format, key_data, key_blob,
+                                       characteristics);
+    }
+
+    static keymaster_error_t export_key(const struct keymaster1_device* dev,  //
+                                        keymaster_key_format_t export_format,
+                                        const keymaster_key_blob_t* key_to_export,
+                                        const keymaster_blob_t* client_id,
+                                        const keymaster_blob_t* app_data,
+                                        keymaster_blob_t* export_data) {
+        return unwrap(dev)->export_key(unwrap(dev), export_format, key_to_export, client_id,
+                                       app_data, export_data);
+    }
+
+    static keymaster_error_t begin(const keymaster1_device_t* dev,  //
+                                   keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
+                                   const keymaster_key_param_set_t* in_params,
+                                   keymaster_key_param_set_t* out_params,
+                                   keymaster_operation_handle_t* operation_handle) {
+        if (!all_digests_supported(in_params))
+            return KM_ERROR_UNSUPPORTED_DIGEST;
+        return unwrap(dev)->begin(unwrap(dev), purpose, key, in_params, out_params,
+                                  operation_handle);
+    }
+
+    static keymaster_error_t update(const keymaster1_device_t* dev,
+                                    keymaster_operation_handle_t operation_handle,
+                                    const keymaster_key_param_set_t* in_params,
+                                    const keymaster_blob_t* input, size_t* input_consumed,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_blob_t* output) {
+        return unwrap(dev)->update(unwrap(dev), operation_handle, in_params, input, input_consumed,
+                                   out_params, output);
+    }
+
+    static keymaster_error_t finish(const struct keymaster1_device* dev,  //
+                                    keymaster_operation_handle_t operation_handle,
+                                    const keymaster_key_param_set_t* in_params,
+                                    const keymaster_blob_t* signature,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_blob_t* output) {
+        return unwrap(dev)->finish(unwrap(dev), operation_handle, in_params, signature, out_params,
+                                   output);
+    }
+
+    static keymaster_error_t abort(const struct keymaster1_device* dev,
+                                   keymaster_operation_handle_t operation_handle) {
+        return unwrap(dev)->abort(unwrap(dev), operation_handle);
+    }
+
+  private:
+    keymaster1_device_t device_;
+    const keymaster1_device_t* wrapped_device_;
+    hw_module_t new_module;
+    string new_module_name;
+};
+
+keymaster1_device_t* make_device_sha256_only(keymaster1_device_t* device) {
+    return (new Sha256OnlyWrapper(device))->keymaster_device();
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/android_keymaster_test_utils.h b/keymaster/android_keymaster_test_utils.h
new file mode 100644
index 0000000..7a4d35e
--- /dev/null
+++ b/keymaster/android_keymaster_test_utils.h
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_
+#define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_
+
+/*
+ * Utilities used to help with testing.  Not used in production code.
+ */
+
+#include <stdarg.h>
+
+#include <algorithm>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include <hardware/keymaster0.h>
+#include <hardware/keymaster1.h>
+#include <hardware/keymaster2.h>
+#include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/logger.h>
+
+std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param);
+bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b);
+std::string hex2str(std::string);
+
+namespace keymaster {
+
+bool operator==(const AuthorizationSet& a, const AuthorizationSet& b);
+bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b);
+
+std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set);
+
+namespace test {
+
+template <keymaster_tag_t Tag, typename KeymasterEnum>
+bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
+              KeymasterEnum val) {
+    int pos = set.find(tag);
+    return pos != -1 && set[pos].enumerated == val;
+}
+
+template <keymaster_tag_t Tag, typename KeymasterEnum>
+bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
+              KeymasterEnum val) {
+    int pos = -1;
+    while ((pos = set.find(tag, pos)) != -1)
+        if (set[pos].enumerated == val)
+            return true;
+    return false;
+}
+
+template <keymaster_tag_t Tag>
+bool contains(const AuthorizationSet& set, TypedTag<KM_UINT, Tag> tag, uint32_t val) {
+    int pos = set.find(tag);
+    return pos != -1 && set[pos].integer == val;
+}
+
+template <keymaster_tag_t Tag>
+bool contains(const AuthorizationSet& set, TypedTag<KM_UINT_REP, Tag> tag, uint32_t val) {
+    int pos = -1;
+    while ((pos = set.find(tag, pos)) != -1)
+        if (set[pos].integer == val)
+            return true;
+    return false;
+}
+
+template <keymaster_tag_t Tag>
+bool contains(const AuthorizationSet& set, TypedTag<KM_ULONG, Tag> tag, uint64_t val) {
+    int pos = set.find(tag);
+    return pos != -1 && set[pos].long_integer == val;
+}
+
+template <keymaster_tag_t Tag>
+bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
+    int pos = set.find(tag);
+    return pos != -1 &&
+           std::string(reinterpret_cast<const char*>(set[pos].blob.data),
+                       set[pos].blob.data_length) == val;
+}
+
+template <keymaster_tag_t Tag>
+bool contains(const AuthorizationSet& set, TypedTag<KM_BIGNUM, Tag> tag, const std::string& val) {
+    int pos = set.find(tag);
+    return pos != -1 &&
+           std::string(reinterpret_cast<const char*>(set[pos].blob.data),
+                       set[pos].blob.data_length) == val;
+}
+
+inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) {
+    return set.find(tag) != -1;
+}
+
+class StdoutLogger : public Logger {
+  public:
+    StdoutLogger() { set_instance(this); }
+
+    int log_msg(LogLevel level, const char* fmt, va_list args) const {
+        int output_len = 0;
+        switch (level) {
+        case DEBUG_LVL:
+            output_len = printf("DEBUG: ");
+            break;
+        case INFO_LVL:
+            output_len = printf("INFO: ");
+            break;
+        case WARNING_LVL:
+            output_len = printf("WARNING: ");
+            break;
+        case ERROR_LVL:
+            output_len = printf("ERROR: ");
+            break;
+        case SEVERE_LVL:
+            output_len = printf("SEVERE: ");
+            break;
+        }
+
+        output_len += vprintf(fmt, args);
+        output_len += printf("\n");
+        return output_len;
+    }
+};
+
+inline std::string make_string(const uint8_t* data, size_t length) {
+    return std::string(reinterpret_cast<const char*>(data), length);
+}
+
+template <size_t N> std::string make_string(const uint8_t (&a)[N]) {
+    return make_string(a, N);
+}
+
+/**
+ * Keymaster2TestInstance is used to parameterize Keymaster2Tests.  Its main function is to create a
+ * keymaster2_device_t to which test calls can be directed.  It also provides a place to specify
+ * various bits of alternative behavior, in cases where different devices are expected to behave
+ * differently (any such cases are a potential bug, but sometimes they may make sense).
+ */
+class Keymaster2TestInstanceCreator {
+  public:
+    virtual ~Keymaster2TestInstanceCreator(){};
+    virtual keymaster2_device_t* CreateDevice() const = 0;
+
+    virtual bool algorithm_in_km0_hardware(keymaster_algorithm_t algorithm) const = 0;
+    virtual int keymaster0_calls() const = 0;
+    virtual int minimal_digest_set() const { return false; }
+};
+
+// Use a shared_ptr because it's copyable.
+typedef std::shared_ptr<Keymaster2TestInstanceCreator> InstanceCreatorPtr;
+
+const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
+class Keymaster2Test : public testing::TestWithParam<InstanceCreatorPtr> {
+  protected:
+    Keymaster2Test();
+    ~Keymaster2Test();
+
+    keymaster2_device_t* device();
+
+    keymaster_error_t GenerateKey(const AuthorizationSetBuilder& builder);
+
+    keymaster_error_t DeleteKey();
+
+    keymaster_error_t ImportKey(const AuthorizationSetBuilder& builder,
+                                keymaster_key_format_t format, const std::string& key_material);
+
+    keymaster_error_t ExportKey(keymaster_key_format_t format, std::string* export_data);
+
+    keymaster_error_t GetCharacteristics();
+
+    keymaster_error_t BeginOperation(keymaster_purpose_t purpose);
+    keymaster_error_t BeginOperation(keymaster_purpose_t purpose, const AuthorizationSet& input_set,
+                                     AuthorizationSet* output_set = NULL);
+
+    keymaster_error_t UpdateOperation(const std::string& message, std::string* output,
+                                      size_t* input_consumed);
+    keymaster_error_t UpdateOperation(const AuthorizationSet& additional_params,
+                                      const std::string& message, AuthorizationSet* output_params,
+                                      std::string* output, size_t* input_consumed);
+
+    keymaster_error_t FinishOperation(std::string* output);
+    keymaster_error_t FinishOperation(const std::string& signature, std::string* output);
+    keymaster_error_t FinishOperation(const AuthorizationSet& additional_params,
+                                      const std::string& signature, std::string* output) {
+        return FinishOperation(additional_params, signature, nullptr /* output_params */, output);
+    }
+    keymaster_error_t FinishOperation(const AuthorizationSet& additional_params,
+                                      const std::string& signature, AuthorizationSet* output_params,
+                                      std::string* output);
+
+    keymaster_error_t AbortOperation();
+
+    keymaster_error_t AttestKey(keymaster_algorithm_t algorithm, keymaster_cert_chain_t* chain);
+
+    keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor);
+
+    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message);
+    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message,
+                               const AuthorizationSet& begin_params,
+                               const AuthorizationSet& update_params,
+                               AuthorizationSet* output_params = NULL);
+    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message,
+                               const std::string& signature, const AuthorizationSet& begin_params,
+                               const AuthorizationSet& update_params,
+                               AuthorizationSet* output_params = NULL);
+    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message,
+                               const std::string& signature);
+
+    void SignMessage(const std::string& message, std::string* signature, keymaster_digest_t digest);
+    void SignMessage(const std::string& message, std::string* signature, keymaster_digest_t digest,
+                     keymaster_padding_t padding);
+    void MacMessage(const std::string& message, std::string* signature, size_t mac_length);
+
+    void VerifyMessage(const std::string& message, const std::string& signature,
+                       keymaster_digest_t digest);
+    void VerifyMessage(const std::string& message, const std::string& signature,
+                       keymaster_digest_t digest, keymaster_padding_t padding);
+    void VerifyMac(const std::string& message, const std::string& signature);
+
+    std::string EncryptMessage(const std::string& message, keymaster_padding_t padding,
+                               std::string* generated_nonce = NULL);
+    std::string EncryptMessage(const std::string& message, keymaster_digest_t digest,
+                               keymaster_padding_t padding, std::string* generated_nonce = NULL);
+    std::string EncryptMessage(const std::string& message, keymaster_block_mode_t block_mode,
+                               keymaster_padding_t padding, std::string* generated_nonce = NULL);
+    std::string EncryptMessage(const AuthorizationSet& update_params, const std::string& message,
+                               keymaster_digest_t digest, keymaster_padding_t padding,
+                               std::string* generated_nonce = NULL);
+    std::string EncryptMessage(const AuthorizationSet& update_params, const std::string& message,
+                               keymaster_block_mode_t block_mode, keymaster_padding_t padding,
+                               std::string* generated_nonce = NULL);
+    std::string EncryptMessageWithParams(const std::string& message,
+                                         const AuthorizationSet& begin_params,
+                                         const AuthorizationSet& update_params,
+                                         AuthorizationSet* output_params);
+
+    std::string DecryptMessage(const std::string& ciphertext, keymaster_padding_t padding);
+    std::string DecryptMessage(const std::string& ciphertext, keymaster_digest_t digest,
+                               keymaster_padding_t padding);
+    std::string DecryptMessage(const std::string& ciphertext, keymaster_block_mode_t block_mode,
+                               keymaster_padding_t padding);
+    std::string DecryptMessage(const std::string& ciphertext, keymaster_digest_t digest,
+                               keymaster_padding_t padding, const std::string& nonce);
+    std::string DecryptMessage(const std::string& ciphertext, keymaster_block_mode_t block_mode,
+                               keymaster_padding_t padding, const std::string& nonce);
+    std::string DecryptMessage(const AuthorizationSet& update_params, const std::string& ciphertext,
+                               keymaster_digest_t digest, keymaster_padding_t padding,
+                               const std::string& nonce);
+    std::string DecryptMessage(const AuthorizationSet& update_params, const std::string& ciphertext,
+                               keymaster_block_mode_t block_mode, keymaster_padding_t padding,
+                               const std::string& nonce);
+
+    void CheckHmacTestVector(const std::string& key, const std::string& message, keymaster_digest_t digest,
+                             std::string expected_mac);
+    void CheckAesOcbTestVector(const std::string& key, const std::string& nonce,
+                               const std::string& associated_data, const std::string& message,
+                               const std::string& expected_ciphertext);
+    void CheckAesCtrTestVector(const std::string& key, const std::string& nonce,
+                               const std::string& message, const std::string& expected_ciphertext);
+    AuthorizationSet UserAuthParams();
+    AuthorizationSet ClientParams();
+
+    template <typename T>
+    bool ResponseContains(const std::vector<T>& expected, const T* values, size_t len) {
+        return expected.size() == len &&
+               std::is_permutation(values, values + len, expected.begin());
+    }
+
+    template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
+        return (len == 1 && *values == expected);
+    }
+
+    AuthorizationSet hw_enforced();
+    AuthorizationSet sw_enforced();
+
+    void FreeCharacteristics();
+    void FreeKeyBlob();
+
+    void corrupt_key_blob();
+
+    void set_key_blob(const uint8_t* key, size_t key_length) {
+        FreeKeyBlob();
+        blob_.key_material = key;
+        blob_.key_material_size = key_length;
+    }
+
+    AuthorizationSet client_params() {
+        return AuthorizationSet(client_params_, sizeof(client_params_) / sizeof(client_params_[0]));
+    }
+
+  private:
+    keymaster2_device_t* device_;
+    keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
+                                   .data_length = 6};
+    keymaster_key_param_t client_params_[1] = {
+        Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
+
+    uint64_t op_handle_;
+
+    keymaster_key_blob_t blob_;
+    keymaster_key_characteristics_t characteristics_;
+};
+
+struct Keymaster0CountingWrapper : public keymaster0_device_t {
+    explicit Keymaster0CountingWrapper(keymaster0_device_t* device) : device_(device), counter_(0) {
+        common = device_->common;
+        common.close = counting_close_device;
+        client_version = device_->client_version;
+        flags = device_->flags;
+        context = this;
+
+        generate_keypair = counting_generate_keypair;
+        import_keypair = counting_import_keypair;
+        get_keypair_public = counting_get_keypair_public;
+        delete_keypair = counting_delete_keypair;
+        delete_all = counting_delete_all;
+        sign_data = counting_sign_data;
+        verify_data = counting_verify_data;
+    }
+
+    int count() { return counter_; }
+
+    // The blobs generated by the underlying softkeymaster start with "PK#8".  Tweak the prefix so
+    // they don't get identified as softkeymaster blobs.
+    static void munge_blob(uint8_t* blob, size_t blob_length) {
+        if (blob && blob_length > 0 && *blob == 'P')
+            *blob = 'Q';  // Mind your Ps and Qs!
+    }
+
+    // Copy and un-modfy the blob.  The caller must clean up the return value.
+    static uint8_t* unmunge_blob(const uint8_t* blob, size_t blob_length) {
+        uint8_t* dup_blob = dup_buffer(blob, blob_length);
+        if (dup_blob && blob_length > 0 && *dup_blob == 'Q')
+            *dup_blob = 'P';
+        return dup_blob;
+    }
+
+    static keymaster0_device_t* device(const keymaster0_device_t* dev) {
+        Keymaster0CountingWrapper* wrapper =
+            reinterpret_cast<Keymaster0CountingWrapper*>(dev->context);
+        return wrapper->device_;
+    }
+
+    static void increment(const keymaster0_device_t* dev) {
+        Keymaster0CountingWrapper* wrapper =
+            reinterpret_cast<Keymaster0CountingWrapper*>(dev->context);
+        wrapper->counter_++;
+    }
+
+    static int counting_close_device(hw_device_t* dev) {
+        keymaster0_device_t* k0_dev = reinterpret_cast<keymaster0_device_t*>(dev);
+        increment(k0_dev);
+        Keymaster0CountingWrapper* wrapper =
+            reinterpret_cast<Keymaster0CountingWrapper*>(k0_dev->context);
+        int retval =
+            wrapper->device_->common.close(reinterpret_cast<hw_device_t*>(wrapper->device_));
+        delete wrapper;
+        return retval;
+    }
+
+    static int counting_generate_keypair(const struct keymaster0_device* dev,
+                                         const keymaster_keypair_t key_type, const void* key_params,
+                                         uint8_t** key_blob, size_t* key_blob_length) {
+        increment(dev);
+        int result = device(dev)->generate_keypair(device(dev), key_type, key_params, key_blob,
+                                                   key_blob_length);
+        if (result == 0)
+            munge_blob(*key_blob, *key_blob_length);
+        return result;
+    }
+
+    static int counting_import_keypair(const struct keymaster0_device* dev, const uint8_t* key,
+                                       const size_t key_length, uint8_t** key_blob,
+                                       size_t* key_blob_length) {
+        increment(dev);
+        int result =
+            device(dev)->import_keypair(device(dev), key, key_length, key_blob, key_blob_length);
+        if (result == 0)
+            munge_blob(*key_blob, *key_blob_length);
+        return result;
+    }
+
+    static int counting_get_keypair_public(const struct keymaster0_device* dev,
+                                           const uint8_t* key_blob, const size_t key_blob_length,
+                                           uint8_t** x509_data, size_t* x509_data_length) {
+        increment(dev);
+        std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length));
+        return device(dev)->get_keypair_public(device(dev), dup_blob.get(), key_blob_length,
+                                               x509_data, x509_data_length);
+    }
+
+    static int counting_delete_keypair(const struct keymaster0_device* dev, const uint8_t* key_blob,
+                                       const size_t key_blob_length) {
+        increment(dev);
+        if (key_blob && key_blob_length > 0)
+            EXPECT_EQ('Q', *key_blob);
+        if (device(dev)->delete_keypair) {
+            std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length));
+            return device(dev)->delete_keypair(device(dev), dup_blob.get(), key_blob_length);
+        }
+        return 0;
+    }
+
+    static int counting_delete_all(const struct keymaster0_device* dev) {
+        increment(dev);
+        if (device(dev)->delete_all)
+            return device(dev)->delete_all(device(dev));
+        return 0;
+    }
+
+    static int counting_sign_data(const struct keymaster0_device* dev, const void* signing_params,
+                                  const uint8_t* key_blob, const size_t key_blob_length,
+                                  const uint8_t* data, const size_t data_length,
+                                  uint8_t** signed_data, size_t* signed_data_length) {
+        increment(dev);
+        std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length));
+        return device(dev)->sign_data(device(dev), signing_params, dup_blob.get(), key_blob_length,
+                                      data, data_length, signed_data, signed_data_length);
+    }
+
+    static int counting_verify_data(const struct keymaster0_device* dev, const void* signing_params,
+                                    const uint8_t* key_blob, const size_t key_blob_length,
+                                    const uint8_t* signed_data, const size_t signed_data_length,
+                                    const uint8_t* signature, const size_t signature_length) {
+        increment(dev);
+        std::unique_ptr<uint8_t[]> dup_blob(unmunge_blob(key_blob, key_blob_length));
+        return device(dev)->verify_data(device(dev), signing_params, dup_blob.get(),
+                                        key_blob_length, signed_data, signed_data_length, signature,
+                                        signature_length);
+    }
+
+  private:
+    keymaster0_device_t* device_;
+    int counter_;
+};
+
+/**
+ * This function takes a keymaster1_device_t and wraps it in an adapter that supports only
+ * KM_DIGEST_SHA_2_256.
+ */
+keymaster1_device_t* make_device_sha256_only(keymaster1_device_t* device);
+
+}  // namespace test
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_
diff --git a/keymaster/android_keymaster_utils.cpp b/keymaster/android_keymaster_utils.cpp
new file mode 100644
index 0000000..053e72a
--- /dev/null
+++ b/keymaster/android_keymaster_utils.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/android_keymaster_utils.h>
+
+#include <new>
+
+namespace keymaster {
+
+// Keymaster never manages enormous buffers, so anything particularly large is bad data or the
+// result of a bug.  We arbitrarily set a 16 MiB limit.
+const size_t kMaxDupBufferSize = 16 * 1024 * 1024;
+
+uint8_t* dup_buffer(const void* buf, size_t size) {
+    if (size >= kMaxDupBufferSize)
+        return nullptr;
+    uint8_t* retval = new (std::nothrow) uint8_t[size];
+    if (retval)
+        memcpy(retval, buf, size);
+    return retval;
+}
+
+int memcmp_s(const void* p1, const void* p2, size_t length) {
+    const uint8_t* s1 = static_cast<const uint8_t*>(p1);
+    const uint8_t* s2 = static_cast<const uint8_t*>(p2);
+    uint8_t result = 0;
+    while (length-- > 0)
+        result |= *s1++ ^ *s2++;
+    return result == 0 ? 0 : 1;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/asymmetric_key.cpp b/keymaster/asymmetric_key.cpp
new file mode 100644
index 0000000..02a7f15
--- /dev/null
+++ b/keymaster/asymmetric_key.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "asymmetric_key.h"
+
+#include <new>
+
+#include <openssl/asn1.h>
+#include <openssl/stack.h>
+#include <openssl/x509.h>
+
+#include "attestation_record.h"
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+keymaster_error_t AsymmetricKey::formatted_key_material(keymaster_key_format_t format,
+                                                        UniquePtr<uint8_t[]>* material,
+                                                        size_t* size) const {
+    if (format != KM_KEY_FORMAT_X509)
+        return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
+
+    if (material == NULL || size == NULL)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    EVP_PKEY_Ptr pkey(EVP_PKEY_new());
+    if (!InternalToEvp(pkey.get()))
+        return TranslateLastOpenSslError();
+
+    int key_data_length = i2d_PUBKEY(pkey.get(), NULL);
+    if (key_data_length <= 0)
+        return TranslateLastOpenSslError();
+
+    material->reset(new (std::nothrow) uint8_t[key_data_length]);
+    if (material->get() == NULL)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    uint8_t* tmp = material->get();
+    if (i2d_PUBKEY(pkey.get(), &tmp) != key_data_length) {
+        material->reset();
+        return TranslateLastOpenSslError();
+    }
+
+    *size = key_data_length;
+    return KM_ERROR_OK;
+}
+
+static keymaster_error_t build_attestation_extension(const AuthorizationSet& tee_enforced,
+                                                     const AuthorizationSet& sw_enforced,
+                                                     X509_EXTENSION_Ptr* extension) {
+    ASN1_OBJECT_Ptr oid(
+        OBJ_txt2obj(kAttestionRecordOid, 1 /* accept numerical dotted string form only */));
+    if (!oid.get())
+        return TranslateLastOpenSslError();
+
+    UniquePtr<uint8_t[]> attest_bytes;
+    size_t attest_bytes_len;
+    keymaster_error_t error =
+        build_attestation_record(sw_enforced, tee_enforced, &attest_bytes, &attest_bytes_len);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    ASN1_OCTET_STRING_Ptr attest_str(ASN1_OCTET_STRING_new());
+    if (!attest_str.get() ||
+        !ASN1_OCTET_STRING_set(attest_str.get(), attest_bytes.get(), attest_bytes_len))
+        return TranslateLastOpenSslError();
+
+    extension->reset(
+        X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */, attest_str.get()));
+    if (!extension->get())
+        return TranslateLastOpenSslError();
+
+    return KM_ERROR_OK;
+}
+
+static bool add_public_key(EVP_PKEY* key, X509* certificate, keymaster_error_t* error) {
+    if (!X509_set_pubkey(certificate, key)) {
+        *error = TranslateLastOpenSslError();
+        return false;
+    }
+    return true;
+}
+
+static bool add_attestation_extension(const AuthorizationSet& tee_enforced,
+                                      const AuthorizationSet& sw_enforced, X509* certificate,
+                                      keymaster_error_t* error) {
+    X509_EXTENSION_Ptr attest_extension;
+    *error = build_attestation_extension(tee_enforced, sw_enforced, &attest_extension);
+    if (*error != KM_ERROR_OK)
+        return false;
+
+    if (!X509_add_ext(certificate, attest_extension.get() /* Don't release; copied */,
+                      -1 /* insert at end */)) {
+        *error = TranslateLastOpenSslError();
+        return false;
+    }
+
+    return true;
+}
+
+static keymaster_error_t get_certificate_blob(X509* certificate, keymaster_blob_t* blob) {
+    int len = i2d_X509(certificate, nullptr);
+    if (len < 0)
+        return TranslateLastOpenSslError();
+
+    uint8_t* data = new uint8_t[len];
+    if (!data)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    uint8_t* p = data;
+    i2d_X509(certificate, &p);
+
+    blob->data_length = len;
+    blob->data = data;
+
+    return KM_ERROR_OK;
+}
+
+static bool allocate_cert_chain(size_t entry_count, keymaster_cert_chain_t* chain,
+                                keymaster_error_t* error) {
+    if (chain->entries) {
+        for (size_t i = 0; i < chain->entry_count; ++i)
+            delete[] chain->entries[i].data;
+        delete[] chain->entries;
+    }
+
+    chain->entry_count = entry_count;
+    chain->entries = new keymaster_blob_t[entry_count];
+    if (!chain->entries) {
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        return false;
+    }
+    return true;
+}
+
+// Copies the intermediate and root certificates into chain, leaving the first slot for the leaf
+// certificate.
+static bool copy_attestation_chain(const KeymasterContext& context,
+                                   keymaster_algorithm_t sign_algorithm,
+                                   keymaster_cert_chain_t* chain, keymaster_error_t* error) {
+
+    UniquePtr<keymaster_cert_chain_t, CertificateChainDelete> attest_key_chain(
+        context.AttestationChain(sign_algorithm, error));
+    if (!attest_key_chain.get())
+        return false;
+
+    if (!allocate_cert_chain(attest_key_chain->entry_count + 1, chain, error))
+        return false;
+
+    chain->entries[0].data = nullptr;  // Leave empty for the leaf certificate.
+    chain->entries[0].data_length = 0;
+
+    for (size_t i = 0; i < attest_key_chain->entry_count; ++i) {
+        chain->entries[i + 1] = attest_key_chain->entries[i];
+        attest_key_chain->entries[i].data = nullptr;
+    }
+
+    return true;
+}
+
+keymaster_error_t AsymmetricKey::GenerateAttestation(const KeymasterContext& context,
+                                                     const AuthorizationSet& attest_params,
+                                                     const AuthorizationSet& tee_enforced,
+                                                     const AuthorizationSet& sw_enforced,
+                                                     keymaster_cert_chain_t* cert_chain) const {
+
+    keymaster_algorithm_t sign_algorithm;
+    if (!attest_params.GetTagValue(TAG_ALGORITHM, &sign_algorithm) ||
+        (sign_algorithm != KM_ALGORITHM_RSA && sign_algorithm != KM_ALGORITHM_EC))
+        return KM_ERROR_INCOMPATIBLE_ALGORITHM;
+
+    EVP_PKEY_Ptr pkey(EVP_PKEY_new());
+    if (!InternalToEvp(pkey.get()))
+        return TranslateLastOpenSslError();
+
+    X509_Ptr certificate(X509_new());
+    if (!certificate.get())
+        return TranslateLastOpenSslError();
+
+    if (!X509_set_version(certificate.get(), 2 /* version 3, but zero-based */))
+        return TranslateLastOpenSslError();
+
+    ASN1_INTEGER_Ptr serialNumber(ASN1_INTEGER_new());
+    if (!serialNumber.get() ||
+        !ASN1_INTEGER_set(
+            serialNumber.get(),
+            10000 /* TODO(swillden): Figure out what should go in serial number; probably a random
+                   * value */) ||
+        !X509_set_serialNumber(certificate.get(), serialNumber.get() /* Don't release; copied */))
+        return TranslateLastOpenSslError();
+
+    // TODO(swillden): Find useful values (if possible) for issuerName and subjectName.
+    X509_NAME_Ptr issuerName(X509_NAME_new());
+    if (!issuerName.get() ||
+        !X509_set_subject_name(certificate.get(), issuerName.get() /* Don't release; copied  */))
+        return TranslateLastOpenSslError();
+
+    X509_NAME_Ptr subjectName(X509_NAME_new());
+    if (!subjectName.get() ||
+        !X509_set_subject_name(certificate.get(), subjectName.get() /* Don't release; copied */))
+        return TranslateLastOpenSslError();
+
+    // TODO(swillden): Use key activity and expiration dates for notBefore and notAfter.
+    ASN1_TIME_Ptr notBefore(ASN1_TIME_new());
+    if (!notBefore.get() || !ASN1_TIME_set(notBefore.get(), 0) ||
+        !X509_set_notBefore(certificate.get(), notBefore.get() /* Don't release; copied */))
+        return TranslateLastOpenSslError();
+
+    ASN1_TIME_Ptr notAfter(ASN1_TIME_new());
+    if (!notAfter.get() || !ASN1_TIME_set(notAfter.get(), 10000) ||
+        !X509_set_notAfter(certificate.get(), notAfter.get() /* Don't release; copied */))
+        return TranslateLastOpenSslError();
+
+    keymaster_error_t error = KM_ERROR_OK;
+    EVP_PKEY_Ptr sign_key(context.AttestationKey(sign_algorithm, &error));
+
+    if (!sign_key.get() ||  //
+        !add_public_key(pkey.get(), certificate.get(), &error) ||
+        !add_attestation_extension(tee_enforced, sw_enforced, certificate.get(), &error))
+        return error;
+
+    if (!X509_sign(certificate.get(), sign_key.get(), EVP_sha256()))
+        return TranslateLastOpenSslError();
+
+    if (!copy_attestation_chain(context, sign_algorithm, cert_chain, &error))
+        return error;
+
+    return get_certificate_blob(certificate.get(), &cert_chain->entries[0]);
+}
+
+}  // namespace keymaster
diff --git a/keymaster/asymmetric_key.h b/keymaster/asymmetric_key.h
new file mode 100644
index 0000000..99ee585
--- /dev/null
+++ b/keymaster/asymmetric_key.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ASYMMETRIC_KEY_H
+#define SYSTEM_KEYMASTER_ASYMMETRIC_KEY_H
+
+#include <openssl/evp.h>
+
+#include "key.h"
+
+namespace keymaster {
+
+class AsymmetricKey : public Key {
+  public:
+    AsymmetricKey(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+                  keymaster_error_t* error)
+        : Key(hw_enforced, sw_enforced, error) {}
+
+    keymaster_error_t formatted_key_material(keymaster_key_format_t format,
+                                             UniquePtr<uint8_t[]>* material,
+                                             size_t* size) const override;
+
+    keymaster_error_t GenerateAttestation(const KeymasterContext& context,
+                                          const AuthorizationSet& attest_params,
+                                          const AuthorizationSet& tee_enforced,
+                                          const AuthorizationSet& sw_enforced,
+                                          keymaster_cert_chain_t* certificate_chain) const override;
+
+    virtual bool InternalToEvp(EVP_PKEY* pkey) const = 0;
+    virtual bool EvpToInternal(const EVP_PKEY* pkey) = 0;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ASYMMETRIC_KEY_H
diff --git a/keymaster/asymmetric_key_factory.cpp b/keymaster/asymmetric_key_factory.cpp
new file mode 100644
index 0000000..b06d0d8
--- /dev/null
+++ b/keymaster/asymmetric_key_factory.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/asymmetric_key_factory.h>
+
+#include <keymaster/android_keymaster_utils.h>
+
+#include "asymmetric_key.h"
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_PKCS8};
+const keymaster_key_format_t*
+AsymmetricKeyFactory::SupportedImportFormats(size_t* format_count) const {
+    *format_count = array_length(supported_import_formats);
+    return supported_import_formats;
+}
+
+static const keymaster_key_format_t supported_export_formats[] = {KM_KEY_FORMAT_X509};
+const keymaster_key_format_t*
+AsymmetricKeyFactory::SupportedExportFormats(size_t* format_count) const {
+    *format_count = array_length(supported_export_formats);
+    return supported_export_formats;
+}
+
+keymaster_error_t AsymmetricKeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                                const AuthorizationSet& /* additional_params */,
+                                                const AuthorizationSet& hw_enforced,
+                                                const AuthorizationSet& sw_enforced,
+                                                UniquePtr<Key>* key) const {
+    UniquePtr<AsymmetricKey> asymmetric_key;
+    keymaster_error_t error = CreateEmptyKey(hw_enforced, sw_enforced, &asymmetric_key);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    const uint8_t* tmp = key_material.key_material;
+    EVP_PKEY* pkey =
+        d2i_PrivateKey(evp_key_type(), NULL /* pkey */, &tmp, key_material.key_material_size);
+    if (!pkey)
+        return TranslateLastOpenSslError();
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey_deleter(pkey);
+
+    if (!asymmetric_key->EvpToInternal(pkey))
+        error = TranslateLastOpenSslError();
+    else
+        key->reset(asymmetric_key.release());
+
+    return error;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/attestation_record.cpp b/keymaster/attestation_record.cpp
new file mode 100644
index 0000000..809f7c8
--- /dev/null
+++ b/keymaster/attestation_record.cpp
@@ -0,0 +1,654 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#include "attestation_record.h"
+
+#include <assert.h>
+
+#include <openssl/asn1t.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+struct stack_st_ASN1_TYPE_Delete {
+    void operator()(stack_st_ASN1_TYPE* p) { sk_ASN1_TYPE_free(p); }
+};
+
+struct ASN1_STRING_Delete {
+    void operator()(ASN1_STRING* p) { ASN1_STRING_free(p); }
+};
+
+struct ASN1_TYPE_Delete {
+    void operator()(ASN1_TYPE* p) { ASN1_TYPE_free(p); }
+};
+
+#define ASN1_INTEGER_SET STACK_OF(ASN1_INTEGER)
+
+typedef struct km_root_of_trust {
+    ASN1_OCTET_STRING* verified_boot_key;
+    ASN1_INTEGER* os_version;
+    ASN1_INTEGER* os_patchlevel;
+} KM_ROOT_OF_TRUST;
+
+ASN1_SEQUENCE(KM_ROOT_OF_TRUST) = {
+    ASN1_SIMPLE(KM_ROOT_OF_TRUST, verified_boot_key, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(KM_ROOT_OF_TRUST, os_version, ASN1_INTEGER),
+    ASN1_SIMPLE(KM_ROOT_OF_TRUST, os_patchlevel, ASN1_INTEGER),
+} ASN1_SEQUENCE_END(KM_ROOT_OF_TRUST);
+IMPLEMENT_ASN1_FUNCTIONS(KM_ROOT_OF_TRUST);
+
+typedef struct km_auth_list {
+    ASN1_INTEGER_SET* purpose;
+    ASN1_INTEGER* algorithm;
+    ASN1_INTEGER* key_size;
+    ASN1_INTEGER_SET* block_mode;
+    ASN1_INTEGER_SET* digest;
+    ASN1_INTEGER_SET* padding;
+    ASN1_NULL* caller_nonce;
+    ASN1_INTEGER* min_mac_length;
+    ASN1_INTEGER_SET* kdf;
+    ASN1_INTEGER* ec_curve;
+    ASN1_INTEGER* rsa_public_exponent;
+    ASN1_NULL* ecies_single_hash_mode;
+    ASN1_NULL* include_unique_id;
+    ASN1_INTEGER* blob_usage_requirement;
+    ASN1_NULL* bootloader_only;
+    ASN1_INTEGER* active_date_time;
+    ASN1_INTEGER* origination_expire_date_time;
+    ASN1_INTEGER* usage_expire_date_time;
+    ASN1_INTEGER* min_seconds_between_ops;
+    ASN1_INTEGER* max_uses_per_boot;
+    ASN1_NULL* no_auth_required;
+    ASN1_INTEGER* user_auth_type;
+    ASN1_INTEGER* auth_timeout;
+    ASN1_NULL* allow_while_on_body;
+    ASN1_NULL* all_applications;
+    ASN1_OCTET_STRING* application_id;
+    ASN1_OCTET_STRING* application_data;
+    ASN1_INTEGER* creation_date_time;
+    ASN1_INTEGER* origin;
+    ASN1_NULL* rollback_resistant;
+    KM_ROOT_OF_TRUST* root_of_trust;
+    ASN1_INTEGER* os_version;
+    ASN1_INTEGER* os_patchlevel;
+    ASN1_OCTET_STRING* unique_id;
+} KM_AUTH_LIST;
+
+ASN1_SEQUENCE(KM_AUTH_LIST) = {
+    ASN1_IMP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.masked_tag()),
+    ASN1_IMP_SET_OF_OPT(KM_AUTH_LIST, block_mode, ASN1_INTEGER, TAG_BLOCK_MODE.masked_tag()),
+    ASN1_IMP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.masked_tag()),
+    ASN1_IMP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, caller_nonce, ASN1_NULL, TAG_CALLER_NONCE.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, min_mac_length, ASN1_INTEGER, TAG_MIN_MAC_LENGTH.masked_tag()),
+    ASN1_IMP_SET_OF_OPT(KM_AUTH_LIST, kdf, ASN1_INTEGER, TAG_KDF.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER,
+                 TAG_RSA_PUBLIC_EXPONENT.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, ecies_single_hash_mode, ASN1_NULL,
+                 TAG_ECIES_SINGLE_HASH_MODE.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, include_unique_id, ASN1_NULL, TAG_INCLUDE_UNIQUE_ID.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, blob_usage_requirement, ASN1_INTEGER,
+                 TAG_BLOB_USAGE_REQUIREMENTS.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, bootloader_only, ASN1_NULL, TAG_BOOTLOADER_ONLY.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
+                 TAG_ORIGINATION_EXPIRE_DATETIME.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER,
+                 TAG_USAGE_EXPIRE_DATETIME.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, min_seconds_between_ops, ASN1_INTEGER,
+                 TAG_MIN_SECONDS_BETWEEN_OPS.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, max_uses_per_boot, ASN1_INTEGER, TAG_MAX_USES_PER_BOOT.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL,
+                 TAG_ALLOW_WHILE_ON_BODY.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, all_applications, ASN1_NULL, TAG_ALL_APPLICATIONS.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, application_id, ASN1_OCTET_STRING, TAG_APPLICATION_ID.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, application_data, ASN1_OCTET_STRING,
+                 TAG_APPLICATION_DATA.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER,
+                 TAG_CREATION_DATETIME.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, rollback_resistant, ASN1_NULL, TAG_ROLLBACK_RESISTANT.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.masked_tag()),
+    ASN1_IMP_OPT(KM_AUTH_LIST, unique_id, ASN1_NULL, TAG_UNIQUE_ID.masked_tag()),
+} ASN1_SEQUENCE_END(KM_AUTH_LIST);
+IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
+
+typedef struct km_key_description {
+    KM_AUTH_LIST* software_enforced;
+    KM_AUTH_LIST* tee_enforced;
+} KM_KEY_DESCRIPTION;
+
+ASN1_SEQUENCE(KM_KEY_DESCRIPTION) = {
+    ASN1_SIMPLE(KM_KEY_DESCRIPTION, software_enforced, KM_AUTH_LIST),
+    ASN1_SIMPLE(KM_KEY_DESCRIPTION, tee_enforced, KM_AUTH_LIST),
+} ASN1_SEQUENCE_END(KM_KEY_DESCRIPTION);
+IMPLEMENT_ASN1_FUNCTIONS(KM_KEY_DESCRIPTION);
+
+struct KM_AUTH_LIST_Delete {
+    void operator()(KM_AUTH_LIST* p) { KM_AUTH_LIST_free(p); }
+};
+
+struct KM_KEY_DESCRIPTION_Delete {
+    void operator()(KM_KEY_DESCRIPTION* p) { KM_KEY_DESCRIPTION_free(p); }
+};
+
+static uint32_t get_uint32_value(const keymaster_key_param_t& param) {
+    switch (keymaster_tag_get_type(param.tag)) {
+    case KM_ENUM:
+    case KM_ENUM_REP:
+        return param.enumerated;
+    case KM_UINT:
+    case KM_UINT_REP:
+        return param.integer;
+    default:
+        assert(false);
+        return 0xFFFFFFFF;
+    }
+}
+
+// Insert value in either the dest_integer or the dest_integer_set, whichever is provided.
+static keymaster_error_t insert_integer(ASN1_INTEGER* value, ASN1_INTEGER** dest_integer,
+                                        ASN1_INTEGER_SET** dest_integer_set) {
+    assert((dest_integer == nullptr) ^ (dest_integer_set == nullptr));
+    assert(value);
+
+    if (dest_integer_set) {
+        if (!*dest_integer_set)
+            *dest_integer_set = sk_ASN1_INTEGER_new_null();
+        if (!*dest_integer_set)
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        if (!sk_ASN1_INTEGER_push(*dest_integer_set, value))
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        return KM_ERROR_OK;
+
+    } else if (dest_integer) {
+        if (*dest_integer)
+            ASN1_INTEGER_free(*dest_integer);
+        *dest_integer = value;
+        return KM_ERROR_OK;
+    }
+
+    assert(false);  // Should never get here.
+    return KM_ERROR_OK;
+}
+
+// Put the contents of the keymaster AuthorizationSet auth_list in to the ASN.1 record structure,
+// record.
+static keymaster_error_t build_auth_list(const AuthorizationSet& auth_list, KM_AUTH_LIST* record) {
+
+    assert(record);
+
+    for (auto entry : auth_list) {
+
+        ASN1_INTEGER_SET** integer_set = nullptr;
+        ASN1_INTEGER** integer_ptr = nullptr;
+        ASN1_OCTET_STRING** string_ptr = nullptr;
+        ASN1_NULL** bool_ptr = nullptr;
+
+        switch (entry.tag) {
+
+        /* Ignored tags */
+        case KM_TAG_INVALID:
+        case KM_TAG_ASSOCIATED_DATA:
+        case KM_TAG_NONCE:
+        case KM_TAG_AUTH_TOKEN:
+        case KM_TAG_MAC_LENGTH:
+        case KM_TAG_ALL_USERS:
+        case KM_TAG_USER_ID:
+        case KM_TAG_USER_SECURE_ID:
+        case KM_TAG_EXPORTABLE:
+        case KM_TAG_RESET_SINCE_ID_ROTATION:
+            continue;
+
+        /* Non-repeating enumerations */
+        case KM_TAG_ALGORITHM:
+            integer_ptr = &record->algorithm;
+            break;
+        case KM_TAG_EC_CURVE:
+            integer_ptr = &record->ec_curve;
+            break;
+        case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+            integer_ptr = &record->blob_usage_requirement;
+            break;
+        case KM_TAG_USER_AUTH_TYPE:
+            integer_ptr = &record->user_auth_type;
+            break;
+        case KM_TAG_ORIGIN:
+            integer_ptr = &record->origin;
+            break;
+
+        /* Repeating enumerations */
+        case KM_TAG_PURPOSE:
+            integer_set = &record->purpose;
+            break;
+        case KM_TAG_BLOCK_MODE:
+            integer_set = &record->block_mode;
+            break;
+        case KM_TAG_PADDING:
+            integer_set = &record->padding;
+            break;
+        case KM_TAG_DIGEST:
+            integer_set = &record->digest;
+            break;
+        case KM_TAG_KDF:
+            integer_set = &record->kdf;
+            break;
+
+        /* Non-repeating unsigned integers */
+        case KM_TAG_KEY_SIZE:
+            integer_ptr = &record->key_size;
+            break;
+        case KM_TAG_MIN_MAC_LENGTH:
+            integer_ptr = &record->min_mac_length;
+            break;
+        case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+            integer_ptr = &record->min_seconds_between_ops;
+            break;
+        case KM_TAG_MAX_USES_PER_BOOT:
+            integer_ptr = &record->max_uses_per_boot;
+            break;
+        case KM_TAG_AUTH_TIMEOUT:
+            integer_ptr = &record->auth_timeout;
+            break;
+
+        /* Non-repeating long unsigned integers */
+        case KM_TAG_RSA_PUBLIC_EXPONENT:
+            integer_ptr = &record->rsa_public_exponent;
+            break;
+
+        /* Dates */
+        case KM_TAG_ACTIVE_DATETIME:
+            integer_ptr = &record->active_date_time;
+            break;
+        case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
+            integer_ptr = &record->origination_expire_date_time;
+            break;
+        case KM_TAG_USAGE_EXPIRE_DATETIME:
+            integer_ptr = &record->usage_expire_date_time;
+            break;
+        case KM_TAG_CREATION_DATETIME:
+            integer_ptr = &record->creation_date_time;
+            break;
+
+        /* Booleans */
+        case KM_TAG_CALLER_NONCE:
+            bool_ptr = &record->caller_nonce;
+            break;
+        case KM_TAG_ECIES_SINGLE_HASH_MODE:
+            bool_ptr = &record->ecies_single_hash_mode;
+            break;
+        case KM_TAG_BOOTLOADER_ONLY:
+            bool_ptr = &record->bootloader_only;
+            break;
+        case KM_TAG_NO_AUTH_REQUIRED:
+            bool_ptr = &record->no_auth_required;
+            break;
+        case KM_TAG_ALL_APPLICATIONS:
+            bool_ptr = &record->all_applications;
+            break;
+        case KM_TAG_ROLLBACK_RESISTANT:
+            bool_ptr = &record->rollback_resistant;
+            break;
+        case KM_TAG_INCLUDE_UNIQUE_ID:
+            bool_ptr = &record->include_unique_id;
+            break;
+        case KM_TAG_ALLOW_WHILE_ON_BODY:
+            bool_ptr = &record->allow_while_on_body;
+            break;
+
+        /* Byte arrays*/
+        case KM_TAG_APPLICATION_ID:
+            string_ptr = &record->application_id;
+            break;
+        case KM_TAG_APPLICATION_DATA:
+            string_ptr = &record->application_data;
+            break;
+        case KM_TAG_UNIQUE_ID:
+            string_ptr = &record->unique_id;
+            break;
+
+        /* Root of Trust components */
+        case KM_TAG_OS_VERSION:
+        case KM_TAG_OS_PATCHLEVEL:
+        case KM_TAG_ROOT_OF_TRUST:
+            if (!record->root_of_trust)
+                record->root_of_trust = KM_ROOT_OF_TRUST_new();
+            if (!record->root_of_trust)
+                return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+            switch (entry.tag) {
+            case KM_TAG_OS_VERSION:
+                integer_ptr = &record->root_of_trust->os_version;
+                break;
+            case KM_TAG_OS_PATCHLEVEL:
+                integer_ptr = &record->root_of_trust->os_patchlevel;
+                break;
+            case KM_TAG_ROOT_OF_TRUST:
+                string_ptr = &record->root_of_trust->verified_boot_key;
+                break;
+            default:
+                assert(false);  // Can't get here.
+            }
+            break;
+        }
+
+        keymaster_tag_type_t type = keymaster_tag_get_type(entry.tag);
+        switch (type) {
+        case KM_ENUM:
+        case KM_ENUM_REP:
+        case KM_UINT:
+        case KM_UINT_REP: {
+            assert((keymaster_tag_repeatable(entry.tag) && integer_set) ||
+                   (!keymaster_tag_repeatable(entry.tag) && integer_ptr));
+
+            UniquePtr<ASN1_INTEGER, ASN1_INTEGER_Delete> value(ASN1_INTEGER_new());
+            if (!value.get())
+                return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+            if (!ASN1_INTEGER_set(value.get(), get_uint32_value(entry)))
+                return TranslateLastOpenSslError();
+
+            insert_integer(value.release(), integer_ptr, integer_set);
+            break;
+        }
+
+        case KM_ULONG:
+        case KM_ULONG_REP:
+        case KM_DATE: {
+            assert((keymaster_tag_repeatable(entry.tag) && integer_set) ||
+                   (!keymaster_tag_repeatable(entry.tag) && integer_ptr));
+
+            UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new());
+            if (!exponent.get())
+                return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+            if (type == KM_DATE) {
+                if (!BN_set_word(exponent.get(), entry.date_time))
+                    return TranslateLastOpenSslError();
+            } else {
+                if (!BN_set_word(exponent.get(), entry.long_integer))
+                    return TranslateLastOpenSslError();
+            }
+
+            UniquePtr<ASN1_INTEGER, ASN1_INTEGER_Delete> value(
+                BN_to_ASN1_INTEGER(exponent.get(), nullptr));
+            if (!value.get())
+                return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+            insert_integer(value.release(), integer_ptr, integer_set);
+            break;
+        }
+
+        case KM_BOOL:
+            assert(bool_ptr);
+            if (!*bool_ptr)
+                *bool_ptr = ASN1_NULL_new();
+            if (!*bool_ptr)
+                return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+            break;
+
+        /* Byte arrays*/
+        case KM_BYTES:
+            assert(string_ptr);
+            if (!*string_ptr)
+                *string_ptr = ASN1_OCTET_STRING_new();
+            if (!*string_ptr)
+                return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+            if (!ASN1_OCTET_STRING_set(*string_ptr, entry.blob.data, entry.blob.data_length))
+                return TranslateLastOpenSslError();
+            break;
+
+        default:
+            return KM_ERROR_UNIMPLEMENTED;
+        }
+    }
+
+    return KM_ERROR_OK;
+}
+
+// Construct an ASN1.1 DER-encoded attestation record containing the values from sw_enforced and
+// tee_enforced.
+keymaster_error_t build_attestation_record(const AuthorizationSet& sw_enforced,
+                                           const AuthorizationSet& tee_enforced,
+                                           UniquePtr<uint8_t[]>* asn1_key_desc,
+                                           size_t* asn1_key_desc_len) {
+    assert(asn1_key_desc && asn1_key_desc_len);
+
+    UniquePtr<KM_KEY_DESCRIPTION, KM_KEY_DESCRIPTION_Delete> key_desc(KM_KEY_DESCRIPTION_new());
+    if (!key_desc.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    keymaster_error_t error;
+
+    error = build_auth_list(sw_enforced, key_desc->software_enforced);
+    if (error != KM_ERROR_OK)
+        return error;
+    error = build_auth_list(tee_enforced, key_desc->tee_enforced);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    int len = i2d_KM_KEY_DESCRIPTION(key_desc.get(), nullptr);
+    if (len < 0)
+        return TranslateLastOpenSslError();
+    *asn1_key_desc_len = len;
+    asn1_key_desc->reset(new uint8_t[*asn1_key_desc_len]);
+    if (!asn1_key_desc->get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    uint8_t* p = asn1_key_desc->get();
+    len = i2d_KM_KEY_DESCRIPTION(key_desc.get(), &p);
+    if (len < 0)
+        return TranslateLastOpenSslError();
+
+    return KM_ERROR_OK;
+}
+
+// Copy all enumerated values with the specified tag from stack to auth_list.
+static bool get_repeated_enums(const stack_st_ASN1_INTEGER* stack, keymaster_tag_t tag,
+                               AuthorizationSet* auth_list) {
+    assert(keymaster_tag_get_type(tag) == KM_ENUM_REP);
+    for (size_t i = 0; i < sk_ASN1_INTEGER_num(stack); ++i) {
+        if (!auth_list->push_back(
+                keymaster_param_enum(tag, ASN1_INTEGER_get(sk_ASN1_INTEGER_value(stack, i)))))
+            return false;
+    }
+    return true;
+}
+
+// Add the specified integer tag/value pair to auth_list.
+template <keymaster_tag_type_t Type, keymaster_tag_t Tag, typename KeymasterEnum>
+static bool get_enum(const ASN1_INTEGER* asn1_int, TypedEnumTag<Type, Tag, KeymasterEnum> tag,
+                     AuthorizationSet* auth_list) {
+    if (!asn1_int)
+        return true;
+    return auth_list->push_back(tag, static_cast<KeymasterEnum>(ASN1_INTEGER_get(asn1_int)));
+}
+
+// Add the specified ulong tag/value pair to auth_list.
+static bool get_ulong(const ASN1_INTEGER* asn1_int, keymaster_tag_t tag,
+                      AuthorizationSet* auth_list) {
+    if (!asn1_int)
+        return true;
+    UniquePtr<BIGNUM, BIGNUM_Delete> bn(ASN1_INTEGER_to_BN(asn1_int, nullptr));
+    if (!bn.get())
+        return false;
+    uint64_t ulong = BN_get_word(bn.get());
+    return auth_list->push_back(keymaster_param_long(tag, ulong));
+}
+
+// Extract the values from the specified ASN.1 record and place them in auth_list.
+static keymaster_error_t extract_auth_list(const KM_AUTH_LIST* record,
+                                           AuthorizationSet* auth_list) {
+    // Purpose
+    if (!get_repeated_enums(record->purpose, TAG_PURPOSE, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Algorithm
+    if (!get_enum(record->algorithm, TAG_ALGORITHM, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Key size
+    if (record->key_size && !auth_list->push_back(TAG_KEY_SIZE, ASN1_INTEGER_get(record->key_size)))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Block mode
+    if (!get_repeated_enums(record->block_mode, TAG_BLOCK_MODE, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Digest
+    if (!get_repeated_enums(record->digest, TAG_DIGEST, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Padding
+    if (!get_repeated_enums(record->padding, TAG_PADDING, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Caller NONCE
+    if (record->caller_nonce && !auth_list->push_back(TAG_CALLER_NONCE))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Min MAC length
+    if (record->min_mac_length &&
+        !auth_list->push_back(TAG_MIN_MAC_LENGTH, ASN1_INTEGER_get(record->min_mac_length)))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // EC curve
+    if (!get_enum(record->ec_curve, TAG_EC_CURVE, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // RSA public exponent
+    if (!get_ulong(record->rsa_public_exponent, TAG_RSA_PUBLIC_EXPONENT, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // ECIES single hash mode
+    if (record->ecies_single_hash_mode && !auth_list->push_back(TAG_ECIES_SINGLE_HASH_MODE))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Blob usage requirement
+    if (!get_enum(record->blob_usage_requirement, TAG_BLOB_USAGE_REQUIREMENTS, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Bootloader only
+    if (record->bootloader_only && !auth_list->push_back(TAG_BOOTLOADER_ONLY))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Active date time
+    if (!get_ulong(record->active_date_time, TAG_ACTIVE_DATETIME, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Origination expire date time
+    if (!get_ulong(record->origination_expire_date_time, TAG_ORIGINATION_EXPIRE_DATETIME,
+                   auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Usage Expire date time
+    if (!get_ulong(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Min seconds between ops
+    if (record->min_seconds_between_ops &&
+        !auth_list->push_back(TAG_MIN_SECONDS_BETWEEN_OPS,
+                              ASN1_INTEGER_get(record->min_seconds_between_ops)))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Max uses per boot
+    if (record->max_uses_per_boot &&
+        !auth_list->push_back(TAG_MAX_USES_PER_BOOT, ASN1_INTEGER_get(record->max_uses_per_boot)))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // No auth required
+    if (record->no_auth_required && !auth_list->push_back(TAG_NO_AUTH_REQUIRED))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // User auth type
+    if (!get_enum(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Auth timeout
+    if (record->auth_timeout &&
+        !auth_list->push_back(TAG_AUTH_TIMEOUT, ASN1_INTEGER_get(record->auth_timeout)))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // All applications
+    if (record->all_applications && !auth_list->push_back(TAG_ALL_APPLICATIONS))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Application ID
+    if (record->application_id &&
+        !auth_list->push_back(TAG_APPLICATION_ID, record->application_id->data,
+                              record->application_id->length))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Application data
+    if (record->application_data &&
+        !auth_list->push_back(TAG_APPLICATION_DATA, record->application_data->data,
+                              record->application_data->length))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Creation date time
+    if (!get_ulong(record->creation_date_time, TAG_CREATION_DATETIME, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Origin
+    if (!get_enum(record->origin, TAG_ORIGIN, auth_list))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Rollback resistant
+    if (record->rollback_resistant && !auth_list->push_back(TAG_ROLLBACK_RESISTANT))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Root of trust
+    if (record->root_of_trust) {
+        KM_ROOT_OF_TRUST* rot = record->root_of_trust;
+        if (!rot->verified_boot_key || !rot->os_version || !rot->os_patchlevel)
+            return KM_ERROR_INVALID_KEY_BLOB;
+
+        if (!auth_list->push_back(TAG_OS_VERSION, ASN1_INTEGER_get(rot->os_version)) ||
+            !auth_list->push_back(TAG_OS_PATCHLEVEL, ASN1_INTEGER_get(rot->os_patchlevel)) ||
+            !auth_list->push_back(TAG_ROOT_OF_TRUST, rot->verified_boot_key->data,
+                                  rot->verified_boot_key->length))
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+
+    return KM_ERROR_OK;
+}
+
+// Parse the DER-encoded attestation record, placing the results in software_enforced and
+// tee_enforced.
+keymaster_error_t parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
+                                           AuthorizationSet* software_enforced,
+                                           AuthorizationSet* tee_enforced) {
+    const uint8_t* p = asn1_key_desc;
+    UniquePtr<KM_KEY_DESCRIPTION, KM_KEY_DESCRIPTION_Delete> record(
+        d2i_KM_KEY_DESCRIPTION(nullptr, &p, asn1_key_desc_len));
+    if (!record.get())
+        return TranslateLastOpenSslError();
+
+    keymaster_error_t error = extract_auth_list(record->software_enforced, software_enforced);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return extract_auth_list(record->tee_enforced, tee_enforced);
+}
+
+}  // namepace keymaster
diff --git a/keymaster/attestation_record.h b/keymaster/attestation_record.h
new file mode 100644
index 0000000..3cd5dde
--- /dev/null
+++ b/keymaster/attestation_record.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ATTESTATION_RECORD_H_
+#define SYSTEM_KEYMASTER_ATTESTATION_RECORD_H_
+
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/authorization_set.h>
+
+namespace keymaster {
+
+/**
+ * The OID for Android attestation records.  For the curious, it breaks down as follows:
+ *
+ * 1 = ISO
+ * 3 = org
+ * 6 = DoD (Huh? OIDs are weird.)
+ * 1 = IANA
+ * 4 = Private
+ * 1 = Enterprises
+ * 11129 = Google
+ * 2 = Google security
+ * 1 = certificate extension
+ * 17 = Android attestation extension.
+ */
+static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17";
+
+keymaster_error_t build_attestation_record(const AuthorizationSet& software_enforced,
+                                           const AuthorizationSet& tee_enforced,
+                                           UniquePtr<uint8_t[]>* asn1_key_desc,
+                                           size_t* asn1_key_desc_len);
+
+keymaster_error_t parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
+                                           AuthorizationSet* software_enforced,
+                                           AuthorizationSet* tee_enforced);
+}
+
+#endif  // SYSTEM_KEYMASTER_ATTESTATION_RECORD_H_
diff --git a/keymaster/attestation_record_test.cpp b/keymaster/attestation_record_test.cpp
new file mode 100644
index 0000000..21a7eee
--- /dev/null
+++ b/keymaster/attestation_record_test.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#include <fstream>
+
+#include <gtest/gtest.h>
+
+#include "android_keymaster_test_utils.h"
+#include "attestation_record.h"
+
+namespace keymaster {
+namespace test {
+
+TEST(AttestTest, Simple) {
+    AuthorizationSet hw_set(AuthorizationSetBuilder()
+                                .RsaSigningKey(512, 3)
+                                .Digest(KM_DIGEST_SHA_2_256)
+                                .Digest(KM_DIGEST_SHA_2_384)
+                                .Authorization(TAG_ROOT_OF_TRUST, "foo", 3)
+                                .Authorization(TAG_OS_VERSION, 60000)
+                                .Authorization(TAG_OS_PATCHLEVEL, 201512)
+                                .Authorization(TAG_APPLICATION_ID, "bar", 3));
+    AuthorizationSet sw_set(AuthorizationSetBuilder().Authorization(TAG_ACTIVE_DATETIME, 10));
+
+    UniquePtr<uint8_t[]> asn1;
+    size_t asn1_len;
+    EXPECT_EQ(KM_ERROR_OK, build_attestation_record(sw_set, hw_set, &asn1, &asn1_len));
+    EXPECT_GT(asn1_len, 0U);
+
+    std::ofstream output("attest.der",
+                         std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
+    if (output)
+        output.write(reinterpret_cast<const char*>(asn1.get()), asn1_len);
+    output.close();
+
+    AuthorizationSet parsed_hw_set;
+    AuthorizationSet parsed_sw_set;
+    EXPECT_EQ(KM_ERROR_OK,
+              parse_attestation_record(asn1.get(), asn1_len, &parsed_sw_set, &parsed_hw_set));
+
+    hw_set.Sort();
+    sw_set.Sort();
+    parsed_hw_set.Sort();
+    parsed_sw_set.Sort();
+    EXPECT_EQ(hw_set, parsed_hw_set);
+    EXPECT_EQ(sw_set, parsed_sw_set);
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/auth_encrypted_key_blob.cpp b/keymaster/auth_encrypted_key_blob.cpp
new file mode 100644
index 0000000..655bc12
--- /dev/null
+++ b/keymaster/auth_encrypted_key_blob.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright 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.
+ */
+
+#include "auth_encrypted_key_blob.h"
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/logger.h>
+
+#include "ocb_utils.h"
+
+namespace keymaster {
+
+const uint32_t CURRENT_BLOB_VERSION = 0;
+
+keymaster_error_t SerializeAuthEncryptedBlob(const KeymasterKeyBlob& encrypted_key_material,
+                                             const AuthorizationSet& hw_enforced,
+                                             const AuthorizationSet& sw_enforced,
+
+                                             const Buffer& nonce, const Buffer& tag,
+                                             KeymasterKeyBlob* key_blob) {
+    size_t size = 1 /* version byte */ + nonce.SerializedSize() +
+                  encrypted_key_material.SerializedSize() + tag.SerializedSize() +
+                  hw_enforced.SerializedSize() + sw_enforced.SerializedSize();
+
+    if (!key_blob->Reset(size))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    uint8_t* buf = key_blob->writable_data();
+    const uint8_t* end = key_blob->key_material + key_blob->key_material_size;
+
+    *buf++ = CURRENT_BLOB_VERSION;
+    buf = nonce.Serialize(buf, end);
+    buf = encrypted_key_material.Serialize(buf, end);
+    buf = tag.Serialize(buf, end);
+    buf = hw_enforced.Serialize(buf, end);
+    buf = sw_enforced.Serialize(buf, end);
+    if (buf != key_blob->key_material + key_blob->key_material_size)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    return KM_ERROR_OK;
+}
+
+static keymaster_error_t DeserializeUnversionedBlob(const KeymasterKeyBlob& key_blob,
+                                                    KeymasterKeyBlob* encrypted_key_material,
+                                                    AuthorizationSet* hw_enforced,
+                                                    AuthorizationSet* sw_enforced, Buffer* nonce,
+                                                    Buffer* tag) {
+    const uint8_t* tmp = key_blob.key_material;
+    const uint8_t** buf_ptr = &tmp;
+    const uint8_t* end = tmp + key_blob.key_material_size;
+
+    if (!nonce->reserve(OCB_NONCE_LENGTH) || !tag->reserve(OCB_TAG_LENGTH))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (!copy_from_buf(buf_ptr, end, nonce->peek_write(), OCB_NONCE_LENGTH) ||
+        !encrypted_key_material->Deserialize(buf_ptr, end) ||
+        !copy_from_buf(buf_ptr, end, tag->peek_write(), OCB_TAG_LENGTH) ||
+        !hw_enforced->Deserialize(buf_ptr, end) ||  //
+        !sw_enforced->Deserialize(buf_ptr, end)) {
+        LOG_D("Failed to deserialize unversioned blob (may be a HW-backed key)", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+    if (!nonce->advance_write(OCB_NONCE_LENGTH) || !tag->advance_write(OCB_TAG_LENGTH))
+        return KM_ERROR_UNKNOWN_ERROR;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t DeserializeAuthEncryptedBlob(const KeymasterKeyBlob& key_blob,
+                                               KeymasterKeyBlob* encrypted_key_material,
+                                               AuthorizationSet* hw_enforced,
+                                               AuthorizationSet* sw_enforced, Buffer* nonce,
+                                               Buffer* tag) {
+    if (!key_blob.key_material || key_blob.key_material_size == 0)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    const uint8_t* tmp = key_blob.key_material;
+    const uint8_t** buf_ptr = &tmp;
+    const uint8_t* end = tmp + key_blob.key_material_size;
+
+    if (end <= *buf_ptr)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    uint8_t version = *(*buf_ptr)++;
+    if (version != CURRENT_BLOB_VERSION ||  //
+        !nonce->Deserialize(buf_ptr, end) || nonce->available_read() != OCB_NONCE_LENGTH ||
+        !encrypted_key_material->Deserialize(buf_ptr, end) ||  //
+        !tag->Deserialize(buf_ptr, end) || tag->available_read() != OCB_TAG_LENGTH ||
+        !hw_enforced->Deserialize(buf_ptr, end) ||  //
+        !sw_enforced->Deserialize(buf_ptr, end)) {
+        // This blob failed to parse.  Either it's corrupted or it's a blob generated by an earlier
+        // version of keymaster using a previous blob format which did not include the version byte
+        // or the nonce or tag length fields.  So we try to parse it as that previous version.
+        //
+        // Note that it's not really a problem if we erronously parse a corrupted blob, because
+        // decryption will fail the authentication check.
+        //
+        // A bigger potential problem is: What if a valid unversioned blob appears to parse
+        // correctly as a versioned blob?  It would then be rejected during decryption, causing a
+        // valid key to become unusable.  If this is a disk encryption key, upgrading to a keymaster
+        // version with the new format would destroy the user's data.
+        //
+        // What is the probability that an unversioned key could be successfully parsed as a version
+        // 0 key?  The first 12 bytes of an unversioned key are the nonce, which, in the only
+        // keymaster version released with unversioned keys, is chosen randomly.  In order for an
+        // unversioned key to parse as a version 0 key, the following must be true about the first
+        // five of those random bytes:
+        //
+        // 1.  The first byte must be zero.  This will happen with probability 1/2^8.
+        //
+        // 2.  The second through fifth bytes must contain an unsigned integer value equal to
+        //     NONCE_LENGTH.  This will happen with probability 1/2^32.
+        //
+        // Based on those two checks alone, the probability of interpreting an unversioned blob as a
+        // version 0 blob is 1/2^40.  That's small enough to be negligible, but there are additional
+        // checks which lower it further.
+        LOG_D("Failed to deserialize versioned key blob.  Assuming unversioned.", 0);
+        return DeserializeUnversionedBlob(key_blob, encrypted_key_material, hw_enforced,
+                                          sw_enforced, nonce, tag);
+    }
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/auth_encrypted_key_blob.h b/keymaster/auth_encrypted_key_blob.h
new file mode 100644
index 0000000..b987d77
--- /dev/null
+++ b/keymaster/auth_encrypted_key_blob.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_AUTH_ENCRYPTED_KEY_BLOB_H_
+#define SYSTEM_KEYMASTER_AUTH_ENCRYPTED_KEY_BLOB_H_
+
+#include <hardware/keymaster_defs.h>
+
+namespace keymaster {
+
+class AuthorizationSet;
+class Buffer;
+struct KeymasterKeyBlob;
+
+keymaster_error_t SerializeAuthEncryptedBlob(const KeymasterKeyBlob& encrypted_key_material,
+                                             const AuthorizationSet& hw_enforced,
+                                             const AuthorizationSet& sw_enforced,
+                                             const Buffer& nonce, const Buffer& tag,
+                                             KeymasterKeyBlob* key_blob);
+
+keymaster_error_t DeserializeAuthEncryptedBlob(const KeymasterKeyBlob& key_blob,
+                                               KeymasterKeyBlob* encrypted_key_material,
+                                               AuthorizationSet* hw_enforced,
+                                               AuthorizationSet* sw_enforced, Buffer* nonce,
+                                               Buffer* tag);
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_AUTH_ENCRYPTED_KEY_BLOB_H_
diff --git a/keymaster/authorization_set.cpp b/keymaster/authorization_set.cpp
new file mode 100644
index 0000000..09093c9
--- /dev/null
+++ b/keymaster/authorization_set.cpp
@@ -0,0 +1,616 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <keymaster/authorization_set.h>
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <new>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+static inline bool is_blob_tag(keymaster_tag_t tag) {
+    return (keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM);
+}
+
+const size_t STARTING_ELEMS_CAPACITY = 8;
+
+AuthorizationSet::AuthorizationSet(AuthorizationSetBuilder& builder) {
+    elems_ = builder.set.elems_;
+    builder.set.elems_ = NULL;
+
+    elems_size_ = builder.set.elems_size_;
+    builder.set.elems_size_ = 0;
+
+    elems_capacity_ = builder.set.elems_capacity_;
+    builder.set.elems_capacity_ = 0;
+
+    indirect_data_ = builder.set.indirect_data_;
+    builder.set.indirect_data_ = NULL;
+
+    indirect_data_capacity_ = builder.set.indirect_data_capacity_;
+    builder.set.indirect_data_capacity_ = 0;
+
+    indirect_data_size_ = builder.set.indirect_data_size_;
+    builder.set.indirect_data_size_ = 0;
+
+    error_ = builder.set.error_;
+    builder.set.error_ = OK;
+}
+
+AuthorizationSet::~AuthorizationSet() {
+    FreeData();
+}
+
+bool AuthorizationSet::reserve_elems(size_t count) {
+    if (is_valid() != OK)
+        return false;
+
+    if (count >= elems_capacity_) {
+        keymaster_key_param_t* new_elems = new (std::nothrow) keymaster_key_param_t[count];
+        if (new_elems == NULL) {
+            set_invalid(ALLOCATION_FAILURE);
+            return false;
+        }
+        memcpy(new_elems, elems_, sizeof(*elems_) * elems_size_);
+        delete[] elems_;
+        elems_ = new_elems;
+        elems_capacity_ = count;
+    }
+    return true;
+}
+
+bool AuthorizationSet::reserve_indirect(size_t length) {
+    if (is_valid() != OK)
+        return false;
+
+    if (length > indirect_data_capacity_) {
+        uint8_t* new_data = new (std::nothrow) uint8_t[length];
+        if (new_data == NULL) {
+            set_invalid(ALLOCATION_FAILURE);
+            return false;
+        }
+        memcpy(new_data, indirect_data_, indirect_data_size_);
+
+        // Fix up the data pointers to point into the new region.
+        for (size_t i = 0; i < elems_size_; ++i) {
+            if (is_blob_tag(elems_[i].tag))
+                elems_[i].blob.data = new_data + (elems_[i].blob.data - indirect_data_);
+        }
+        delete[] indirect_data_;
+        indirect_data_ = new_data;
+        indirect_data_capacity_ = length;
+    }
+    return true;
+}
+
+bool AuthorizationSet::Reinitialize(const keymaster_key_param_t* elems, const size_t count) {
+    FreeData();
+
+    if (elems == NULL || count == 0) {
+        error_ = OK;
+        return true;
+    }
+
+    if (!reserve_elems(count))
+        return false;
+
+    if (!reserve_indirect(ComputeIndirectDataSize(elems, count)))
+        return false;
+
+    memcpy(elems_, elems, sizeof(keymaster_key_param_t) * count);
+    elems_size_ = count;
+    CopyIndirectData();
+    error_ = OK;
+    return true;
+}
+
+void AuthorizationSet::set_invalid(Error error) {
+    FreeData();
+    error_ = error;
+}
+
+void AuthorizationSet::Sort() {
+    qsort(elems_, elems_size_, sizeof(*elems_),
+          reinterpret_cast<int (*)(const void*, const void*)>(keymaster_param_compare));
+}
+
+void AuthorizationSet::Deduplicate() {
+    Sort();
+
+    size_t invalid_count = 0;
+    for (size_t i = 1; i < size(); ++i) {
+        if (elems_[i - 1].tag == KM_TAG_INVALID)
+            ++invalid_count;
+        else if (keymaster_param_compare(elems_ + i - 1, elems_ + i) == 0) {
+            // Mark dups as invalid.  Note that this "leaks" the data referenced by KM_BYTES and
+            // KM_BIGNUM entries, but those are just pointers into indirect_data_, so it will all
+            // get cleaned up.
+            elems_[i - 1].tag = KM_TAG_INVALID;
+            ++invalid_count;
+        }
+    }
+    if (size() > 0 && elems_[size() - 1].tag == KM_TAG_INVALID)
+        ++invalid_count;
+
+    if (invalid_count == 0)
+        return;
+
+    Sort();
+
+    // Since KM_TAG_INVALID == 0, all of the invalid entries are first.
+    elems_size_ -= invalid_count;
+    memmove(elems_, elems_ + invalid_count, size() * sizeof(*elems_));
+}
+
+void AuthorizationSet::CopyToParamSet(keymaster_key_param_set_t* set) const {
+    assert(set);
+
+    set->length = size();
+    set->params =
+        reinterpret_cast<keymaster_key_param_t*>(malloc(sizeof(keymaster_key_param_t) * size()));
+
+    for (size_t i = 0; i < size(); ++i) {
+        const keymaster_key_param_t src = (*this)[i];
+        keymaster_key_param_t& dst(set->params[i]);
+
+        dst = src;
+        keymaster_tag_type_t type = keymaster_tag_get_type(src.tag);
+        if (type == KM_BIGNUM || type == KM_BYTES) {
+            void* tmp = malloc(src.blob.data_length);
+            memcpy(tmp, src.blob.data, src.blob.data_length);
+            dst.blob.data = reinterpret_cast<uint8_t*>(tmp);
+        }
+    }
+}
+
+int AuthorizationSet::find(keymaster_tag_t tag, int begin) const {
+    if (is_valid() != OK)
+        return -1;
+
+    int i = ++begin;
+    while (i < (int)elems_size_ && elems_[i].tag != tag)
+        ++i;
+    if (i == (int)elems_size_)
+        return -1;
+    else
+        return i;
+}
+
+bool AuthorizationSet::erase(size_t index) {
+    if (index >= size())
+        return false;
+
+    --elems_size_;
+    for (size_t i = index; i < elems_size_; ++i)
+        elems_[i] = elems_[i + 1];
+    return true;
+}
+
+keymaster_key_param_t empty_set = {KM_TAG_INVALID, {}};
+keymaster_key_param_t& AuthorizationSet::operator[](int at) {
+    if (is_valid() == OK && at < (int)elems_size_) {
+        return elems_[at];
+    }
+    empty_set = {KM_TAG_INVALID, {}};
+    return empty_set;
+}
+
+keymaster_key_param_t AuthorizationSet::operator[](int at) const {
+    if (is_valid() == OK && at < (int)elems_size_) {
+        return elems_[at];
+    }
+    empty_set = {KM_TAG_INVALID, {}};
+    return empty_set;
+}
+
+bool AuthorizationSet::push_back(const keymaster_key_param_set_t& set) {
+    if (is_valid() != OK)
+        return false;
+
+    if (!reserve_elems(elems_size_ + set.length))
+        return false;
+
+    if (!reserve_indirect(indirect_data_size_ + ComputeIndirectDataSize(set.params, set.length)))
+        return false;
+
+    for (size_t i = 0; i < set.length; ++i)
+        if (!push_back(set.params[i]))
+            return false;
+
+    return true;
+}
+
+bool AuthorizationSet::push_back(keymaster_key_param_t elem) {
+    if (is_valid() != OK)
+        return false;
+
+    if (elems_size_ >= elems_capacity_)
+        if (!reserve_elems(elems_capacity_ ? elems_capacity_ * 2 : STARTING_ELEMS_CAPACITY))
+            return false;
+
+    if (is_blob_tag(elem.tag)) {
+        if (indirect_data_capacity_ - indirect_data_size_ < elem.blob.data_length)
+            if (!reserve_indirect(2 * (indirect_data_capacity_ + elem.blob.data_length)))
+                return false;
+
+        memcpy(indirect_data_ + indirect_data_size_, elem.blob.data, elem.blob.data_length);
+        elem.blob.data = indirect_data_ + indirect_data_size_;
+        indirect_data_size_ += elem.blob.data_length;
+    }
+
+    elems_[elems_size_++] = elem;
+    return true;
+}
+
+static size_t serialized_size(const keymaster_key_param_t& param) {
+    switch (keymaster_tag_get_type(param.tag)) {
+    case KM_INVALID:
+        return sizeof(uint32_t);
+    case KM_ENUM:
+    case KM_ENUM_REP:
+    case KM_UINT:
+    case KM_UINT_REP:
+        return sizeof(uint32_t) * 2;
+    case KM_ULONG:
+    case KM_ULONG_REP:
+    case KM_DATE:
+        return sizeof(uint32_t) + sizeof(uint64_t);
+    case KM_BOOL:
+        return sizeof(uint32_t) + 1;
+    case KM_BIGNUM:
+    case KM_BYTES:
+        return sizeof(uint32_t) * 3;
+    }
+
+    return sizeof(uint32_t);
+}
+
+static uint8_t* serialize(const keymaster_key_param_t& param, uint8_t* buf, const uint8_t* end,
+                          const uint8_t* indirect_base) {
+    buf = append_uint32_to_buf(buf, end, param.tag);
+    switch (keymaster_tag_get_type(param.tag)) {
+    case KM_INVALID:
+        break;
+    case KM_ENUM:
+    case KM_ENUM_REP:
+        buf = append_uint32_to_buf(buf, end, param.enumerated);
+        break;
+    case KM_UINT:
+    case KM_UINT_REP:
+        buf = append_uint32_to_buf(buf, end, param.integer);
+        break;
+    case KM_ULONG:
+    case KM_ULONG_REP:
+        buf = append_uint64_to_buf(buf, end, param.long_integer);
+        break;
+    case KM_DATE:
+        buf = append_uint64_to_buf(buf, end, param.date_time);
+        break;
+    case KM_BOOL:
+        if (buf < end)
+            *buf = static_cast<uint8_t>(param.boolean);
+        buf++;
+        break;
+    case KM_BIGNUM:
+    case KM_BYTES:
+        buf = append_uint32_to_buf(buf, end, param.blob.data_length);
+        buf = append_uint32_to_buf(buf, end, param.blob.data - indirect_base);
+        break;
+    }
+    return buf;
+}
+
+static bool deserialize(keymaster_key_param_t* param, const uint8_t** buf_ptr, const uint8_t* end,
+                        const uint8_t* indirect_base, const uint8_t* indirect_end) {
+    if (!copy_uint32_from_buf(buf_ptr, end, &param->tag))
+        return false;
+
+    switch (keymaster_tag_get_type(param->tag)) {
+    case KM_INVALID:
+        return false;
+    case KM_ENUM:
+    case KM_ENUM_REP:
+        return copy_uint32_from_buf(buf_ptr, end, &param->enumerated);
+    case KM_UINT:
+    case KM_UINT_REP:
+        return copy_uint32_from_buf(buf_ptr, end, &param->integer);
+    case KM_ULONG:
+    case KM_ULONG_REP:
+        return copy_uint64_from_buf(buf_ptr, end, &param->long_integer);
+    case KM_DATE:
+        return copy_uint64_from_buf(buf_ptr, end, &param->date_time);
+        break;
+    case KM_BOOL:
+        if (*buf_ptr < end) {
+            param->boolean = static_cast<bool>(**buf_ptr);
+            (*buf_ptr)++;
+            return true;
+        }
+        return false;
+
+    case KM_BIGNUM:
+    case KM_BYTES: {
+        uint32_t offset;
+        if (!copy_uint32_from_buf(buf_ptr, end, &param->blob.data_length) ||
+            !copy_uint32_from_buf(buf_ptr, end, &offset))
+            return false;
+        if (param->blob.data_length + offset < param->blob.data_length ||  // Overflow check
+            static_cast<ptrdiff_t>(offset) > indirect_end - indirect_base ||
+            static_cast<ptrdiff_t>(offset + param->blob.data_length) > indirect_end - indirect_base)
+            return false;
+        param->blob.data = indirect_base + offset;
+        return true;
+    }
+    }
+
+    return false;
+}
+
+size_t AuthorizationSet::SerializedSizeOfElements() const {
+    size_t size = 0;
+    for (size_t i = 0; i < elems_size_; ++i) {
+        size += serialized_size(elems_[i]);
+    }
+    return size;
+}
+
+size_t AuthorizationSet::SerializedSize() const {
+    return sizeof(uint32_t) +           // Size of indirect_data_
+           indirect_data_size_ +        // indirect_data_
+           sizeof(uint32_t) +           // Number of elems_
+           sizeof(uint32_t) +           // Size of elems_
+           SerializedSizeOfElements();  // elems_
+}
+
+uint8_t* AuthorizationSet::Serialize(uint8_t* buf, const uint8_t* end) const {
+    buf = append_size_and_data_to_buf(buf, end, indirect_data_, indirect_data_size_);
+    buf = append_uint32_to_buf(buf, end, elems_size_);
+    buf = append_uint32_to_buf(buf, end, SerializedSizeOfElements());
+    for (size_t i = 0; i < elems_size_; ++i) {
+        buf = serialize(elems_[i], buf, end, indirect_data_);
+    }
+    return buf;
+}
+
+bool AuthorizationSet::DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end) {
+    UniquePtr<uint8_t[]> indirect_buf;
+    if (!copy_size_and_data_from_buf(buf_ptr, end, &indirect_data_size_, &indirect_buf)) {
+        LOG_E("Malformed data found in AuthorizationSet deserialization", 0);
+        set_invalid(MALFORMED_DATA);
+        return false;
+    }
+    indirect_data_ = indirect_buf.release();
+    return true;
+}
+
+bool AuthorizationSet::DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end) {
+    uint32_t elements_count;
+    uint32_t elements_size;
+    if (!copy_uint32_from_buf(buf_ptr, end, &elements_count) ||
+        !copy_uint32_from_buf(buf_ptr, end, &elements_size)) {
+        LOG_E("Malformed data found in AuthorizationSet deserialization", 0);
+        set_invalid(MALFORMED_DATA);
+        return false;
+    }
+
+    // Note that the following validation of elements_count is weak, but it prevents allocation of
+    // elems_ arrays which are clearly too large to be reasonable.
+    if (static_cast<ptrdiff_t>(elements_size) > end - *buf_ptr ||
+        elements_count * sizeof(uint32_t) > elements_size ||
+        *buf_ptr + (elements_count * sizeof(*elems_)) < *buf_ptr) {
+        LOG_E("Malformed data found in AuthorizationSet deserialization", 0);
+        set_invalid(MALFORMED_DATA);
+        return false;
+    }
+
+    if (!reserve_elems(elements_count))
+        return false;
+
+    uint8_t* indirect_end = indirect_data_ + indirect_data_size_;
+    const uint8_t* elements_end = *buf_ptr + elements_size;
+    for (size_t i = 0; i < elements_count; ++i) {
+        if (!deserialize(elems_ + i, buf_ptr, elements_end, indirect_data_, indirect_end)) {
+            LOG_E("Malformed data found in AuthorizationSet deserialization", 0);
+            set_invalid(MALFORMED_DATA);
+            return false;
+        }
+    }
+    elems_size_ = elements_count;
+    return true;
+}
+
+bool AuthorizationSet::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    FreeData();
+
+    if (!DeserializeIndirectData(buf_ptr, end) || !DeserializeElementsData(buf_ptr, end))
+        return false;
+
+    if (indirect_data_size_ != ComputeIndirectDataSize(elems_, elems_size_)) {
+        LOG_E("Malformed data found in AuthorizationSet deserialization", 0);
+        set_invalid(MALFORMED_DATA);
+        return false;
+    }
+    return true;
+}
+
+void AuthorizationSet::Clear() {
+    memset_s(elems_, 0, elems_size_ * sizeof(keymaster_key_param_t));
+    memset_s(indirect_data_, 0, indirect_data_size_);
+    elems_size_ = 0;
+    indirect_data_size_ = 0;
+}
+
+void AuthorizationSet::FreeData() {
+    Clear();
+
+    delete[] elems_;
+    delete[] indirect_data_;
+
+    elems_ = NULL;
+    indirect_data_ = NULL;
+    elems_capacity_ = 0;
+    indirect_data_capacity_ = 0;
+    error_ = OK;
+}
+
+/* static */
+size_t AuthorizationSet::ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count) {
+    size_t size = 0;
+    for (size_t i = 0; i < count; ++i) {
+        if (is_blob_tag(elems[i].tag)) {
+            size += elems[i].blob.data_length;
+        }
+    }
+    return size;
+}
+
+void AuthorizationSet::CopyIndirectData() {
+    memset_s(indirect_data_, 0, indirect_data_capacity_);
+
+    uint8_t* indirect_data_pos = indirect_data_;
+    for (size_t i = 0; i < elems_size_; ++i) {
+        assert(indirect_data_pos <= indirect_data_ + indirect_data_capacity_);
+        if (is_blob_tag(elems_[i].tag)) {
+            memcpy(indirect_data_pos, elems_[i].blob.data, elems_[i].blob.data_length);
+            elems_[i].blob.data = indirect_data_pos;
+            indirect_data_pos += elems_[i].blob.data_length;
+        }
+    }
+    assert(indirect_data_pos == indirect_data_ + indirect_data_capacity_);
+    indirect_data_size_ = indirect_data_pos - indirect_data_;
+}
+
+size_t AuthorizationSet::GetTagCount(keymaster_tag_t tag) const {
+    size_t count = 0;
+    for (int pos = -1; (pos = find(tag, pos)) != -1;)
+        ++count;
+    return count;
+}
+
+bool AuthorizationSet::GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const {
+    int pos = find(tag);
+    if (pos == -1) {
+        return false;
+    }
+    *val = elems_[pos].enumerated;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueEnumRep(keymaster_tag_t tag, size_t instance,
+                                          uint32_t* val) const {
+    size_t count = 0;
+    int pos = -1;
+    while (count <= instance) {
+        pos = find(tag, pos);
+        if (pos == -1) {
+            return false;
+        }
+        ++count;
+    }
+    *val = elems_[pos].enumerated;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const {
+    int pos = find(tag);
+    if (pos == -1) {
+        return false;
+    }
+    *val = elems_[pos].integer;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueIntRep(keymaster_tag_t tag, size_t instance,
+                                         uint32_t* val) const {
+    size_t count = 0;
+    int pos = -1;
+    while (count <= instance) {
+        pos = find(tag, pos);
+        if (pos == -1) {
+            return false;
+        }
+        ++count;
+    }
+    *val = elems_[pos].integer;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const {
+    int pos = find(tag);
+    if (pos == -1) {
+        return false;
+    }
+    *val = elems_[pos].long_integer;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueLongRep(keymaster_tag_t tag, size_t instance,
+                                          uint64_t* val) const {
+    size_t count = 0;
+    int pos = -1;
+    while (count <= instance) {
+        pos = find(tag, pos);
+        if (pos == -1) {
+            return false;
+        }
+        ++count;
+    }
+    *val = elems_[pos].long_integer;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const {
+    int pos = find(tag);
+    if (pos == -1) {
+        return false;
+    }
+    *val = elems_[pos].date_time;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const {
+    int pos = find(tag);
+    if (pos == -1) {
+        return false;
+    }
+    *val = elems_[pos].blob;
+    return true;
+}
+
+bool AuthorizationSet::GetTagValueBool(keymaster_tag_t tag) const {
+    int pos = find(tag);
+    if (pos == -1) {
+        return false;
+    }
+    assert(elems_[pos].boolean);
+    return elems_[pos].boolean;
+}
+
+bool AuthorizationSet::ContainsEnumValue(keymaster_tag_t tag, uint32_t value) const {
+    for (auto& entry : *this)
+        if (entry.tag == tag && entry.enumerated == value)
+            return true;
+    return false;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/authorization_set_test.cpp b/keymaster/authorization_set_test.cpp
new file mode 100644
index 0000000..ddc7df3
--- /dev/null
+++ b/keymaster/authorization_set_test.cpp
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <keymaster/authorization_set.h>
+#include <keymaster/android_keymaster_utils.h>
+
+#include "android_keymaster_test_utils.h"
+
+namespace keymaster {
+
+namespace test {
+
+TEST(Construction, ListProvided) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_USER_ID, 7),
+        Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD),
+        Authorization(TAG_APPLICATION_ID, "my_app", 6), Authorization(TAG_KEY_SIZE, 256),
+        Authorization(TAG_AUTH_TIMEOUT, 300),
+    };
+    AuthorizationSet set(params, array_length(params));
+    EXPECT_EQ(8U, set.size());
+}
+
+TEST(Construction, Copy) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_USER_ID, 7),
+        Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD),
+        Authorization(TAG_APPLICATION_ID, "my_app", 6), Authorization(TAG_KEY_SIZE, 256),
+        Authorization(TAG_AUTH_TIMEOUT, 300),
+    };
+    AuthorizationSet set(params, array_length(params));
+    AuthorizationSet set2(set);
+    EXPECT_EQ(set, set2);
+}
+
+TEST(Construction, NullProvided) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+    };
+
+    AuthorizationSet set1(params, 0);
+    EXPECT_EQ(0U, set1.size());
+    EXPECT_EQ(AuthorizationSet::OK, set1.is_valid());
+
+    AuthorizationSet set2(reinterpret_cast<keymaster_key_param_t*>(NULL), array_length(params));
+    EXPECT_EQ(0U, set2.size());
+    EXPECT_EQ(AuthorizationSet::OK, set2.is_valid());
+}
+
+TEST(Lookup, NonRepeated) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_KEY_SIZE, 256)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    EXPECT_EQ(8U, set.size());
+
+    int pos = set.find(TAG_ALGORITHM);
+    ASSERT_NE(-1, pos);
+    EXPECT_EQ(KM_TAG_ALGORITHM, set[pos].tag);
+    EXPECT_EQ(KM_ALGORITHM_RSA, set[pos].enumerated);
+
+    pos = set.find(TAG_MAC_LENGTH);
+    EXPECT_EQ(-1, pos);
+
+    uint32_t int_val = 0;
+    EXPECT_TRUE(set.GetTagValue(TAG_USER_ID, &int_val));
+    EXPECT_EQ(7U, int_val);
+
+    keymaster_blob_t blob_val;
+    EXPECT_TRUE(set.GetTagValue(TAG_APPLICATION_ID, &blob_val));
+    EXPECT_EQ(6U, blob_val.data_length);
+    EXPECT_EQ(0, memcmp(blob_val.data, "my_app", 6));
+}
+
+TEST(Lookup, Repeated) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_SECURE_ID, 47727)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_KEY_SIZE, 256)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+    EXPECT_EQ(9U, set.size());
+
+    int pos = set.find(TAG_PURPOSE);
+    ASSERT_FALSE(pos == -1);
+    EXPECT_EQ(KM_TAG_PURPOSE, set[pos].tag);
+    EXPECT_EQ(KM_PURPOSE_SIGN, set[pos].enumerated);
+
+    pos = set.find(TAG_PURPOSE, pos);
+    EXPECT_EQ(KM_TAG_PURPOSE, set[pos].tag);
+    EXPECT_EQ(KM_PURPOSE_VERIFY, set[pos].enumerated);
+
+    EXPECT_EQ(-1, set.find(TAG_PURPOSE, pos));
+
+    pos = set.find(TAG_USER_SECURE_ID, pos);
+    EXPECT_EQ(KM_TAG_USER_SECURE_ID, set[pos].tag);
+    EXPECT_EQ(47727U, set[pos].long_integer);
+}
+
+TEST(Lookup, Indexed) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_KEY_SIZE, 256)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+    EXPECT_EQ(8U, set.size());
+
+    EXPECT_EQ(KM_TAG_PURPOSE, set[0].tag);
+    EXPECT_EQ(KM_PURPOSE_SIGN, set[0].enumerated);
+
+    // Lookup beyond end doesn't work, just returns zeros, but doens't blow up either (verify by
+    // running under valgrind).
+    EXPECT_EQ(KM_TAG_INVALID, set[10].tag);
+}
+
+TEST(Serialization, RoundTrip) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_KEY_SIZE, 256)
+                             .Authorization(TAG_USER_SECURE_ID, 47727)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300)
+                             .Authorization(TAG_ALL_USERS)
+                             .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)
+                             .Authorization(TAG_ACTIVE_DATETIME, 10));
+
+    size_t size = set.SerializedSize();
+    EXPECT_TRUE(size > 0);
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
+    AuthorizationSet deserialized(buf.get(), size);
+
+    EXPECT_EQ(AuthorizationSet::OK, deserialized.is_valid());
+    EXPECT_EQ(set, deserialized);
+
+    int pos = deserialized.find(TAG_APPLICATION_ID);
+    ASSERT_NE(-1, pos);
+    EXPECT_EQ(KM_TAG_APPLICATION_ID, deserialized[pos].tag);
+    EXPECT_EQ(6U, deserialized[pos].blob.data_length);
+    EXPECT_EQ(0, memcmp(deserialized[pos].blob.data, "my_app", 6));
+}
+
+TEST(Deserialization, Deserialize) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_KEY_SIZE, 256)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    size_t size = set.SerializedSize();
+    EXPECT_TRUE(size > 0);
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
+    AuthorizationSet deserialized;
+    const uint8_t* p = buf.get();
+    EXPECT_TRUE(deserialized.Deserialize(&p, p + size));
+    EXPECT_EQ(p, buf.get() + size);
+
+    EXPECT_EQ(AuthorizationSet::OK, deserialized.is_valid());
+
+    EXPECT_EQ(set.size(), deserialized.size());
+    for (size_t i = 0; i < set.size(); ++i) {
+        EXPECT_EQ(set[i].tag, deserialized[i].tag);
+    }
+
+    int pos = deserialized.find(TAG_APPLICATION_ID);
+    ASSERT_NE(-1, pos);
+    EXPECT_EQ(KM_TAG_APPLICATION_ID, deserialized[pos].tag);
+    EXPECT_EQ(6U, deserialized[pos].blob.data_length);
+    EXPECT_EQ(0, memcmp(deserialized[pos].blob.data, "my_app", 6));
+}
+
+TEST(Deserialization, TooShortBuffer) {
+    uint8_t buf[] = {0, 0, 0};
+    AuthorizationSet deserialized(buf, array_length(buf));
+    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
+
+    const uint8_t* p = buf;
+    EXPECT_FALSE(deserialized.Deserialize(&p, p + array_length(buf)));
+    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
+}
+
+TEST(Deserialization, InvalidLengthField) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_KEY_SIZE, 256)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    size_t size = set.SerializedSize();
+    EXPECT_TRUE(size > 0);
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
+    *reinterpret_cast<uint32_t*>(buf.get()) = 9;
+
+    AuthorizationSet deserialized(buf.get(), size);
+    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
+
+    const uint8_t* p = buf.get();
+    EXPECT_FALSE(deserialized.Deserialize(&p, p + size));
+    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized.is_valid());
+}
+
+static uint32_t read_uint32(const uint8_t* buf) {
+    uint32_t val;
+    memcpy(&val, buf, sizeof(val));
+    return val;
+}
+
+static void add_to_uint32(uint8_t* buf, int delta) {
+    uint32_t val;
+    memcpy(&val, buf, sizeof(val));
+    val += delta;
+    memcpy(buf, &val, sizeof(val));
+}
+
+TEST(Deserialization, MalformedIndirectData) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_APPLICATION_DATA, "foo", 3));
+    size_t size = set.SerializedSize();
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[size]);
+    EXPECT_EQ(buf.get() + size, set.Serialize(buf.get(), buf.get() + size));
+
+    // This sucks.  This test, as written, requires intimate knowledge of the serialized layout of
+    // this particular set, which means it's brittle.  But it's important to test that we handle
+    // broken serialized data and I can't think of a better way to write this.
+    //
+    // The contents of buf are:
+    //
+    // Bytes:   Content:
+    // 0-3      Length of string data, which is 9.
+    // 4-9      "my_app"
+    // 10-12    "foo"
+    // 13-16    Number of elements, which is 2.
+    // 17-20    Length of elements, which is 24.
+    // 21-24    First tag, TAG_APPLICATION_ID
+    // 25-28    Length of string "my_app", 6
+    // 29-32    Offset of string "my_app", 0
+    // 33-36    Second tag, TAG_APPLICATION_DATA
+    // 37-40    Length of string "foo", 3
+    // 41-44    Offset of string "foo", 6
+
+    // Check that stuff is where we think.
+    EXPECT_EQ('m', buf[4]);
+    EXPECT_EQ('f', buf[10]);
+    // Length of "my_app"
+    EXPECT_EQ(6U, read_uint32(buf.get() + 25));
+    // Offset of "my_app"
+    EXPECT_EQ(0U, read_uint32(buf.get() + 29));
+    // Length of "foo"
+    EXPECT_EQ(3U, read_uint32(buf.get() + 37));
+    // Offset of "foo"
+    EXPECT_EQ(6U, read_uint32(buf.get() + 41));
+
+    // Check that deserialization works.
+    AuthorizationSet deserialized1(buf.get(), size);
+    EXPECT_EQ(AuthorizationSet::OK, deserialized1.is_valid());
+
+    const uint8_t* p = buf.get();
+    EXPECT_TRUE(deserialized1.Deserialize(&p, p + size));
+    EXPECT_EQ(AuthorizationSet::OK, deserialized1.is_valid());
+
+    //
+    // Now mess them up in various ways:
+    //
+
+    // Move "foo" offset so offset + length goes off the end
+    add_to_uint32(buf.get() + 41, 1);
+    AuthorizationSet deserialized2(buf.get(), size);
+    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized2.is_valid());
+    add_to_uint32(buf.get() + 41, -1);
+
+    // Shorten the "my_app" length to make a gap between the blobs.
+    add_to_uint32(buf.get() + 25, -1);
+    AuthorizationSet deserialized3(buf.get(), size);
+    EXPECT_EQ(AuthorizationSet::MALFORMED_DATA, deserialized3.is_valid());
+    add_to_uint32(buf.get() + 25, 1);
+
+    // Extend the "my_app" length to make them overlap, and decrease the "foo" length to keep the
+    // total length the same.  We don't detect this but should.
+    // TODO(swillden): Detect overlaps and holes that leave total size correct.
+    add_to_uint32(buf.get() + 25, 1);
+    add_to_uint32(buf.get() + 37, -1);
+    AuthorizationSet deserialized4(buf.get(), size);
+    EXPECT_EQ(AuthorizationSet::OK, deserialized4.is_valid());
+}
+
+TEST(Growable, SuccessfulRoundTrip) {
+    AuthorizationSet growable;
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)));
+    EXPECT_EQ(1U, growable.size());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)));
+    EXPECT_EQ(2U, growable.size());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)));
+    EXPECT_EQ(3U, growable.size());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_ID, "data", 4)));
+    EXPECT_EQ(4U, growable.size());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_DATA, "some more data", 14)));
+    EXPECT_EQ(5U, growable.size());
+
+    size_t serialize_size = growable.SerializedSize();
+    UniquePtr<uint8_t[]> serialized(new uint8_t[serialize_size]);
+    EXPECT_EQ(serialized.get() + serialize_size,
+              growable.Serialize(serialized.get(), serialized.get() + serialize_size));
+
+    AuthorizationSet deserialized(serialized.get(), serialize_size);
+    EXPECT_EQ(growable, deserialized);
+}
+
+TEST(Growable, InsufficientElemBuf) {
+    AuthorizationSet growable;
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+
+    // First insertion fits.
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)));
+    EXPECT_EQ(1U, growable.size());
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+
+    // Second does too.
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)));
+    EXPECT_EQ(2U, growable.size());
+}
+
+TEST(Growable, InsufficientIndirectBuf) {
+    AuthorizationSet growable;
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)));
+    EXPECT_EQ(1U, growable.size());
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_ID, "1234567890", 10)));
+    EXPECT_EQ(2U, growable.size());
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_APPLICATION_DATA, "1", 1)));
+    EXPECT_EQ(3U, growable.size());
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+
+    // Can still add another entry without indirect data.  Now it's full.
+    EXPECT_TRUE(growable.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)));
+    EXPECT_EQ(4U, growable.size());
+    EXPECT_EQ(AuthorizationSet::OK, growable.is_valid());
+}
+
+TEST(Growable, PushBackSets) {
+    AuthorizationSetBuilder builder;
+    builder.Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+        .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+        .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+        .Authorization(TAG_USER_ID, 7)
+        .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+        .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+        .Authorization(TAG_KEY_SIZE, 256)
+        .Authorization(TAG_AUTH_TIMEOUT, 300);
+
+    AuthorizationSet set1(builder.build());
+    AuthorizationSet set2(builder.build());
+
+    AuthorizationSet combined;
+    EXPECT_TRUE(combined.push_back(set1));
+    EXPECT_TRUE(combined.push_back(set2));
+    EXPECT_EQ(set1.size() + set2.size(), combined.size());
+    EXPECT_EQ(12U, combined.indirect_size());
+}
+
+TEST(GetValue, GetInt) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    uint32_t val;
+    EXPECT_TRUE(set.GetTagValue(TAG_USER_ID, &val));
+    EXPECT_EQ(7U, val);
+
+    // Find one that isn't there
+    EXPECT_FALSE(set.GetTagValue(TAG_KEY_SIZE, &val));
+}
+
+TEST(GetValue, GetLong) {
+    AuthorizationSet set1(AuthorizationSetBuilder()
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                              .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
+
+    AuthorizationSet set2(AuthorizationSetBuilder()
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
+
+    uint64_t val;
+    EXPECT_TRUE(set1.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &val));
+    EXPECT_EQ(3U, val);
+
+    // Find one that isn't there
+    EXPECT_FALSE(set2.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &val));
+}
+
+TEST(GetValue, GetLongRep) {
+    AuthorizationSet set1(AuthorizationSetBuilder()
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                              .Authorization(TAG_USER_SECURE_ID, 8338)
+                              .Authorization(TAG_USER_SECURE_ID, 4334)
+                              .Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
+
+    AuthorizationSet set2(AuthorizationSetBuilder()
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
+
+    uint64_t val;
+    EXPECT_TRUE(set1.GetTagValue(TAG_USER_SECURE_ID, 0, &val));
+    EXPECT_EQ(8338U, val);
+    EXPECT_TRUE(set1.GetTagValue(TAG_USER_SECURE_ID, 1, &val));
+    EXPECT_EQ(4334U, val);
+
+    // Find one that isn't there
+    EXPECT_FALSE(set2.GetTagValue(TAG_USER_SECURE_ID, &val));
+}
+
+TEST(GetValue, GetEnum) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    keymaster_algorithm_t val;
+    EXPECT_TRUE(set.GetTagValue(TAG_ALGORITHM, &val));
+    EXPECT_EQ(KM_ALGORITHM_RSA, val);
+
+    // Find one that isn't there
+    keymaster_padding_t val2;
+    EXPECT_FALSE(set.GetTagValue(TAG_PADDING, &val2));
+}
+
+TEST(GetValue, GetEnumRep) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    keymaster_purpose_t val;
+    EXPECT_TRUE(set.GetTagValue(TAG_PURPOSE, 0, &val));
+    EXPECT_EQ(KM_PURPOSE_SIGN, val);
+    EXPECT_TRUE(set.GetTagValue(TAG_PURPOSE, 1, &val));
+    EXPECT_EQ(KM_PURPOSE_VERIFY, val);
+
+    // Find one that isn't there
+    EXPECT_FALSE(set.GetTagValue(TAG_PURPOSE, 2, &val));
+}
+
+TEST(GetValue, GetDate) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_ACTIVE_DATETIME, 10)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    uint64_t val;
+    EXPECT_TRUE(set.GetTagValue(TAG_ACTIVE_DATETIME, &val));
+    EXPECT_EQ(10U, val);
+
+    // Find one that isn't there
+    EXPECT_FALSE(set.GetTagValue(TAG_USAGE_EXPIRE_DATETIME, &val));
+}
+
+TEST(GetValue, GetBlob) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+                             .Authorization(TAG_APPLICATION_ID, "my_app", 6)
+                             .Authorization(TAG_AUTH_TIMEOUT, 300));
+
+    keymaster_blob_t val;
+    EXPECT_TRUE(set.GetTagValue(TAG_APPLICATION_ID, &val));
+    EXPECT_EQ(6U, val.data_length);
+    EXPECT_EQ(0, memcmp(val.data, "my_app", 6));
+
+    // Find one that isn't there
+    EXPECT_FALSE(set.GetTagValue(TAG_APPLICATION_DATA, &val));
+}
+
+TEST(Deduplication, NoDuplicates) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_ACTIVE_DATETIME, 10)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
+    AuthorizationSet copy(set);
+
+    EXPECT_EQ(copy, set);
+    set.Deduplicate();
+    EXPECT_EQ(copy.size(), set.size());
+
+    // Sets no longer compare equal, because of ordering (ugh, maybe it should be
+    // AuthorizationList, not AuthorizationSet).
+    EXPECT_NE(copy, set);
+}
+
+TEST(Deduplication, NoDuplicatesHasInvalid) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_ACTIVE_DATETIME, 10)
+                             .Authorization(TAG_INVALID)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
+    AuthorizationSet copy(set);
+
+    EXPECT_EQ(copy, set);
+    set.Deduplicate();
+
+    // Deduplicate should have removed the invalid.
+    EXPECT_EQ(copy.size() - 1, set.size());
+    EXPECT_NE(copy, set);
+}
+
+TEST(Deduplication, DuplicateEnum) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ACTIVE_DATETIME, 10)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
+    AuthorizationSet copy(set);
+
+    EXPECT_EQ(copy, set);
+    set.Deduplicate();
+    EXPECT_EQ(copy.size() - 2, set.size());
+    EXPECT_NE(copy, set);
+}
+
+TEST(Deduplication, DuplicateBlob) {
+    AuthorizationSet set(AuthorizationSetBuilder()
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_ACTIVE_DATETIME, 10)
+                             .Authorization(TAG_APPLICATION_DATA, "data", 4)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_USER_ID, 7)
+                             .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                             .Authorization(TAG_APPLICATION_DATA, "data", 4)
+                             .Authorization(TAG_APPLICATION_DATA, "foo", 3)
+                             .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD));
+    AuthorizationSet copy(set);
+
+    EXPECT_EQ(copy, set);
+    set.Deduplicate();
+    EXPECT_EQ(copy.size() - 3, set.size());
+    EXPECT_NE(copy, set);
+
+    // The real test here is that valgrind reports no leak.
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/ec_key.cpp b/keymaster/ec_key.cpp
new file mode 100644
index 0000000..64ffc7a
--- /dev/null
+++ b/keymaster/ec_key.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "ec_key.h"
+
+#if defined(OPENSSL_IS_BORINGSSL)
+typedef size_t openssl_size_t;
+#else
+typedef int openssl_size_t;
+#endif
+
+namespace keymaster {
+
+bool EcKey::EvpToInternal(const EVP_PKEY* pkey) {
+    ec_key_.reset(EVP_PKEY_get1_EC_KEY(const_cast<EVP_PKEY*>(pkey)));
+    return ec_key_.get() != NULL;
+}
+
+bool EcKey::InternalToEvp(EVP_PKEY* pkey) const {
+    return EVP_PKEY_set1_EC_KEY(pkey, ec_key_.get()) == 1;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ec_key.h b/keymaster/ec_key.h
new file mode 100644
index 0000000..8230d23
--- /dev/null
+++ b/keymaster/ec_key.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_EC_KEY_H_
+#define SYSTEM_KEYMASTER_EC_KEY_H_
+
+#include <openssl/ec.h>
+
+#include "asymmetric_key.h"
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+class EcdsaOperationFactory;
+
+class EcKey : public AsymmetricKey {
+  public:
+    EcKey(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+          keymaster_error_t* error)
+        : AsymmetricKey(hw_enforced, sw_enforced, error) {}
+
+    bool InternalToEvp(EVP_PKEY* pkey) const override;
+    bool EvpToInternal(const EVP_PKEY* pkey) override;
+
+    EC_KEY* key() const { return ec_key_.get(); }
+
+  protected:
+    EcKey(EC_KEY* ec_key, const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+          keymaster_error_t* error)
+        : AsymmetricKey(hw_enforced, sw_enforced, error), ec_key_(ec_key) {}
+
+  private:
+    UniquePtr<EC_KEY, EC_KEY_Delete> ec_key_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_EC_KEY_H_
diff --git a/keymaster/ec_key_factory.cpp b/keymaster/ec_key_factory.cpp
new file mode 100644
index 0000000..14c8327
--- /dev/null
+++ b/keymaster/ec_key_factory.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright 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.
+ */
+
+#include <keymaster/ec_key_factory.h>
+
+#include <openssl/evp.h>
+
+#include <keymaster/keymaster_context.h>
+
+#include "ec_key.h"
+#include "ecdsa_operation.h"
+#include "openssl_err.h"
+
+namespace keymaster {
+
+static EcdsaSignOperationFactory sign_factory;
+static EcdsaVerifyOperationFactory verify_factory;
+
+OperationFactory* EcKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return &sign_factory;
+    case KM_PURPOSE_VERIFY:
+        return &verify_factory;
+    default:
+        return nullptr;
+    }
+}
+
+keymaster_error_t EcKeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                            KeymasterKeyBlob* key_blob,
+                                            AuthorizationSet* hw_enforced,
+                                            AuthorizationSet* sw_enforced) const {
+    if (!key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    AuthorizationSet authorizations(key_description);
+
+    uint32_t key_size;
+    if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) {
+        LOG_E("%s", "No key size specified for EC key generation");
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+    }
+
+    UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EC_KEY_new());
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
+    if (ec_key.get() == NULL || pkey.get() == NULL)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    UniquePtr<EC_GROUP, EC_GROUP_Delete> group(choose_group(key_size));
+    if (group.get() == NULL) {
+        LOG_E("Unable to get EC group for key of size %d", key_size);
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+    }
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+    EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
+    EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
+#endif
+
+    if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+        EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+        return TranslateLastOpenSslError();
+    }
+
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1)
+        return TranslateLastOpenSslError();
+
+    KeymasterKeyBlob key_material;
+    keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob,
+                                   hw_enforced, sw_enforced);
+}
+
+keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_description,
+                                          keymaster_key_format_t input_key_material_format,
+                                          const KeymasterKeyBlob& input_key_material,
+                                          KeymasterKeyBlob* output_key_blob,
+                                          AuthorizationSet* hw_enforced,
+                                          AuthorizationSet* sw_enforced) const {
+    if (!output_key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    AuthorizationSet authorizations;
+    uint32_t key_size;
+    keymaster_error_t error = UpdateImportKeyDescription(
+        key_description, input_key_material_format, input_key_material, &authorizations, &key_size);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
+                                   output_key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t EcKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description,
+                                                           keymaster_key_format_t key_format,
+                                                           const KeymasterKeyBlob& key_material,
+                                                           AuthorizationSet* updated_description,
+                                                           uint32_t* key_size_bits) const {
+    if (!updated_description || !key_size_bits)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey;
+    keymaster_error_t error =
+        KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (!ec_key.get())
+        return TranslateLastOpenSslError();
+
+    updated_description->Reinitialize(key_description);
+
+    size_t extracted_key_size_bits;
+    error = ec_get_group_size(EC_KEY_get0_group(ec_key.get()), &extracted_key_size_bits);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    *key_size_bits = extracted_key_size_bits;
+    if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size_bits))
+        updated_description->push_back(TAG_KEY_SIZE, extracted_key_size_bits);
+    if (*key_size_bits != extracted_key_size_bits)
+        return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
+
+    keymaster_algorithm_t algorithm = KM_ALGORITHM_EC;
+    if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm))
+        updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
+    if (algorithm != KM_ALGORITHM_EC)
+        return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
+
+    return KM_ERROR_OK;
+}
+
+/* static */
+EC_GROUP* EcKeyFactory::choose_group(size_t key_size_bits) {
+    switch (key_size_bits) {
+    case 224:
+        return EC_GROUP_new_by_curve_name(NID_secp224r1);
+        break;
+    case 256:
+        return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+        break;
+    case 384:
+        return EC_GROUP_new_by_curve_name(NID_secp384r1);
+        break;
+    case 521:
+        return EC_GROUP_new_by_curve_name(NID_secp521r1);
+        break;
+    default:
+        return NULL;
+        break;
+    }
+}
+
+keymaster_error_t EcKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
+                                               const AuthorizationSet& sw_enforced,
+                                               UniquePtr<AsymmetricKey>* key) const {
+    keymaster_error_t error;
+    key->reset(new (std::nothrow) EcKey(hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return error;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ec_keymaster0_key.cpp b/keymaster/ec_keymaster0_key.cpp
new file mode 100644
index 0000000..705ee73
--- /dev/null
+++ b/keymaster/ec_keymaster0_key.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 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.
+ */
+
+#include "ec_keymaster0_key.h"
+
+#include <memory>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+#include <keymaster/soft_keymaster_context.h>
+
+#include "keymaster0_engine.h"
+#include "openssl_utils.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+EcdsaKeymaster0KeyFactory::EcdsaKeymaster0KeyFactory(const SoftKeymasterContext* context,
+                                                     const Keymaster0Engine* engine)
+    : EcKeyFactory(context), engine_(engine) {}
+
+keymaster_error_t EcdsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                                         KeymasterKeyBlob* key_blob,
+                                                         AuthorizationSet* hw_enforced,
+                                                         AuthorizationSet* sw_enforced) const {
+    if (!key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    if (!engine_ || !engine_->supports_ec())
+        return super::GenerateKey(key_description, key_blob, hw_enforced, sw_enforced);
+
+    uint32_t key_size;
+    if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) {
+        LOG_E("%s", "No key size specified for EC key generation");
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+    }
+
+    KeymasterKeyBlob key_material;
+    if (!engine_->GenerateEcKey(key_size, &key_material))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
+    // context_->CreateKeyBlob doesn't put them in sw_enforced.
+    hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
+    hw_enforced->push_back(TAG_KEY_SIZE, key_size);
+    hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
+
+    return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob,
+                                   hw_enforced, sw_enforced);
+}
+
+keymaster_error_t EcdsaKeymaster0KeyFactory::ImportKey(
+    const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
+    const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
+    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
+    if (!output_key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    if (!engine_ || !engine_->supports_ec())
+        return super::ImportKey(key_description, input_key_material_format, input_key_material,
+                                output_key_blob, hw_enforced, sw_enforced);
+
+    AuthorizationSet authorizations;
+    uint32_t key_size;
+    keymaster_error_t error = UpdateImportKeyDescription(
+        key_description, input_key_material_format, input_key_material, &authorizations, &key_size);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    KeymasterKeyBlob imported_hw_key;
+    if (!engine_->ImportKey(input_key_material_format, input_key_material, &imported_hw_key))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
+    // context_->CreateKeyBlob doesn't put them in sw_enforced.
+    hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC);
+    hw_enforced->push_back(TAG_KEY_SIZE, key_size);
+    hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
+
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key,
+                                   output_key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t EcdsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                                     const AuthorizationSet& additional_params,
+                                                     const AuthorizationSet& hw_enforced,
+                                                     const AuthorizationSet& sw_enforced,
+                                                     UniquePtr<Key>* key) const {
+    if (!key)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1)
+        return super::LoadKey(key_material, additional_params, hw_enforced, sw_enforced, key);
+
+    unique_ptr<EC_KEY, EC_KEY_Delete> ec_key(engine_->BlobToEcKey(key_material));
+    if (!ec_key)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    keymaster_error_t error;
+    key->reset(new (std::nothrow)
+                   EcKeymaster0Key(ec_key.release(), hw_enforced, sw_enforced, &error));
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ec_keymaster0_key.h b/keymaster/ec_keymaster0_key.h
new file mode 100644
index 0000000..0d0af3d
--- /dev/null
+++ b/keymaster/ec_keymaster0_key.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_EC_KEYMASTER0_KEY_H_
+#define SYSTEM_KEYMASTER_EC_KEYMASTER0_KEY_H_
+
+#include <openssl/ec_key.h>
+
+#include <keymaster/ec_key_factory.h>
+
+#include "ec_key.h"
+
+namespace keymaster {
+
+class Keymaster0Engine;
+class SoftKeymasterContext;
+
+/**
+ * An EcdsaKeyFactory which can delegate key generation, importing and loading operations to a
+ * keymaster0-backed OpenSSL engine.
+ */
+class EcdsaKeymaster0KeyFactory : public EcKeyFactory {
+    typedef EcKeyFactory super;
+
+  public:
+    EcdsaKeymaster0KeyFactory(const SoftKeymasterContext* context, const Keymaster0Engine* engine);
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+  private:
+    const Keymaster0Engine* engine_;
+};
+
+class EcKeymaster0Key : public EcKey {
+  public:
+    EcKeymaster0Key(EC_KEY* ec_key, const AuthorizationSet& hw_enforced,
+                    const AuthorizationSet& sw_enforced, keymaster_error_t* error)
+        : EcKey(ec_key, hw_enforced, sw_enforced, error) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_EC_KEYMASTER0_KEY_H_
diff --git a/keymaster/ec_keymaster1_key.cpp b/keymaster/ec_keymaster1_key.cpp
new file mode 100644
index 0000000..5cc2539
--- /dev/null
+++ b/keymaster/ec_keymaster1_key.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 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.
+ */
+
+#include "ec_keymaster1_key.h"
+
+#include <memory>
+
+#include <keymaster/logger.h>
+
+#include "ecdsa_keymaster1_operation.h"
+#include "ecdsa_operation.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+EcdsaKeymaster1KeyFactory::EcdsaKeymaster1KeyFactory(const SoftKeymasterContext* context,
+                                                     const Keymaster1Engine* engine)
+    : EcKeyFactory(context), engine_(engine),
+      sign_factory_(new EcdsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)),
+      // For pubkey ops we can use the normal operation factories.
+      verify_factory_(new EcdsaVerifyOperationFactory) {}
+
+static bool is_supported(uint32_t digest) {
+    return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
+}
+
+static void UpdateToWorkAroundUnsupportedDigests(const AuthorizationSet& key_description,
+                                                 AuthorizationSet* new_description) {
+    bool have_unsupported_digests = false;
+    bool have_digest_none = false;
+    for (const keymaster_key_param_t& entry : key_description) {
+        new_description->push_back(entry);
+
+        if (entry.tag == TAG_DIGEST) {
+            if (entry.enumerated == KM_DIGEST_NONE) {
+                have_digest_none = true;
+            } else if (!is_supported(entry.enumerated)) {
+                LOG_D("Found request for unsupported digest %u", entry.enumerated);
+                have_unsupported_digests = true;
+            }
+        }
+    }
+
+    if (have_unsupported_digests && !have_digest_none) {
+        LOG_I("Adding KM_DIGEST_NONE to key authorization, to enable software digesting", 0);
+        new_description->push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    }
+}
+
+keymaster_error_t EcdsaKeymaster1KeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                                         KeymasterKeyBlob* key_blob,
+                                                         AuthorizationSet* hw_enforced,
+                                                         AuthorizationSet* sw_enforced) const {
+    AuthorizationSet key_params_copy;
+    UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
+    return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t EcdsaKeymaster1KeyFactory::ImportKey(
+    const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
+    const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
+    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
+    AuthorizationSet key_params_copy;
+    UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
+    return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material,
+                              output_key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t EcdsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                                     const AuthorizationSet& additional_params,
+                                                     const AuthorizationSet& hw_enforced,
+                                                     const AuthorizationSet& sw_enforced,
+                                                     UniquePtr<Key>* key) const {
+    if (!key)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    keymaster_error_t error;
+    unique_ptr<EC_KEY, EC_KEY_Delete> ecdsa(
+        engine_->BuildEcKey(key_material, additional_params, &error));
+    if (!ecdsa)
+        return error;
+
+    key->reset(new (std::nothrow)
+                   EcdsaKeymaster1Key(ecdsa.release(), hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return KM_ERROR_OK;
+}
+
+OperationFactory*
+EcdsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return sign_factory_.get();
+    case KM_PURPOSE_VERIFY:
+        return verify_factory_.get();
+    default:
+        return nullptr;
+    }
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ec_keymaster1_key.h b/keymaster/ec_keymaster1_key.h
new file mode 100644
index 0000000..2702b35
--- /dev/null
+++ b/keymaster/ec_keymaster1_key.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_EC_KEYMASTER1_KEY_H_
+#define SYSTEM_KEYMASTER_EC_KEYMASTER1_KEY_H_
+
+#include <openssl/ecdsa.h>
+
+#include <hardware/keymaster1.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+#include <keymaster/ec_key_factory.h>
+#include <keymaster/soft_keymaster_context.h>
+
+#include "ec_key.h"
+#include "keymaster1_engine.h"
+
+namespace keymaster {
+
+class SoftKeymasterContext;
+
+/**
+ * EcdsaKeymaster1KeyFactory is a KeyFactory that creates and loads keys which are actually backed
+ * by a hardware keymaster1 module, but which does not support all keymaster1 digests.  During
+ * generation or import any unsupported digests in the key description are silently replaced with
+ * KM_DIGEST_NONE.
+ */
+class EcdsaKeymaster1KeyFactory : public EcKeyFactory {
+  public:
+    EcdsaKeymaster1KeyFactory(const SoftKeymasterContext* context, const Keymaster1Engine* engine);
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+  private:
+    const Keymaster1Engine* engine_;
+
+    std::unique_ptr<OperationFactory> sign_factory_;
+    std::unique_ptr<OperationFactory> verify_factory_;
+};
+
+class EcdsaKeymaster1Key : public EcKey {
+  public:
+    EcdsaKeymaster1Key(EC_KEY* ecdsa_key, const AuthorizationSet& hw_enforced,
+                       const AuthorizationSet& sw_enforced, keymaster_error_t* error)
+        : EcKey(ecdsa_key, hw_enforced, sw_enforced, error) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ECDSA_KEYMASTER1_KEY_H_
diff --git a/keymaster/ec_privkey_pk8.der b/keymaster/ec_privkey_pk8.der
new file mode 100644
index 0000000..a4af673
--- /dev/null
+++ b/keymaster/ec_privkey_pk8.der
Binary files differ
diff --git a/keymaster/ecdsa_keymaster1_operation.cpp b/keymaster/ecdsa_keymaster1_operation.cpp
new file mode 100644
index 0000000..7e1a4f5
--- /dev/null
+++ b/keymaster/ecdsa_keymaster1_operation.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright 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.
+ */
+
+#include "ecdsa_keymaster1_operation.h"
+
+#include <memory>
+
+#include <keymaster/android_keymaster_utils.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+#include "ec_keymaster1_key.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+keymaster_error_t EcdsaKeymaster1WrappedOperation::Begin(EVP_PKEY* ecdsa_key,
+                                                         const AuthorizationSet& input_params) {
+    Keymaster1Engine::KeyData* key_data = engine_->GetData(ecdsa_key);
+    if (!key_data)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    // Copy the input params and substitute KM_DIGEST_NONE for whatever was specified.  Also change
+    // KM_PAD_ECDSA_PSS and KM_PAD_OAEP to KM_PAD_NONE, if necessary. These are the params we'll
+    // pass
+    // to the hardware module.  The regular Ecdsa*Operation classes will do software digesting and
+    // padding where we've told the HW not to.
+    //
+    // The reason we don't change KM_PAD_ECDSA_PKCS1_1_5_SIGN or KM_PAD_ECDSA_PKCS1_1_5_ENCRYPT to
+    // KM_PAD_NONE is because the hardware can to those padding modes, since they don't involve
+    // digesting.
+    //
+    // We also cache in the key the padding value that we expect to be passed to the engine crypto
+    // operation.  This just allows us to double-check that the correct padding value is reaching
+    // that layer.
+    AuthorizationSet begin_params(input_params);
+    int pos = begin_params.find(TAG_DIGEST);
+    if (pos == -1)
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    begin_params[pos].enumerated = KM_DIGEST_NONE;
+
+    return engine_->device()->begin(engine_->device(), purpose_, &key_data->key_material,
+                                    &begin_params, nullptr /* out_params */, &operation_handle_);
+}
+
+keymaster_error_t
+EcdsaKeymaster1WrappedOperation::PrepareFinish(EVP_PKEY* ecdsa_key,
+                                               const AuthorizationSet& input_params) {
+    Keymaster1Engine::KeyData* key_data = engine_->GetData(ecdsa_key);
+    if (!key_data) {
+        LOG_E("Could not get extended key data... not a Keymaster1Engine key?", 0);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+    key_data->op_handle = operation_handle_;
+    key_data->finish_params.Reinitialize(input_params);
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaKeymaster1WrappedOperation::Abort() {
+    return engine_->device()->abort(engine_->device(), operation_handle_);
+}
+
+keymaster_error_t EcdsaKeymaster1WrappedOperation::GetError(EVP_PKEY* ecdsa_key) {
+    Keymaster1Engine::KeyData* key_data = engine_->GetData(ecdsa_key);
+    if (!key_data)
+        return KM_ERROR_UNKNOWN_ERROR;
+    return key_data->error;
+}
+
+static EVP_PKEY* GetEvpKey(const EcdsaKeymaster1Key& key, keymaster_error_t* error) {
+    if (!key.key()) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
+    if (!key.InternalToEvp(pkey.get())) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+    return pkey.release();
+}
+
+Operation* EcdsaKeymaster1OperationFactory::CreateOperation(const Key& key,
+                                                            const AuthorizationSet& begin_params,
+                                                            keymaster_error_t* error) {
+    keymaster_digest_t digest;
+    if (!GetAndValidateDigest(begin_params, key, &digest, error))
+        return nullptr;
+
+    const EcdsaKeymaster1Key& ecdsa_km1_key(static_cast<const EcdsaKeymaster1Key&>(key));
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> ecdsa(GetEvpKey(ecdsa_km1_key, error));
+    if (!ecdsa)
+        return nullptr;
+
+    switch (purpose_) {
+    case KM_PURPOSE_SIGN:
+        return new EcdsaKeymaster1Operation<EcdsaSignOperation>(digest, ecdsa.release(), engine_);
+    default:
+        LOG_E(
+            "Bug: Pubkey operation requested.  Those should be handled by normal ECDSA operations.",
+            0);
+        *error = KM_ERROR_UNSUPPORTED_PURPOSE;
+        return nullptr;
+    }
+}
+
+static const keymaster_digest_t supported_digests[] = {
+    KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
+    KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
+
+const keymaster_digest_t*
+EcdsaKeymaster1OperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = array_length(supported_digests);
+    return supported_digests;
+}
+
+const keymaster_padding_t*
+EcdsaKeymaster1OperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    *padding_mode_count = 0;
+    return nullptr;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ecdsa_keymaster1_operation.h b/keymaster/ecdsa_keymaster1_operation.h
new file mode 100644
index 0000000..6045686
--- /dev/null
+++ b/keymaster/ecdsa_keymaster1_operation.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ECDSA_KEYMASTER1_OPERATION_H_
+#define SYSTEM_KEYMASTER_ECDSA_KEYMASTER1_OPERATION_H_
+
+#include <openssl/evp.h>
+
+#include <hardware/keymaster1.h>
+#include <keymaster/android_keymaster_utils.h>
+
+#include "ecdsa_operation.h"
+#include "keymaster1_engine.h"
+
+namespace keymaster {
+
+class EcdsaKeymaster1WrappedOperation {
+  public:
+    EcdsaKeymaster1WrappedOperation(keymaster_purpose_t purpose, const Keymaster1Engine* engine)
+        : purpose_(purpose), operation_handle_(0), engine_(engine) {}
+    ~EcdsaKeymaster1WrappedOperation() {
+        if (operation_handle_)
+            Abort();
+    }
+
+    keymaster_error_t Begin(EVP_PKEY* ecdsa_key, const AuthorizationSet& input_params);
+    keymaster_error_t PrepareFinish(EVP_PKEY* ecdsa_key, const AuthorizationSet& input_params);
+    void Finish() { operation_handle_ = 0; }
+    keymaster_error_t Abort();
+
+    keymaster_error_t GetError(EVP_PKEY* ecdsa_key);
+
+  protected:
+    keymaster_purpose_t purpose_;
+    keymaster_operation_handle_t operation_handle_;
+    const Keymaster1Engine* engine_;
+};
+
+template <typename BaseOperation> class EcdsaKeymaster1Operation : public BaseOperation {
+    typedef BaseOperation super;
+
+  public:
+    EcdsaKeymaster1Operation(keymaster_digest_t digest, EVP_PKEY* key,
+                             const Keymaster1Engine* engine)
+        : BaseOperation(digest, key), wrapped_operation_(super::purpose(), engine) {
+        // Shouldn't be instantiated for public key operations.
+        assert(super::purpose() != KM_PURPOSE_VERIFY);
+        assert(super::purpose() != KM_PURPOSE_ENCRYPT);
+    }
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override {
+        keymaster_error_t error = wrapped_operation_.Begin(super::ecdsa_key_, input_params);
+        if (error != KM_ERROR_OK)
+            return error;
+        return super::Begin(input_params, output_params);
+    }
+
+    keymaster_error_t Finish(const AuthorizationSet& input_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override {
+        keymaster_error_t error = wrapped_operation_.PrepareFinish(super::ecdsa_key_, input_params);
+        if (error != KM_ERROR_OK)
+            return error;
+        error = super::Finish(input_params, input, signature, output_params, output);
+        if (wrapped_operation_.GetError(super::ecdsa_key_) != KM_ERROR_OK)
+            error = wrapped_operation_.GetError(super::ecdsa_key_);
+        if (error == KM_ERROR_OK)
+            wrapped_operation_.Finish();
+        return error;
+    }
+
+    keymaster_error_t Abort() override {
+        keymaster_error_t error = wrapped_operation_.Abort();
+        if (error != KM_ERROR_OK)
+            return error;
+        return super::Abort();
+    }
+
+  private:
+    EcdsaKeymaster1WrappedOperation wrapped_operation_;
+};
+
+/**
+ * Factory that produces EcdsaKeymaster1Operations.  This is instantiated and
+ * provided by EcdsaKeymaster1KeyFactory.
+ */
+class EcdsaKeymaster1OperationFactory : public OperationFactory {
+  public:
+    EcdsaKeymaster1OperationFactory(keymaster_purpose_t purpose, const Keymaster1Engine* engine)
+        : purpose_(purpose), engine_(engine) {}
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose_); }
+
+    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                               keymaster_error_t* error) override;
+
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override;
+
+  private:
+    keymaster_purpose_t purpose_;
+    const Keymaster1Engine* engine_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ECDSA_KEYMASTER1_OPERATION_H_
diff --git a/keymaster/ecdsa_operation.cpp b/keymaster/ecdsa_operation.cpp
new file mode 100644
index 0000000..405dcb5
--- /dev/null
+++ b/keymaster/ecdsa_operation.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "ecdsa_operation.h"
+
+#include <openssl/ecdsa.h>
+
+#include "ec_key.h"
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+static const keymaster_digest_t supported_digests[] = {KM_DIGEST_NONE,      KM_DIGEST_SHA1,
+                                                       KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256,
+                                                       KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
+
+Operation* EcdsaOperationFactory::CreateOperation(const Key& key,
+                                                  const AuthorizationSet& begin_params,
+                                                  keymaster_error_t* error) {
+    const EcKey* ecdsa_key = static_cast<const EcKey*>(&key);
+    if (!ecdsa_key) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
+    if (!ecdsa_key->InternalToEvp(pkey.get())) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+
+    keymaster_digest_t digest;
+    if (!GetAndValidateDigest(begin_params, key, &digest, error))
+        return nullptr;
+
+    *error = KM_ERROR_OK;
+    Operation* op = InstantiateOperation(digest, pkey.release());
+    if (!op)
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return op;
+}
+
+const keymaster_digest_t* EcdsaOperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = array_length(supported_digests);
+    return supported_digests;
+}
+
+EcdsaOperation::~EcdsaOperation() {
+    if (ecdsa_key_ != NULL)
+        EVP_PKEY_free(ecdsa_key_);
+    EVP_MD_CTX_cleanup(&digest_ctx_);
+}
+
+keymaster_error_t EcdsaOperation::InitDigest() {
+    switch (digest_) {
+    case KM_DIGEST_NONE:
+        return KM_ERROR_OK;
+    case KM_DIGEST_MD5:
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    case KM_DIGEST_SHA1:
+        digest_algorithm_ = EVP_sha1();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_224:
+        digest_algorithm_ = EVP_sha224();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_256:
+        digest_algorithm_ = EVP_sha256();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_384:
+        digest_algorithm_ = EVP_sha384();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_512:
+        digest_algorithm_ = EVP_sha512();
+        return KM_ERROR_OK;
+    default:
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    }
+}
+
+inline size_t min(size_t a, size_t b) {
+    return (a < b) ? a : b;
+}
+
+keymaster_error_t EcdsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
+    if (!data_.reserve((EVP_PKEY_bits(ecdsa_key_) + 7) / 8))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (!data_.write(input.peek_read(), min(data_.available_write(), input.available_read())))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaSignOperation::Begin(const AuthorizationSet& /* input_params */,
+                                            AuthorizationSet* /* output_params */) {
+    keymaster_error_t error = InitDigest();
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE)
+        return KM_ERROR_OK;
+
+    EVP_PKEY_CTX* pkey_ctx;
+    if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
+                           ecdsa_key_) != 1)
+        return TranslateLastOpenSslError();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaSignOperation::Update(const AuthorizationSet& /* additional_params */,
+                                             const Buffer& input,
+                                             AuthorizationSet* /* output_params */,
+                                             Buffer* /* output */, size_t* input_consumed) {
+    if (digest_ == KM_DIGEST_NONE)
+        return StoreData(input, input_consumed);
+
+    if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
+        return TranslateLastOpenSslError();
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaSignOperation::Finish(const AuthorizationSet& additional_params,
+                                             const Buffer& input, const Buffer& /* signature */,
+                                             AuthorizationSet* /* output_params */,
+                                             Buffer* output) {
+    if (!output)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    size_t siglen;
+    if (digest_ == KM_DIGEST_NONE) {
+        UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
+        if (!ecdsa.get())
+            return TranslateLastOpenSslError();
+
+        output->Reinitialize(ECDSA_size(ecdsa.get()));
+        unsigned int siglen_tmp;
+        if (!ECDSA_sign(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
+                        output->peek_write(), &siglen_tmp, ecdsa.get()))
+            return TranslateLastOpenSslError();
+        siglen = siglen_tmp;
+    } else {
+        if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
+            return TranslateLastOpenSslError();
+        if (!output->Reinitialize(siglen))
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
+            return TranslateLastOpenSslError();
+    }
+    if (!output->advance_write(siglen))
+        return KM_ERROR_UNKNOWN_ERROR;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaVerifyOperation::Begin(const AuthorizationSet& /* input_params */,
+                                              AuthorizationSet* /* output_params */) {
+    keymaster_error_t error = InitDigest();
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE)
+        return KM_ERROR_OK;
+
+    EVP_PKEY_CTX* pkey_ctx;
+    if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
+                             ecdsa_key_) != 1)
+        return TranslateLastOpenSslError();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaVerifyOperation::Update(const AuthorizationSet& /* additional_params */,
+                                               const Buffer& input,
+                                               AuthorizationSet* /* output_params */,
+                                               Buffer* /* output */, size_t* input_consumed) {
+    if (digest_ == KM_DIGEST_NONE)
+        return StoreData(input, input_consumed);
+
+    if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
+        return TranslateLastOpenSslError();
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t EcdsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
+                                               const Buffer& input, const Buffer& signature,
+                                               AuthorizationSet* /* output_params */,
+                                               Buffer* /* output */) {
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE) {
+        UniquePtr<EC_KEY, EC_KEY_Delete> ecdsa(EVP_PKEY_get1_EC_KEY(ecdsa_key_));
+        if (!ecdsa.get())
+            return TranslateLastOpenSslError();
+
+        int result =
+            ECDSA_verify(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
+                         signature.peek_read(), signature.available_read(), ecdsa.get());
+        if (result < 0)
+            return TranslateLastOpenSslError();
+        else if (result == 0)
+            return KM_ERROR_VERIFICATION_FAILED;
+    } else if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(),
+                                      signature.available_read()))
+        return KM_ERROR_VERIFICATION_FAILED;
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ecdsa_operation.h b/keymaster/ecdsa_operation.h
new file mode 100644
index 0000000..4b95dc9
--- /dev/null
+++ b/keymaster/ecdsa_operation.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ECDSA_OPERATION_H_
+#define SYSTEM_KEYMASTER_ECDSA_OPERATION_H_
+
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+
+#include <UniquePtr.h>
+
+#include "operation.h"
+
+namespace keymaster {
+
+class EcdsaOperation : public Operation {
+  public:
+    EcdsaOperation(keymaster_purpose_t purpose, keymaster_digest_t digest, EVP_PKEY* key)
+        : Operation(purpose), digest_(digest), ecdsa_key_(key) {
+        EVP_MD_CTX_init(&digest_ctx_);
+    }
+    ~EcdsaOperation();
+
+    keymaster_error_t Abort() override { return KM_ERROR_OK; }
+
+  protected:
+    keymaster_error_t StoreData(const Buffer& input, size_t* input_consumed);
+    keymaster_error_t InitDigest();
+
+    keymaster_digest_t digest_;
+    const EVP_MD* digest_algorithm_;
+    EVP_PKEY* ecdsa_key_;
+    EVP_MD_CTX digest_ctx_;
+    Buffer data_;
+};
+
+class EcdsaSignOperation : public EcdsaOperation {
+  public:
+    EcdsaSignOperation(keymaster_digest_t digest, EVP_PKEY* key)
+        : EcdsaOperation(KM_PURPOSE_SIGN, digest, key) {}
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+};
+
+class EcdsaVerifyOperation : public EcdsaOperation {
+  public:
+    EcdsaVerifyOperation(keymaster_digest_t digest, EVP_PKEY* key)
+        : EcdsaOperation(KM_PURPOSE_VERIFY, digest, key) {}
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+};
+
+class EcdsaOperationFactory : public OperationFactory {
+  private:
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_EC, purpose()); }
+    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                               keymaster_error_t* error) override;
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+
+    virtual keymaster_purpose_t purpose() const = 0;
+    virtual Operation* InstantiateOperation(keymaster_digest_t digest, EVP_PKEY* key) = 0;
+};
+
+class EcdsaSignOperationFactory : public EcdsaOperationFactory {
+  private:
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; }
+    Operation* InstantiateOperation(keymaster_digest_t digest, EVP_PKEY* key) {
+        return new (std::nothrow) EcdsaSignOperation(digest, key);
+    }
+};
+
+class EcdsaVerifyOperationFactory : public EcdsaOperationFactory {
+  public:
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; }
+    Operation* InstantiateOperation(keymaster_digest_t digest, EVP_PKEY* key) {
+        return new (std::nothrow) EcdsaVerifyOperation(digest, key);
+    }
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ECDSA_OPERATION_H_
diff --git a/keymaster/ecies_kem.cpp b/keymaster/ecies_kem.cpp
new file mode 100644
index 0000000..2e31573
--- /dev/null
+++ b/keymaster/ecies_kem.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright 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.
+ */
+
+#include "ecies_kem.h"
+
+#include "nist_curve_key_exchange.h"
+#include "openssl_err.h"
+
+namespace keymaster {
+
+EciesKem::EciesKem(const AuthorizationSet& kem_description, keymaster_error_t* error) {
+    const AuthorizationSet& authorizations(kem_description);
+
+    if (!authorizations.GetTagValue(TAG_EC_CURVE, &curve_)) {
+        LOG_E("%s", "EciesKem: no curve specified");
+        *error = KM_ERROR_INVALID_ARGUMENT;
+        return;
+    }
+
+    switch (curve_) {
+    case KM_EC_CURVE_P_224:
+    case KM_EC_CURVE_P_256:
+    case KM_EC_CURVE_P_384:
+    case KM_EC_CURVE_P_521:
+        break;
+    default:
+        LOG_E("EciesKem: curve %d is unsupported", curve_);
+        *error = KM_ERROR_UNSUPPORTED_EC_CURVE;
+        return;
+    }
+
+    keymaster_kdf_t kdf;
+    if (!authorizations.GetTagValue(TAG_KDF, &kdf)) {
+        LOG_E("EciesKem: No KDF specified", 0);
+        *error = KM_ERROR_UNSUPPORTED_KDF;
+        return;
+    }
+    switch (kdf) {
+    case KM_KDF_RFC5869_SHA256:
+        kdf_.reset(new Rfc5869Sha256Kdf());
+        break;
+    default:
+        LOG_E("Kdf %d is unsupported", kdf);
+        *error = KM_ERROR_UNSUPPORTED_KDF;
+        return;
+    }
+    if (!kdf_.get()) {
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        return;
+    }
+
+    if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_bytes_to_generate_)) {
+        LOG_E("%s", "EciesKem: no key length specified");
+        *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
+        return;
+    }
+
+    single_hash_mode_ = authorizations.GetTagValue(TAG_ECIES_SINGLE_HASH_MODE);
+    *error = KM_ERROR_OK;
+}
+
+bool EciesKem::Encrypt(const Buffer& peer_public_value, Buffer* output_clear_key,
+                       Buffer* output_encrypted_key) {
+    return Encrypt(peer_public_value.peek_read(), peer_public_value.available_read(),
+                   output_clear_key, output_encrypted_key);
+}
+
+// http://www.shoup.net/iso/std6.pdf, section 10.2.3.
+bool EciesKem::Encrypt(const uint8_t* peer_public_value, size_t peer_public_value_len,
+                       Buffer* output_clear_key, Buffer* output_encrypted_key) {
+
+    key_exchange_.reset(NistCurveKeyExchange::GenerateKeyExchange(curve_));
+    if (!key_exchange_.get()) {
+        return false;
+    }
+
+    Buffer shared_secret;
+    if (!key_exchange_->CalculateSharedKey(peer_public_value, peer_public_value_len,
+                                           &shared_secret)) {
+        LOG_E("EciesKem: ECDH failed, can't obtain shared secret", 0);
+        return false;
+    }
+    if (!key_exchange_->public_value(output_encrypted_key)) {
+        LOG_E("EciesKem: Can't obtain public value", 0);
+        return false;
+    }
+
+    Buffer z;
+    if (single_hash_mode_) {
+        // z is empty.
+    } else {
+        // z = C0
+        z.Reinitialize(output_encrypted_key->peek_read(), output_encrypted_key->available_read());
+    }
+
+    Buffer actual_secret(z.available_read() + shared_secret.available_read());
+    actual_secret.write(z.peek_read(), z.available_read());
+    actual_secret.write(shared_secret.peek_read(), shared_secret.available_read());
+
+    if (!kdf_->Init(actual_secret.peek_read(), actual_secret.available_read(), nullptr /* salt */,
+                    0 /* salt_len */)) {
+        LOG_E("EciesKem: KDF failed, can't derived keys", 0);
+        return false;
+    }
+    output_clear_key->Reinitialize(key_bytes_to_generate_);
+    if (!kdf_->GenerateKey(nullptr /* info */, 0 /* info length */, output_clear_key->peek_write(),
+                           key_bytes_to_generate_)) {
+        LOG_E("EciesKem: KDF failed, can't derived keys", 0);
+        return false;
+    }
+    output_clear_key->advance_write(key_bytes_to_generate_);
+
+    return true;
+}
+
+bool EciesKem::Decrypt(EC_KEY* private_key, const Buffer& encrypted_key, Buffer* output_key) {
+    return Decrypt(private_key, encrypted_key.peek_read(), encrypted_key.available_read(),
+                   output_key);
+}
+
+// http://www.shoup.net/iso/std6.pdf, section 10.2.4.
+bool EciesKem::Decrypt(EC_KEY* private_key, const uint8_t* encrypted_key, size_t encrypted_key_len,
+                       Buffer* output_key) {
+
+    keymaster_error_t error;
+    key_exchange_.reset(new NistCurveKeyExchange(private_key, &error));
+    if (!key_exchange_.get() || error != KM_ERROR_OK) {
+        return false;
+    }
+
+    Buffer shared_secret;
+    if (!key_exchange_->CalculateSharedKey(encrypted_key, encrypted_key_len, &shared_secret)) {
+        LOG_E("EciesKem: ECDH failed, can't obtain shared secret", 0);
+        return false;
+    }
+
+    Buffer public_value;
+    if (!key_exchange_->public_value(&public_value)) {
+        LOG_E("%s", "EciesKem: Can't obtain public value");
+        return false;
+    }
+
+    Buffer z;
+    if (single_hash_mode_) {
+        // z is empty.
+    } else {
+        // z = C0
+        z.Reinitialize(public_value.peek_read(), public_value.available_read());
+    }
+
+    Buffer actual_secret(z.available_read() + shared_secret.available_read());
+    actual_secret.write(z.peek_read(), z.available_read());
+    actual_secret.write(shared_secret.peek_read(), shared_secret.available_read());
+
+    if (!kdf_->Init(actual_secret.peek_read(), actual_secret.available_read(), nullptr /* salt */,
+                    0 /* salt_len */)) {
+        LOG_E("%s", "EciesKem: KDF failed, can't derived keys");
+        return false;
+    }
+
+    output_key->Reinitialize(key_bytes_to_generate_);
+    if (!kdf_->GenerateKey(nullptr /* info */, 0 /* info_len */, output_key->peek_write(),
+                           key_bytes_to_generate_)) {
+        LOG_E("%s", "EciesKem: KDF failed, can't derived keys");
+        return false;
+    }
+    output_key->advance_write(key_bytes_to_generate_);
+
+    return true;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ecies_kem.h b/keymaster/ecies_kem.h
new file mode 100644
index 0000000..8c1b330
--- /dev/null
+++ b/keymaster/ecies_kem.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ECIES_KEM_H_
+#define SYSTEM_KEYMASTER_ECIES_KEM_H_
+
+#include "kem.h"
+
+#include <UniquePtr.h>
+#include <openssl/ec.h>
+
+#include <keymaster/authorization_set.h>
+
+#include "hkdf.h"
+#include "key_exchange.h"
+
+namespace keymaster {
+
+/**
+ * EciesKem is an implementation of the key encapsulation mechanism ECIES-KEM described in
+ * ISO 18033-2 (http://www.shoup.net/iso/std6.pdf, http://www.shoup.net/papers/iso-2_1.pdf).
+ */
+class EciesKem : public Kem {
+  public:
+    virtual ~EciesKem() override {}
+    EciesKem(const AuthorizationSet& kem_description, keymaster_error_t* error);
+
+    /* Kem interface. */
+    bool Encrypt(const Buffer& peer_public_value, Buffer* output_clear_key,
+                 Buffer* output_encrypted_key) override;
+    bool Encrypt(const uint8_t* peer_public_value, size_t peer_public_value_len,
+                 Buffer* output_clear_key, Buffer* output_encrypted_key) override;
+
+    bool Decrypt(EC_KEY* private_key, const Buffer& encrypted_key, Buffer* output_key) override;
+    bool Decrypt(EC_KEY* private_key, const uint8_t* encrypted_key, size_t encrypted_key_len,
+                 Buffer* output_key) override;
+
+  private:
+    UniquePtr<KeyExchange> key_exchange_;
+    UniquePtr<Rfc5869Sha256Kdf> kdf_;
+    bool single_hash_mode_;
+    uint32_t key_bytes_to_generate_;
+    keymaster_ec_curve_t curve_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ECIES_KEM_H_
diff --git a/keymaster/ecies_kem_test.cpp b/keymaster/ecies_kem_test.cpp
new file mode 100644
index 0000000..f653dc0
--- /dev/null
+++ b/keymaster/ecies_kem_test.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 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.
+ */
+
+#include "ecies_kem.h"
+
+#include <gtest/gtest.h>
+#include <openssl/evp.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_utils.h>
+
+#include "android_keymaster_test_utils.h"
+#include "nist_curve_key_exchange.h"
+
+using std::string;
+
+namespace keymaster {
+namespace test {
+
+StdoutLogger logger;
+
+static const keymaster_ec_curve_t kEcCurves[] = {KM_EC_CURVE_P_224, KM_EC_CURVE_P_256,
+                                                 KM_EC_CURVE_P_384, KM_EC_CURVE_P_521};
+
+/**
+ * TestConsistency just tests that the basic key encapsulation hold.
+ */
+TEST(EciesKem, TestConsistency) {
+    static const uint32_t kKeyLen = 32;
+    for (auto& curve : kEcCurves) {
+        AuthorizationSet kem_description(AuthorizationSetBuilder()
+                                             .Authorization(TAG_EC_CURVE, curve)
+                                             .Authorization(TAG_KDF, KM_KDF_RFC5869_SHA256)
+                                             .Authorization(TAG_ECIES_SINGLE_HASH_MODE)
+                                             .Authorization(TAG_KEY_SIZE, kKeyLen));
+        keymaster_error_t error;
+        EciesKem* kem = new EciesKem(kem_description, &error);
+        ASSERT_EQ(KM_ERROR_OK, error);
+
+        NistCurveKeyExchange* key_exchange = NistCurveKeyExchange::GenerateKeyExchange(curve);
+        Buffer peer_public_value;
+        ASSERT_TRUE(key_exchange->public_value(&peer_public_value));
+
+        Buffer output_clear_key;
+        Buffer output_encrypted_key;
+        ASSERT_TRUE(kem->Encrypt(peer_public_value, &output_clear_key, &output_encrypted_key));
+        ASSERT_EQ(kKeyLen, output_clear_key.available_read());
+        ASSERT_EQ(peer_public_value.available_read(), output_encrypted_key.available_read());
+
+        Buffer decrypted_clear_key;
+        ASSERT_TRUE(
+            kem->Decrypt(key_exchange->private_key(), output_encrypted_key, &decrypted_clear_key));
+        ASSERT_EQ(kKeyLen, decrypted_clear_key.available_read());
+        EXPECT_EQ(0, memcmp(output_clear_key.peek_read(), decrypted_clear_key.peek_read(),
+                            output_clear_key.available_read()));
+    }
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/gtest_main.cpp b/keymaster/gtest_main.cpp
new file mode 100644
index 0000000..6072749
--- /dev/null
+++ b/keymaster/gtest_main.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <openssl/engine.h>
+
+int main(int argc, char** argv) {
+#if !defined(OPENSSL_IS_BORINGSSL)
+    ERR_load_crypto_strings();
+#endif // not OPENSSL_IS_BORINGSSL
+    ::testing::InitGoogleTest(&argc, argv);
+    int result = RUN_ALL_TESTS();
+#if !defined(OPENSSL_IS_BORINGSSL)
+    // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
+    CRYPTO_cleanup_all_ex_data();
+    ERR_remove_thread_state(NULL);
+    ERR_free_strings();
+#endif // not OPENSSL_IS_BORINGSSL
+    return result;
+}
diff --git a/keymaster/hkdf.cpp b/keymaster/hkdf.cpp
new file mode 100644
index 0000000..9727375
--- /dev/null
+++ b/keymaster/hkdf.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 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.
+ */
+
+#include "hkdf.h"
+
+#include <new>
+
+#include <keymaster/android_keymaster_utils.h>
+
+#include "hmac.h"
+
+namespace keymaster {
+
+bool Rfc5869Sha256Kdf::GenerateKey(const uint8_t* info, size_t info_len, uint8_t* output,
+                                   size_t output_len) {
+    if (!is_initialized_ || output == nullptr)
+        return false;
+    /**
+     * Step 1. Extract: PRK = HMAC-SHA256(actual_salt, secret)
+     * https://tools.ietf.org/html/rfc5869#section-2.2
+     */
+    HmacSha256 prk_hmac;
+    bool result;
+    if (salt_.get() != nullptr && salt_len_ > 0) {
+        result = prk_hmac.Init(salt_.get(), salt_len_);
+    } else {
+        UniquePtr<uint8_t[]> zeros(new uint8_t[digest_size_]);
+        if (zeros.get() == nullptr)
+            return false;
+        /* If salt is not given, digest size of zeros are used. */
+        memset(zeros.get(), 0, digest_size_);
+        result = prk_hmac.Init(zeros.get(), digest_size_);
+    }
+    if (!result)
+        return false;
+
+    UniquePtr<uint8_t[]> pseudo_random_key(new uint8_t[digest_size_]);
+    if (pseudo_random_key.get() == nullptr || digest_size_ != prk_hmac.DigestLength())
+        return false;
+    result =
+        prk_hmac.Sign(secret_key_.get(), secret_key_len_, pseudo_random_key.get(), digest_size_);
+    if (!result)
+        return false;
+
+    /**
+     * Step 2. Expand: OUTPUT = HKDF-Expand(PRK, info)
+     * https://tools.ietf.org/html/rfc5869#section-2.3
+     */
+    const size_t num_blocks = (output_len + digest_size_ - 1) / digest_size_;
+    if (num_blocks >= 256u)
+        return false;
+
+    UniquePtr<uint8_t[]> buf(new uint8_t[digest_size_ + info_len + 1]);
+    UniquePtr<uint8_t[]> digest(new uint8_t[digest_size_]);
+    if (buf.get() == nullptr || digest.get() == nullptr)
+        return false;
+    HmacSha256 hmac;
+    result = hmac.Init(pseudo_random_key.get(), digest_size_);
+    if (!result)
+        return false;
+
+    for (size_t i = 0; i < num_blocks; i++) {
+        size_t block_input_len = 0;
+        if (i != 0) {
+            memcpy(buf.get(), digest.get(), digest_size_);
+            block_input_len = digest_size_;
+        }
+        if (info != nullptr && info_len > 0)
+            memcpy(buf.get() + block_input_len, info, info_len);
+        block_input_len += info_len;
+        *(buf.get() + block_input_len++) = static_cast<uint8_t>(i + 1);
+        result = hmac.Sign(buf.get(), block_input_len, digest.get(), digest_size_);
+        if (!result)
+            return false;
+        size_t block_output_len = digest_size_ < output_len - i * digest_size_
+                                      ? digest_size_
+                                      : output_len - i * digest_size_;
+        memcpy(output + i * digest_size_, digest.get(), block_output_len);
+    }
+    return true;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/hkdf.h b/keymaster/hkdf.h
new file mode 100644
index 0000000..9de39bf
--- /dev/null
+++ b/keymaster/hkdf.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_HKDF_H_
+#define SYSTEM_KEYMASTER_HKDF_H_
+
+#include "kdf.h"
+
+#include <keymaster/serializable.h>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+/**
+ * Rfc5869Sha256Kdf implements the key derivation function specified in RFC 5869 (using SHA256) and
+ * outputs key material, as needed by ECIES. See https://tools.ietf.org/html/rfc5869 for details.
+ */
+class Rfc5869Sha256Kdf : public Kdf {
+  public:
+    ~Rfc5869Sha256Kdf() {}
+    bool Init(Buffer& secret, Buffer& salt) {
+        return Init(secret.peek_read(), secret.available_read(), salt.peek_read(),
+                    salt.available_read());
+    }
+
+    bool Init(const uint8_t* secret, size_t secret_len, const uint8_t* salt, size_t salt_len) {
+        return Kdf::Init(KM_DIGEST_SHA_2_256, secret, secret_len, salt, salt_len);
+    }
+
+    bool GenerateKey(const uint8_t* info, size_t info_len, uint8_t* output,
+                     size_t output_len) override;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_HKDF_H_
diff --git a/keymaster/hkdf_test.cpp b/keymaster/hkdf_test.cpp
new file mode 100644
index 0000000..3d3f092
--- /dev/null
+++ b/keymaster/hkdf_test.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 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.
+ */
+
+#include "hkdf.h"
+
+#include <gtest/gtest.h>
+#include <string.h>
+
+#include "android_keymaster_test_utils.h"
+
+using std::string;
+
+namespace keymaster {
+namespace test {
+
+struct HkdfTest {
+    const char* key_hex;
+    const char* salt_hex;
+    const char* info_hex;
+    const char* output_hex;
+};
+
+// These test cases are taken from
+// https://tools.ietf.org/html/rfc5869#appendix-A.
+static const HkdfTest kHkdfTests[] = {
+    {
+        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "000102030405060708090a0b0c",
+        "f0f1f2f3f4f5f6f7f8f9",
+        "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+    },
+    {
+        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c"
+        "2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f",
+        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c"
+        "8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
+        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdc"
+        "dddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+        "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e"
+        "590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87",
+    },
+    {
+        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "",
+        "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8",
+    },
+};
+
+TEST(HkdfTest, Hkdf) {
+    for (auto& test : kHkdfTests) {
+        const string key = hex2str(test.key_hex);
+        const string salt = hex2str(test.salt_hex);
+        const string info = hex2str(test.info_hex);
+        const string expected = hex2str(test.output_hex);
+        size_t output_len = expected.size();
+        uint8_t output[output_len];
+        Rfc5869Sha256Kdf hkdf;
+        ASSERT_TRUE(hkdf.Init(reinterpret_cast<const uint8_t*>(key.data()), key.size(),
+                              reinterpret_cast<const uint8_t*>(salt.data()), salt.size()));
+        ASSERT_TRUE(hkdf.GenerateKey(reinterpret_cast<const uint8_t*>(info.data()), info.size(),
+                                     output, output_len));
+        EXPECT_EQ(0, memcmp(output, expected.data(), output_len));
+    }
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/hmac.cpp b/keymaster/hmac.cpp
new file mode 100644
index 0000000..02f739c
--- /dev/null
+++ b/keymaster/hmac.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright 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.
+ */
+
+#include "hmac.h"
+
+#include <assert.h>
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/mem.h>
+#include <openssl/sha.h>
+
+#include <keymaster/android_keymaster_utils.h>
+
+namespace keymaster {
+
+size_t HmacSha256::DigestLength() const {
+    return SHA256_DIGEST_LENGTH;
+}
+
+bool HmacSha256::Init(const Buffer& key) {
+    return Init(key.peek_read(), key.available_read());
+}
+
+bool HmacSha256::Init(const uint8_t* key, size_t key_len) {
+    if (!key)
+        return false;
+
+    key_len_ = key_len;
+    key_.reset(dup_buffer(key, key_len));
+    if (!key_.get()) {
+        return false;
+    }
+    return true;
+}
+
+bool HmacSha256::Sign(const Buffer& data, uint8_t* out_digest, size_t digest_len) const {
+    return Sign(data.peek_read(), data.available_read(), out_digest, digest_len);
+}
+
+bool HmacSha256::Sign(const uint8_t* data, size_t data_len, uint8_t* out_digest,
+                      size_t digest_len) const {
+    assert(digest_len);
+
+    uint8_t tmp[SHA256_DIGEST_LENGTH];
+    uint8_t* digest = tmp;
+    if (digest_len >= SHA256_DIGEST_LENGTH)
+        digest = out_digest;
+
+    if (nullptr == ::HMAC(EVP_sha256(), key_.get(), key_len_, data, data_len, digest, nullptr)) {
+        return false;
+    }
+    if (digest_len < SHA256_DIGEST_LENGTH)
+        memcpy(out_digest, tmp, digest_len);
+
+    return true;
+}
+
+bool HmacSha256::Verify(const Buffer& data, const Buffer& digest) const {
+    return Verify(data.peek_read(), data.available_read(), digest.peek_read(),
+                  digest.available_read());
+}
+
+bool HmacSha256::Verify(const uint8_t* data, size_t data_len, const uint8_t* digest,
+                        size_t digest_len) const {
+    if (digest_len != SHA256_DIGEST_LENGTH)
+        return false;
+
+    uint8_t computed_digest[SHA256_DIGEST_LENGTH];
+    if (!Sign(data, data_len, computed_digest, sizeof(computed_digest)))
+        return false;
+
+    return 0 == CRYPTO_memcmp(digest, computed_digest, SHA256_DIGEST_LENGTH);
+}
+
+}  // namespace keymaster
diff --git a/keymaster/hmac.h b/keymaster/hmac.h
new file mode 100644
index 0000000..ebd5b70
--- /dev/null
+++ b/keymaster/hmac.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_HMAC_H_
+#define SYSTEM_KEYMASTER_HMAC_H_
+
+#include <keymaster/serializable.h>
+
+namespace keymaster {
+
+// Only HMAC-SHA256 is supported.
+class HmacSha256 {
+  public:
+    HmacSha256(){};
+
+    // DigestLength returns the length, in bytes, of the resulting digest.
+    size_t DigestLength() const;
+
+    // Initializes this instance using |key|. Call Init only once. It returns
+    // false on the second of later calls.
+    bool Init(const uint8_t* key, size_t key_length);
+    bool Init(const Buffer& key);
+
+    // Sign calculates the HMAC of |data| with the key supplied to the Init
+    // method. At most |digest_len| bytes of the resulting digest are written
+    // to |digest|.
+    bool Sign(const Buffer& data, uint8_t* digest, size_t digest_len) const;
+    bool Sign(const uint8_t* data, size_t data_len, uint8_t* digest, size_t digest_len) const;
+
+    // Verify returns true if |digest| is a valid HMAC of |data| using the key
+    // supplied to Init. |digest| must be exactly |DigestLength()| bytes long.
+    // Use of this method is strongly recommended over using Sign() with a manual
+    // comparison (such as memcmp), as such comparisons may result in
+    // side-channel disclosures, such as timing, that undermine the cryptographic
+    // integrity.
+    bool Verify(const Buffer& data, const Buffer& digest) const;
+    bool Verify(const uint8_t* data, size_t data_len, const uint8_t* digest,
+                size_t digest_len) const;
+
+  private:
+    UniquePtr<uint8_t[]> key_;
+    size_t key_len_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_HMAC_H_
diff --git a/keymaster/hmac_key.cpp b/keymaster/hmac_key.cpp
new file mode 100644
index 0000000..40a8906
--- /dev/null
+++ b/keymaster/hmac_key.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "hmac_key.h"
+
+#include <new>
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include "hmac_operation.h"
+
+namespace keymaster {
+
+static HmacSignOperationFactory sign_factory;
+static HmacVerifyOperationFactory verify_factory;
+
+OperationFactory* HmacKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return &sign_factory;
+    case KM_PURPOSE_VERIFY:
+        return &verify_factory;
+    default:
+        return nullptr;
+    }
+}
+
+keymaster_error_t HmacKeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                          const AuthorizationSet& /* additional_params */,
+                                          const AuthorizationSet& hw_enforced,
+                                          const AuthorizationSet& sw_enforced,
+                                          UniquePtr<Key>* key) const {
+    if (!key)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    uint32_t min_mac_length;
+    if (!hw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length) &&
+        !sw_enforced.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length)) {
+        LOG_E("HMAC key must have KM_TAG_MIN_MAC_LENGTH", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    keymaster_error_t error;
+    key->reset(new (std::nothrow) HmacKey(key_material, hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return error;
+}
+
+keymaster_error_t HmacKeyFactory::validate_algorithm_specific_new_key_params(
+    const AuthorizationSet& key_description) const {
+    uint32_t min_mac_length_bits;
+    if (!key_description.GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length_bits))
+        return KM_ERROR_MISSING_MIN_MAC_LENGTH;
+
+    keymaster_digest_t digest;
+    if (!key_description.GetTagValue(TAG_DIGEST, &digest)) {
+        LOG_E("%d digests specified for HMAC key", key_description.GetTagCount(TAG_DIGEST));
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    }
+
+    size_t hash_size_bits = 0;
+    switch (digest) {
+    case KM_DIGEST_NONE:
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    case KM_DIGEST_MD5:
+        hash_size_bits = 128;
+        break;
+    case KM_DIGEST_SHA1:
+        hash_size_bits = 160;
+        break;
+    case KM_DIGEST_SHA_2_224:
+        hash_size_bits = 224;
+        break;
+    case KM_DIGEST_SHA_2_256:
+        hash_size_bits = 256;
+        break;
+    case KM_DIGEST_SHA_2_384:
+        hash_size_bits = 384;
+        break;
+    case KM_DIGEST_SHA_2_512:
+        hash_size_bits = 512;
+        break;
+    };
+
+    if (hash_size_bits == 0) {
+        // digest was not matched
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    }
+
+    if (min_mac_length_bits % 8 != 0 || min_mac_length_bits > hash_size_bits)
+        return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH;
+
+    if (min_mac_length_bits < kMinHmacLengthBits)
+        return KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH;
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/hmac_key.h b/keymaster/hmac_key.h
new file mode 100644
index 0000000..c05e6a3
--- /dev/null
+++ b/keymaster/hmac_key.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_HMAC_KEY_H_
+#define SYSTEM_KEYMASTER_HMAC_KEY_H_
+
+#include "symmetric_key.h"
+
+namespace keymaster {
+
+const size_t kMinHmacLengthBits = 64;
+
+class HmacKeyFactory : public SymmetricKeyFactory {
+  public:
+    explicit HmacKeyFactory(const KeymasterContext* context) : SymmetricKeyFactory(context) {}
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+  private:
+    bool key_size_supported(size_t key_size_bits) const override {
+        return key_size_bits > 0 && key_size_bits % 8 == 00 &&
+               key_size_bits <= 2048 /* Some RFC test cases require >1024-bit keys */;
+    }
+    keymaster_error_t validate_algorithm_specific_new_key_params(
+        const AuthorizationSet& key_description) const override;
+};
+
+class HmacKey : public SymmetricKey {
+  public:
+    HmacKey(const KeymasterKeyBlob& key_material, const AuthorizationSet& hw_enforced,
+            const AuthorizationSet& sw_enforced, keymaster_error_t* error)
+        : SymmetricKey(key_material, hw_enforced, sw_enforced, error) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_HMAC_KEY_H_
diff --git a/keymaster/hmac_operation.cpp b/keymaster/hmac_operation.cpp
new file mode 100644
index 0000000..7f21393
--- /dev/null
+++ b/keymaster/hmac_operation.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "hmac_operation.h"
+
+#include <new>
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include "hmac_key.h"
+#include "openssl_err.h"
+
+#if defined(OPENSSL_IS_BORINGSSL)
+#include <openssl/mem.h>
+typedef size_t openssl_size_t;
+#else
+typedef int openssl_size_t;
+#endif
+
+namespace keymaster {
+
+Operation* HmacOperationFactory::CreateOperation(const Key& key,
+                                                 const AuthorizationSet& begin_params,
+                                                 keymaster_error_t* error) {
+    uint32_t min_mac_length_bits;
+    if (!key.authorizations().GetTagValue(TAG_MIN_MAC_LENGTH, &min_mac_length_bits)) {
+        LOG_E("HMAC key must have KM_TAG_MIN_MAC_LENGTH", 0);
+        *error = KM_ERROR_INVALID_KEY_BLOB;
+        return nullptr;
+    }
+
+    uint32_t mac_length_bits = UINT32_MAX;
+    if (begin_params.GetTagValue(TAG_MAC_LENGTH, &mac_length_bits)) {
+        if (purpose() == KM_PURPOSE_VERIFY) {
+            LOG_E("MAC length may not be specified for verify", 0);
+            *error = KM_ERROR_INVALID_ARGUMENT;
+            return nullptr;
+        }
+    } else {
+        if (purpose() == KM_PURPOSE_SIGN) {
+            *error = KM_ERROR_MISSING_MAC_LENGTH;
+            return nullptr;
+        }
+    }
+
+    keymaster_digest_t digest;
+    if (!key.authorizations().GetTagValue(TAG_DIGEST, &digest)) {
+        LOG_E("%d digests found in HMAC key authorizations; must be exactly 1",
+              begin_params.GetTagCount(TAG_DIGEST));
+        *error = KM_ERROR_INVALID_KEY_BLOB;
+        return nullptr;
+    }
+
+    const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
+    UniquePtr<HmacOperation> op(new (std::nothrow) HmacOperation(
+        purpose(), symmetric_key->key_data(), symmetric_key->key_data_size(), digest,
+        mac_length_bits / 8, min_mac_length_bits / 8));
+    if (!op.get())
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    else
+        *error = op->error();
+
+    if (*error != KM_ERROR_OK)
+        return nullptr;
+
+    return op.release();
+}
+
+static keymaster_digest_t supported_digests[] = {KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
+                                                 KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384,
+                                                 KM_DIGEST_SHA_2_512};
+const keymaster_digest_t* HmacOperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = array_length(supported_digests);
+    return supported_digests;
+}
+
+HmacOperation::HmacOperation(keymaster_purpose_t purpose, const uint8_t* key_data,
+                             size_t key_data_size, keymaster_digest_t digest, size_t mac_length,
+                             size_t min_mac_length)
+    : Operation(purpose), error_(KM_ERROR_OK), mac_length_(mac_length),
+      min_mac_length_(min_mac_length) {
+    // Initialize CTX first, so dtor won't crash even if we error out later.
+    HMAC_CTX_init(&ctx_);
+
+    const EVP_MD* md = nullptr;
+    switch (digest) {
+    case KM_DIGEST_NONE:
+    case KM_DIGEST_MD5:
+        error_ = KM_ERROR_UNSUPPORTED_DIGEST;
+        break;
+    case KM_DIGEST_SHA1:
+        md = EVP_sha1();
+        break;
+    case KM_DIGEST_SHA_2_224:
+        md = EVP_sha224();
+        break;
+    case KM_DIGEST_SHA_2_256:
+        md = EVP_sha256();
+        break;
+    case KM_DIGEST_SHA_2_384:
+        md = EVP_sha384();
+        break;
+    case KM_DIGEST_SHA_2_512:
+        md = EVP_sha512();
+        break;
+    }
+
+    if (md == nullptr) {
+        error_ = KM_ERROR_UNSUPPORTED_DIGEST;
+        return;
+    }
+
+    if (purpose == KM_PURPOSE_SIGN) {
+        if (mac_length > EVP_MD_size(md) || mac_length < kMinHmacLengthBits / 8) {
+            error_ = KM_ERROR_UNSUPPORTED_MAC_LENGTH;
+            return;
+        }
+        if (mac_length < min_mac_length) {
+            error_ = KM_ERROR_INVALID_MAC_LENGTH;
+            return;
+        }
+    }
+
+    HMAC_Init_ex(&ctx_, key_data, key_data_size, md, NULL /* engine */);
+}
+
+HmacOperation::~HmacOperation() {
+    HMAC_CTX_cleanup(&ctx_);
+}
+
+keymaster_error_t HmacOperation::Begin(const AuthorizationSet& /* input_params */,
+                                       AuthorizationSet* /* output_params */) {
+    return error_;
+}
+
+keymaster_error_t HmacOperation::Update(const AuthorizationSet& /* additional_params */,
+                                        const Buffer& input, AuthorizationSet* /* output_params */,
+                                        Buffer* /* output */, size_t* input_consumed) {
+    if (!HMAC_Update(&ctx_, input.peek_read(), input.available_read()))
+        return TranslateLastOpenSslError();
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t HmacOperation::Abort() {
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t HmacOperation::Finish(const AuthorizationSet& additional_params,
+                                        const Buffer& input, const Buffer& signature,
+                                        AuthorizationSet* /* output_params */, Buffer* output) {
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    uint8_t digest[EVP_MAX_MD_SIZE];
+    unsigned int digest_len;
+    if (!HMAC_Final(&ctx_, digest, &digest_len))
+        return TranslateLastOpenSslError();
+
+    switch (purpose()) {
+    case KM_PURPOSE_SIGN:
+        if (mac_length_ > digest_len)
+            return KM_ERROR_UNSUPPORTED_MAC_LENGTH;
+        if (!output->reserve(mac_length_) || !output->write(digest, mac_length_))
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        return KM_ERROR_OK;
+    case KM_PURPOSE_VERIFY: {
+        size_t siglen = signature.available_read();
+        if (siglen > digest_len || siglen < kMinHmacLengthBits / 8)
+            return KM_ERROR_UNSUPPORTED_MAC_LENGTH;
+        if (siglen < min_mac_length_)
+            return KM_ERROR_INVALID_MAC_LENGTH;
+        if (CRYPTO_memcmp(signature.peek_read(), digest, siglen) != 0)
+            return KM_ERROR_VERIFICATION_FAILED;
+        return KM_ERROR_OK;
+    }
+    default:
+        return KM_ERROR_UNSUPPORTED_PURPOSE;
+    }
+}
+
+}  // namespace keymaster
diff --git a/keymaster/hmac_operation.h b/keymaster/hmac_operation.h
new file mode 100644
index 0000000..83f2e09
--- /dev/null
+++ b/keymaster/hmac_operation.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_HMAC_OPERATION_H_
+#define SYSTEM_KEYMASTER_HMAC_OPERATION_H_
+
+#include "operation.h"
+
+#include <openssl/hmac.h>
+
+namespace keymaster {
+
+class HmacOperation : public Operation {
+  public:
+    HmacOperation(keymaster_purpose_t purpose, const uint8_t* key_data, size_t key_data_size,
+                  keymaster_digest_t digest, size_t mac_length, size_t min_mac_length);
+    ~HmacOperation();
+
+    virtual keymaster_error_t Begin(const AuthorizationSet& input_params,
+                                    AuthorizationSet* output_params);
+    virtual keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                                     AuthorizationSet* output_params, Buffer* output,
+                                     size_t* input_consumed);
+    virtual keymaster_error_t Abort();
+    virtual keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                                     const Buffer& signature, AuthorizationSet* output_params,
+                                     Buffer* output);
+
+    keymaster_error_t error() { return error_; }
+
+  private:
+    HMAC_CTX ctx_;
+    keymaster_error_t error_;
+    const size_t mac_length_;
+    const size_t min_mac_length_;
+};
+
+/**
+ * Abstract base for HMAC operation factories.  This class does all of the work to create
+ * HMAC operations.
+ */
+class HmacOperationFactory : public OperationFactory {
+  public:
+    virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_HMAC, purpose()); }
+
+    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                                       keymaster_error_t* error);
+
+    virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const;
+
+    virtual keymaster_purpose_t purpose() const = 0;
+};
+
+class HmacSignOperationFactory : public HmacOperationFactory {
+    keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
+};
+
+class HmacVerifyOperationFactory : public HmacOperationFactory {
+    keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_HMAC_OPERATION_H_
diff --git a/keymaster/hmac_test.cpp b/keymaster/hmac_test.cpp
new file mode 100644
index 0000000..04f9356
--- /dev/null
+++ b/keymaster/hmac_test.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#include "hmac.h"
+
+#include <gtest/gtest.h>
+#include <string.h>
+
+#include "android_keymaster_test_utils.h"
+
+using std::string;
+
+namespace keymaster {
+
+namespace test {
+
+struct HmacTest {
+    const char* data;
+    const char* key;
+    uint8_t digest[32];
+};
+
+static const HmacTest kHmacTests[] = {
+    {
+        "Test Using Larger Than Block-Size Key - Hash Key First",
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+        {
+            0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5,
+            0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f,
+            0x0e, 0xe3, 0x7f, 0x54,
+        },
+    },
+    {
+        "The test message for the MD2, MD5, and SHA-1 hashing algorithms.",
+        "46697265666f7820616e64205468756e64657242697264206172652061776573"
+        "6f6d652100",
+        {
+            0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44, 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14,
+            0x22, 0xe0, 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9, 0xa7, 0x1b, 0x56, 0x7d,
+            0x1d, 0x29, 0x40, 0x48,
+        },
+    },
+};
+
+TEST(HmacTest, SHA256) {
+    for (size_t i = 0; i < 2; i++) {
+        const HmacTest& test(kHmacTests[i]);
+
+        HmacSha256 hmac;
+        const string key = hex2str(test.key);
+        Buffer key_buffer(key.data(), key.size());
+        ASSERT_TRUE(hmac.Init(key_buffer));
+
+        uint8_t digest_copy[sizeof(test.digest)];
+        memcpy(digest_copy, test.digest, sizeof(test.digest));
+        Buffer digest_buffer(reinterpret_cast<uint8_t*>(digest_copy), sizeof(digest_copy));
+
+        Buffer data_buffer(test.data, strlen(test.data));
+        EXPECT_TRUE(hmac.Verify(data_buffer, digest_buffer));
+
+        digest_copy[16] ^= 0x80;
+        digest_buffer.Reinitialize(reinterpret_cast<uint8_t*>(digest_copy), sizeof(digest_copy));
+        EXPECT_FALSE(hmac.Verify(data_buffer, digest_buffer));
+    }
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/include/keymaster/android_keymaster.h b/keymaster/include/keymaster/android_keymaster.h
new file mode 100644
index 0000000..c7ecfad
--- /dev/null
+++ b/keymaster/include/keymaster/android_keymaster.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ANDROID_KEYMASTER_H_
+#define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_H_
+
+#include <keymaster/android_keymaster_messages.h>
+#include <keymaster/authorization_set.h>
+
+namespace keymaster {
+
+class Key;
+class KeyFactory;
+class KeymasterContext;
+class OperationTable;
+
+/**
+ * This is the reference implementation of Keymaster.  In addition to acting as a reference for
+ * other Keymaster implementers to check their assumptions against, it is used by Keystore as the
+ * default implementation when no secure implementation is available, and may be installed and
+ * executed in secure hardware as a secure implementation.
+ *
+ * Note that this class doesn't actually implement the Keymaster HAL interface, instead it
+ * implements an alternative API which is similar to and based upon the HAL, but uses C++ "message"
+ * classes which support serialization.
+ *
+ * For non-secure, pure software implementation there is a HAL translation layer that converts the
+ * HAL's parameters to and from the message representations, which are then passed in to this
+ * API.
+ *
+ * For secure implementation there is another HAL translation layer that serializes the messages to
+ * the TEE. In the TEE implementation there's another component which deserializes the messages,
+ * extracts the relevant parameters and calls this API.
+ */
+class AndroidKeymaster {
+  public:
+    AndroidKeymaster(KeymasterContext* context, size_t operation_table_size);
+    virtual ~AndroidKeymaster();
+
+    void GetVersion(const GetVersionRequest& request, GetVersionResponse* response);
+    void SupportedAlgorithms(const SupportedAlgorithmsRequest& request,
+                             SupportedAlgorithmsResponse* response);
+    void SupportedBlockModes(const SupportedBlockModesRequest& request,
+                             SupportedBlockModesResponse* response);
+    void SupportedPaddingModes(const SupportedPaddingModesRequest& request,
+                               SupportedPaddingModesResponse* response);
+    void SupportedDigests(const SupportedDigestsRequest& request,
+                          SupportedDigestsResponse* response);
+    void SupportedImportFormats(const SupportedImportFormatsRequest& request,
+                                SupportedImportFormatsResponse* response);
+    void SupportedExportFormats(const SupportedExportFormatsRequest& request,
+                                SupportedExportFormatsResponse* response);
+
+    void AddRngEntropy(const AddEntropyRequest& request, AddEntropyResponse* response);
+    void GenerateKey(const GenerateKeyRequest& request, GenerateKeyResponse* response);
+    void GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
+                               GetKeyCharacteristicsResponse* response);
+    void ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response);
+    void ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response);
+    void AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response);
+    void DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response);
+    void DeleteAllKeys(const DeleteAllKeysRequest& request, DeleteAllKeysResponse* response);
+    void BeginOperation(const BeginOperationRequest& request, BeginOperationResponse* response);
+    void UpdateOperation(const UpdateOperationRequest& request, UpdateOperationResponse* response);
+    void FinishOperation(const FinishOperationRequest& request, FinishOperationResponse* response);
+    void AbortOperation(const AbortOperationRequest& request, AbortOperationResponse* response);
+
+    bool has_operation(keymaster_operation_handle_t op_handle) const;
+
+  private:
+    keymaster_error_t LoadKey(const keymaster_key_blob_t& key_blob,
+                              const AuthorizationSet& additional_params,
+                              AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced,
+                              const KeyFactory** factory, UniquePtr<Key>* key);
+
+    UniquePtr<KeymasterContext> context_;
+    UniquePtr<OperationTable> operation_table_;
+};
+
+}  // namespace keymaster
+
+#endif  //  SYSTEM_KEYMASTER_ANDROID_KEYMASTER_H_
diff --git a/keymaster/include/keymaster/android_keymaster_messages.h b/keymaster/include/keymaster/android_keymaster_messages.h
new file mode 100644
index 0000000..30d3fb7
--- /dev/null
+++ b/keymaster/include/keymaster/android_keymaster_messages.h
@@ -0,0 +1,627 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ANDROID_KEYMASTER_MESSAGES_H_
+#define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_MESSAGES_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+
+namespace keymaster {
+
+// Commands
+enum AndroidKeymasterCommand {
+    GENERATE_KEY = 0,
+    BEGIN_OPERATION = 1,
+    UPDATE_OPERATION = 2,
+    FINISH_OPERATION = 3,
+    ABORT_OPERATION = 4,
+    IMPORT_KEY = 5,
+    EXPORT_KEY = 6,
+    GET_VERSION = 7,
+    ADD_RNG_ENTROPY = 8,
+    GET_SUPPORTED_ALGORITHMS = 9,
+    GET_SUPPORTED_BLOCK_MODES = 10,
+    GET_SUPPORTED_PADDING_MODES = 11,
+    GET_SUPPORTED_DIGESTS = 12,
+    GET_SUPPORTED_IMPORT_FORMATS = 13,
+    GET_SUPPORTED_EXPORT_FORMATS = 14,
+    GET_KEY_CHARACTERISTICS = 15,
+    ATTEST_KEY = 16,
+};
+
+/**
+ * Keymaster message versions are tied to keymaster versions.  We map the keymaster
+ * major.minor.subminor version to a sequential "message version".
+ *
+ * Rather than encoding a version number into each message we rely on the client -- who initiates
+ * all requests -- to check the version of the keymaster implementation with the GET_VERSION command
+ * and to send only requests that the implementation can understand.  This means that only the
+ * client side needs to manage version compatibility; the implementation can always expect/produce
+ * messages of its format.
+ *
+ * Because message version selection is purely a client-side issue, all messages default to using
+ * the latest version (MAX_MESSAGE_VERSION).  Client code must take care to check versions and pass
+ * correct version values to message constructors.  The AndroidKeymaster implementation always uses
+ * the default, latest.
+ *
+ * Note that this approach implies that GetVersionRequest and GetVersionResponse cannot be
+ * versioned.
+ */
+const int32_t MAX_MESSAGE_VERSION = 3;
+inline int32_t MessageVersion(uint8_t major_ver, uint8_t minor_ver, uint8_t /* subminor_ver */) {
+    int32_t message_version = -1;
+    switch (major_ver) {
+    case 0:
+        // For the moment we still support version 0, though in general the plan is not to support
+        // non-matching major versions.
+        message_version = 0;
+        break;
+    case 1:
+        switch (minor_ver) {
+        case 0:
+            message_version = 1;
+            break;
+        case 1:
+            message_version = 2;
+            break;
+        }
+        break;
+    case 2:
+        message_version = 3;
+        break;
+    };
+    return message_version;
+}
+
+struct KeymasterMessage : public Serializable {
+    explicit KeymasterMessage(int32_t ver) : message_version(ver) { assert(ver >= 0); }
+    uint32_t message_version;
+};
+
+/**
+ * All responses include an error value, and if the error is not KM_ERROR_OK, return no additional
+ * data.  This abstract class factors out the common serialization functionality for all of the
+ * responses, so we only have to implement it once.  Inheritance for reuse is generally not a great
+ * structure, but in this case it's the cleanest option.
+ */
+struct KeymasterResponse : public KeymasterMessage {
+    explicit KeymasterResponse(int32_t ver)
+        : KeymasterMessage(ver), error(KM_ERROR_UNKNOWN_ERROR) {}
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    virtual size_t NonErrorSerializedSize() const = 0;
+    virtual uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const = 0;
+    virtual bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) = 0;
+
+    keymaster_error_t error;
+};
+
+struct SupportedAlgorithmsRequest : public KeymasterMessage {
+    explicit SupportedAlgorithmsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override { return 0; };
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* /* end */) const override { return buf; }
+    bool Deserialize(const uint8_t** /* buf_ptr */, const uint8_t* /* end */) override {
+        return true;
+    }
+};
+
+struct SupportedByAlgorithmRequest : public KeymasterMessage {
+    explicit SupportedByAlgorithmRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override { return sizeof(uint32_t); };
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
+        return append_uint32_to_buf(buf, end, algorithm);
+    }
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+        return copy_uint32_from_buf(buf_ptr, end, &algorithm);
+    }
+
+    keymaster_algorithm_t algorithm;
+};
+
+struct SupportedImportFormatsRequest : public SupportedByAlgorithmRequest {
+    explicit SupportedImportFormatsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedByAlgorithmRequest(ver) {}
+};
+
+struct SupportedExportFormatsRequest : public SupportedByAlgorithmRequest {
+    explicit SupportedExportFormatsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedByAlgorithmRequest(ver) {}
+};
+
+struct SupportedByAlgorithmAndPurposeRequest : public KeymasterMessage {
+    explicit SupportedByAlgorithmAndPurposeRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override { return sizeof(uint32_t) * 2; };
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
+        buf = append_uint32_to_buf(buf, end, algorithm);
+        return append_uint32_to_buf(buf, end, purpose);
+    }
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+        return copy_uint32_from_buf(buf_ptr, end, &algorithm) &&
+               copy_uint32_from_buf(buf_ptr, end, &purpose);
+    }
+
+    keymaster_algorithm_t algorithm;
+    keymaster_purpose_t purpose;
+};
+
+struct SupportedBlockModesRequest : public SupportedByAlgorithmAndPurposeRequest {
+    explicit SupportedBlockModesRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedByAlgorithmAndPurposeRequest(ver) {}
+};
+
+struct SupportedPaddingModesRequest : public SupportedByAlgorithmAndPurposeRequest {
+    explicit SupportedPaddingModesRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedByAlgorithmAndPurposeRequest(ver) {}
+};
+
+struct SupportedDigestsRequest : public SupportedByAlgorithmAndPurposeRequest {
+    explicit SupportedDigestsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedByAlgorithmAndPurposeRequest(ver) {}
+};
+
+template <typename T> struct SupportedResponse : public KeymasterResponse {
+    explicit SupportedResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterResponse(ver), results(nullptr), results_length(0) {}
+    ~SupportedResponse() { delete[] results; }
+
+    template <size_t N> void SetResults(const T (&arr)[N]) { SetResults(arr, N); }
+
+    void SetResults(const T* arr, size_t n) {
+        delete[] results;
+        results_length = 0;
+        results = dup_array(arr, n);
+        if (results == nullptr) {
+            error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        } else {
+            results_length = n;
+            error = KM_ERROR_OK;
+        }
+    }
+
+    size_t NonErrorSerializedSize() const override {
+        return sizeof(uint32_t) + results_length * sizeof(uint32_t);
+    }
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override {
+        return append_uint32_array_to_buf(buf, end, results, results_length);
+    }
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+        delete[] results;
+        results = nullptr;
+        UniquePtr<T[]> tmp;
+        if (!copy_uint32_array_from_buf(buf_ptr, end, &tmp, &results_length))
+            return false;
+        results = tmp.release();
+        return true;
+    }
+
+    T* results;
+    size_t results_length;
+};
+
+struct SupportedAlgorithmsResponse : public SupportedResponse<keymaster_algorithm_t> {
+    explicit SupportedAlgorithmsResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedResponse<keymaster_algorithm_t>(ver) {}
+};
+
+struct SupportedBlockModesResponse : public SupportedResponse<keymaster_block_mode_t> {
+    explicit SupportedBlockModesResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedResponse<keymaster_block_mode_t>(ver) {}
+};
+
+struct SupportedPaddingModesResponse : public SupportedResponse<keymaster_padding_t> {
+    explicit SupportedPaddingModesResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedResponse<keymaster_padding_t>(ver) {}
+};
+
+struct SupportedDigestsResponse : public SupportedResponse<keymaster_digest_t> {
+    explicit SupportedDigestsResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedResponse<keymaster_digest_t>(ver) {}
+};
+
+struct SupportedImportFormatsResponse : public SupportedResponse<keymaster_key_format_t> {
+    explicit SupportedImportFormatsResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedResponse<keymaster_key_format_t>(ver) {}
+};
+
+struct SupportedExportFormatsResponse : public SupportedResponse<keymaster_key_format_t> {
+    explicit SupportedExportFormatsResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : SupportedResponse<keymaster_key_format_t>(ver) {}
+};
+
+struct GenerateKeyRequest : public KeymasterMessage {
+    explicit GenerateKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override { return key_description.SerializedSize(); }
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
+        return key_description.Serialize(buf, end);
+    }
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+        return key_description.Deserialize(buf_ptr, end);
+    }
+
+    AuthorizationSet key_description;
+};
+
+struct GenerateKeyResponse : public KeymasterResponse {
+    explicit GenerateKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~GenerateKeyResponse();
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_key_blob_t key_blob;
+    AuthorizationSet enforced;
+    AuthorizationSet unenforced;
+};
+
+struct GetKeyCharacteristicsRequest : public KeymasterMessage {
+    explicit GetKeyCharacteristicsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~GetKeyCharacteristicsRequest();
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_key_blob_t key_blob;
+    AuthorizationSet additional_params;
+};
+
+struct GetKeyCharacteristicsResponse : public KeymasterResponse {
+    explicit GetKeyCharacteristicsResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterResponse(ver) {}
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    AuthorizationSet enforced;
+    AuthorizationSet unenforced;
+};
+
+struct BeginOperationRequest : public KeymasterMessage {
+    explicit BeginOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~BeginOperationRequest() { delete[] key_blob.key_material; }
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t SerializedSize() const;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_purpose_t purpose;
+    keymaster_key_blob_t key_blob;
+    AuthorizationSet additional_params;
+};
+
+struct BeginOperationResponse : public KeymasterResponse {
+    explicit BeginOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_operation_handle_t op_handle;
+    AuthorizationSet output_params;
+};
+
+struct UpdateOperationRequest : public KeymasterMessage {
+    explicit UpdateOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_operation_handle_t op_handle;
+    Buffer input;
+    AuthorizationSet additional_params;
+};
+
+struct UpdateOperationResponse : public KeymasterResponse {
+    explicit UpdateOperationResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterResponse(ver), input_consumed(0) {}
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    Buffer output;
+    size_t input_consumed;
+    AuthorizationSet output_params;
+};
+
+struct FinishOperationRequest : public KeymasterMessage {
+    explicit FinishOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_operation_handle_t op_handle;
+    Buffer input;
+    Buffer signature;
+    AuthorizationSet additional_params;
+};
+
+struct FinishOperationResponse : public KeymasterResponse {
+    explicit FinishOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    Buffer output;
+    AuthorizationSet output_params;
+};
+
+struct AbortOperationRequest : public KeymasterMessage {
+    explicit AbortOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override { return sizeof(uint64_t); }
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override {
+        return append_uint64_to_buf(buf, end, op_handle);
+    }
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
+        return copy_uint64_from_buf(buf_ptr, end, &op_handle);
+    }
+
+    keymaster_operation_handle_t op_handle;
+};
+
+struct AbortOperationResponse : public KeymasterResponse {
+    explicit AbortOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+
+    size_t NonErrorSerializedSize() const override { return 0; }
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t*) const override { return buf; }
+    bool NonErrorDeserialize(const uint8_t**, const uint8_t*) override { return true; }
+};
+
+struct AddEntropyRequest : public KeymasterMessage {
+    explicit AddEntropyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    Buffer random_data;
+};
+
+struct AddEntropyResponse : public KeymasterResponse {
+    explicit AddEntropyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+
+    size_t NonErrorSerializedSize() const override { return 0; }
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* /* end */) const override {
+        return buf;
+    }
+    bool NonErrorDeserialize(const uint8_t** /* buf_ptr */, const uint8_t* /* end */) override {
+        return true;
+    }
+};
+
+struct ImportKeyRequest : public KeymasterMessage {
+    explicit ImportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver), key_data(nullptr) {}
+    ~ImportKeyRequest() { delete[] key_data; }
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    AuthorizationSet key_description;
+    keymaster_key_format_t key_format;
+    uint8_t* key_data;
+    size_t key_data_length;
+};
+
+struct ImportKeyResponse : public KeymasterResponse {
+    explicit ImportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~ImportKeyResponse() { delete[] key_blob.key_material; }
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_key_blob_t key_blob;
+    AuthorizationSet enforced;
+    AuthorizationSet unenforced;
+};
+
+struct ExportKeyRequest : public KeymasterMessage {
+    explicit ExportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~ExportKeyRequest() { delete[] key_blob.key_material; }
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    AuthorizationSet additional_params;
+    keymaster_key_format_t key_format;
+    keymaster_key_blob_t key_blob;
+};
+
+struct ExportKeyResponse : public KeymasterResponse {
+    explicit ExportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterResponse(ver), key_data(nullptr) {}
+    ~ExportKeyResponse() { delete[] key_data; }
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    uint8_t* key_data;
+    size_t key_data_length;
+};
+
+struct DeleteKeyRequest : public KeymasterMessage {
+    explicit DeleteKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~DeleteKeyRequest() { delete[] key_blob.key_material; }
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_key_blob_t key_blob;
+};
+
+struct DeleteKeyResponse : public KeymasterResponse {
+    explicit DeleteKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+
+    size_t NonErrorSerializedSize() const override { return 0; }
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t*) const override { return buf; }
+    bool NonErrorDeserialize(const uint8_t**, const uint8_t*) override { return true; }
+};
+
+struct DeleteAllKeysRequest : public KeymasterMessage {
+    explicit DeleteAllKeysRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+
+    size_t SerializedSize() const override { return 0; }
+    uint8_t* Serialize(uint8_t* buf, const uint8_t*) const override { return buf; }
+    bool Deserialize(const uint8_t**, const uint8_t*) override { return true; };
+};
+
+struct DeleteAllKeysResponse : public KeymasterResponse {
+    explicit DeleteAllKeysResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+
+    size_t NonErrorSerializedSize() const override { return 0; }
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t*) const override { return buf; }
+    bool NonErrorDeserialize(const uint8_t**, const uint8_t*) override { return true; }
+};
+
+struct GetVersionRequest : public KeymasterMessage {
+    GetVersionRequest() : KeymasterMessage(0 /* not versionable */) {}
+
+    size_t SerializedSize() const override { return 0; }
+    uint8_t* Serialize(uint8_t* buf, const uint8_t*) const override { return buf; }
+    bool Deserialize(const uint8_t**, const uint8_t*) override { return true; };
+};
+
+struct GetVersionResponse : public KeymasterResponse {
+    GetVersionResponse()
+        : KeymasterResponse(0 /* not versionable */), major_ver(0), minor_ver(0), subminor_ver(0) {}
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    uint8_t major_ver;
+    uint8_t minor_ver;
+    uint8_t subminor_ver;
+};
+
+struct AttestKeyRequest : public KeymasterMessage {
+    explicit AttestKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+        key_blob.key_material = nullptr;
+        key_blob.key_material_size = 0;
+    }
+    ~AttestKeyRequest();
+
+    void SetKeyMaterial(const void* key_material, size_t length);
+    void SetKeyMaterial(const keymaster_key_blob_t& blob) {
+        SetKeyMaterial(blob.key_material, blob.key_material_size);
+    }
+
+    size_t SerializedSize() const override;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_key_blob_t key_blob;
+    AuthorizationSet attest_params;
+};
+
+struct AttestKeyResponse : public KeymasterResponse {
+    explicit AttestKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
+        certificate_chain.entry_count = 0;
+        certificate_chain.entries = nullptr;
+    }
+    ~AttestKeyResponse();
+
+    bool AllocateChain(size_t entry_count);
+
+    size_t NonErrorSerializedSize() const override;
+    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override;
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override;
+
+    keymaster_cert_chain_t certificate_chain;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_MESSAGES_H_
diff --git a/keymaster/include/keymaster/android_keymaster_utils.h b/keymaster/include/keymaster/android_keymaster_utils.h
new file mode 100644
index 0000000..c190e04
--- /dev/null
+++ b/keymaster/include/keymaster/android_keymaster_utils.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ANDROID_KEYMASTER_UTILS_H_
+#define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_UTILS_H_
+
+#include <stdint.h>
+#include <string.h>
+#include <time.h>  // for time_t.
+
+#include <UniquePtr.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/serializable.h>
+
+namespace keymaster {
+
+/**
+ * Convert the specified time value into "Java time", which is a signed 64-bit integer representing
+ * elapsed milliseconds since Jan 1, 1970.
+ */
+inline int64_t java_time(time_t time) {
+    // The exact meaning of a time_t value is implementation-dependent.  If this code is ported to a
+    // platform that doesn't define it as "seconds since Jan 1, 1970 UTC", this function will have
+    // to be revised.
+    return time * 1000;
+}
+
+/*
+ * Array Manipulation functions.  This set of templated inline functions provides some nice tools
+ * for operating on c-style arrays.  C-style arrays actually do have a defined size associated with
+ * them, as long as they are not allowed to decay to a pointer.  These template methods exploit this
+ * to allow size-based array operations without explicitly specifying the size.  If passed a pointer
+ * rather than an array, they'll fail to compile.
+ */
+
+/**
+ * Return the size in bytes of the array \p a.
+ */
+template <typename T, size_t N> inline size_t array_size(const T (&a)[N]) {
+    return sizeof(a);
+}
+
+/**
+ * Return the number of elements in array \p a.
+ */
+template <typename T, size_t N> inline size_t array_length(const T (&)[N]) {
+    return N;
+}
+
+/**
+ * Duplicate the array \p a.  The memory for the new array is allocated and the caller takes
+ * responsibility.
+ */
+template <typename T> inline T* dup_array(const T* a, size_t n) {
+    T* dup = new (std::nothrow) T[n];
+    if (dup)
+        for (size_t i = 0; i < n; ++i)
+            dup[i] = a[i];
+    return dup;
+}
+
+/**
+ * Duplicate the array \p a.  The memory for the new array is allocated and the caller takes
+ * responsibility.  Note that the dup is necessarily returned as a pointer, so size is lost.  Call
+ * array_length() on the original array to discover the size.
+ */
+template <typename T, size_t N> inline T* dup_array(const T (&a)[N]) {
+    return dup_array(a, N);
+}
+
+/**
+ * Duplicate the buffer \p buf.  The memory for the new buffer is allocated and the caller takes
+ * responsibility.
+ */
+uint8_t* dup_buffer(const void* buf, size_t size);
+
+/**
+ * Copy the contents of array \p arr to \p dest.
+ */
+template <typename T, size_t N> inline void copy_array(const T (&arr)[N], T* dest) {
+    for (size_t i = 0; i < N; ++i)
+        dest[i] = arr[i];
+}
+
+/**
+ * Search array \p a for value \p val, returning true if found.  Note that this function is
+ * early-exit, meaning that it should not be used in contexts where timing analysis attacks could be
+ * a concern.
+ */
+template <typename T, size_t N> inline bool array_contains(const T (&a)[N], T val) {
+    for (size_t i = 0; i < N; ++i) {
+        if (a[i] == val) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Variant of memset() that uses GCC-specific pragmas to disable optimizations, so effect is not
+ * optimized away.  This is important because we often need to wipe blocks of sensitive data from
+ * memory.  As an additional convenience, this implementation avoids writing to NULL pointers.
+ */
+#ifdef __clang__
+#define OPTNONE __attribute__((optnone))
+#else  // not __clang__
+#define OPTNONE __attribute__((optimize("O0")))
+#endif  // not __clang__
+inline OPTNONE void* memset_s(void* s, int c, size_t n) {
+    if (!s)
+        return s;
+    return memset(s, c, n);
+}
+#undef OPTNONE
+
+/**
+ * Variant of memcmp that has the same runtime regardless of whether the data matches (i.e. doesn't
+ * short-circuit).  Not an exact equivalent to memcmp because it doesn't return <0 if p1 < p2, just
+ * 0 for match and non-zero for non-match.
+ */
+int memcmp_s(const void* p1, const void* p2, size_t length);
+
+/**
+ * Eraser clears buffers.  Construct it with a buffer or object and the destructor will ensure that
+ * it is zeroed.
+ */
+class Eraser {
+  public:
+    /* Not implemented.  If this gets used, we want a link error. */
+    template <typename T> explicit Eraser(T* t);
+
+    template <typename T>
+    explicit Eraser(T& t) : buf_(reinterpret_cast<uint8_t*>(&t)), size_(sizeof(t)) {}
+
+    template <size_t N> explicit Eraser(uint8_t (&arr)[N]) : buf_(arr), size_(N) {}
+
+    Eraser(void* buf, size_t size) : buf_(static_cast<uint8_t*>(buf)), size_(size) {}
+    ~Eraser() { memset_s(buf_, 0, size_); }
+
+  private:
+    Eraser(const Eraser&);
+    void operator=(const Eraser&);
+
+    uint8_t* buf_;
+    size_t size_;
+};
+
+/**
+ * ArrayWrapper is a trivial wrapper around a C-style array that provides begin() and end()
+ * methods. This is primarily to facilitate range-based iteration on arrays.  It does not copy, nor
+ * does it take ownership; it just holds pointers.
+ */
+template <typename T> class ArrayWrapper {
+  public:
+    ArrayWrapper(T* array, size_t size) : begin_(array), end_(array + size) {}
+
+    T* begin() { return begin_; }
+    T* end() { return end_; }
+
+  private:
+    T* begin_;
+    T* end_;
+};
+template <typename T> ArrayWrapper<T> array_range(T* begin, size_t length) {
+    return ArrayWrapper<T>(begin, length);
+}
+
+/**
+ * Convert any unsigned integer from network to host order.  We implement this here rather than
+ * using the functions from arpa/inet.h because the TEE doesn't have inet.h.  This isn't the most
+ * efficient implementation, but the compiler should unroll the loop and tighten it up.
+ */
+template <typename T> T ntoh(T t) {
+    const uint8_t* byte_ptr = reinterpret_cast<const uint8_t*>(&t);
+    T retval = 0;
+    for (size_t i = 0; i < sizeof(t); ++i) {
+        retval <<= 8;
+        retval |= byte_ptr[i];
+    }
+    return retval;
+}
+
+/**
+ * Convert any unsigned integer from host to network order.  We implement this here rather than
+ * using the functions from arpa/inet.h because the TEE doesn't have inet.h.  This isn't the most
+ * efficient implementation, but the compiler should unroll the loop and tighten it up.
+ */
+template <typename T> T hton(T t) {
+    T retval;
+    uint8_t* byte_ptr = reinterpret_cast<uint8_t*>(&retval);
+    for (size_t i = sizeof(t); i > 0; --i) {
+        byte_ptr[i - 1] = t & 0xFF;
+        t >>= 8;
+    }
+    return retval;
+}
+
+/**
+ * KeymasterKeyBlob is a very simple extension of the C struct keymaster_key_blob_t.  It manages its
+ * own memory, which makes avoiding memory leaks much easier.
+ */
+struct KeymasterKeyBlob : public keymaster_key_blob_t {
+    KeymasterKeyBlob() {
+        key_material = nullptr;
+        key_material_size = 0;
+    }
+
+    KeymasterKeyBlob(const uint8_t* data, size_t size) {
+        key_material_size = 0;
+        key_material = dup_buffer(data, size);
+        if (key_material)
+            key_material_size = size;
+    }
+
+    explicit KeymasterKeyBlob(size_t size) {
+        key_material_size = 0;
+        key_material = new (std::nothrow) uint8_t[size];
+        if (key_material)
+            key_material_size = size;
+    }
+
+    explicit KeymasterKeyBlob(const keymaster_key_blob_t& blob) {
+        key_material_size = 0;
+        key_material = dup_buffer(blob.key_material, blob.key_material_size);
+        if (key_material)
+            key_material_size = blob.key_material_size;
+    }
+
+    KeymasterKeyBlob(const KeymasterKeyBlob& blob) {
+        key_material_size = 0;
+        key_material = dup_buffer(blob.key_material, blob.key_material_size);
+        if (key_material)
+            key_material_size = blob.key_material_size;
+    }
+
+    void operator=(const KeymasterKeyBlob& blob) {
+        Clear();
+        key_material = dup_buffer(blob.key_material, blob.key_material_size);
+        key_material_size = blob.key_material_size;
+    }
+
+    ~KeymasterKeyBlob() { Clear(); }
+
+    const uint8_t* begin() const { return key_material; }
+    const uint8_t* end() const { return key_material + key_material_size; }
+
+    void Clear() {
+        memset_s(const_cast<uint8_t*>(key_material), 0, key_material_size);
+        delete[] key_material;
+        key_material = nullptr;
+        key_material_size = 0;
+    }
+
+    const uint8_t* Reset(size_t new_size) {
+        Clear();
+        key_material = new (std::nothrow) uint8_t[new_size];
+        if (key_material)
+            key_material_size = new_size;
+        return key_material;
+    }
+
+    // The key_material in keymaster_key_blob_t is const, which is the right thing in most
+    // circumstances, but occasionally we do need to write into it.  This method exposes a non-const
+    // version of the pointer.  Use sparingly.
+    uint8_t* writable_data() { return const_cast<uint8_t*>(key_material); }
+
+    keymaster_key_blob_t release() {
+        keymaster_key_blob_t tmp = {key_material, key_material_size};
+        key_material = nullptr;
+        key_material_size = 0;
+        return tmp;
+    }
+
+    size_t SerializedSize() const { return sizeof(uint32_t) + key_material_size; }
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const {
+        return append_size_and_data_to_buf(buf, end, key_material, key_material_size);
+    }
+
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+        Clear();
+        UniquePtr<uint8_t[]> tmp;
+        if (!copy_size_and_data_from_buf(buf_ptr, end, &key_material_size, &tmp)) {
+            key_material = nullptr;
+            key_material_size = 0;
+            return false;
+        }
+        key_material = tmp.release();
+        return true;
+    }
+};
+
+struct Characteristics_Delete {
+    void operator()(keymaster_key_characteristics_t* p) {
+        keymaster_free_characteristics(p);
+        free(p);
+    }
+};
+
+struct Malloc_Delete {
+    void operator()(void* p) { free(p); }
+};
+
+struct CertificateChainDelete {
+    void operator()(keymaster_cert_chain_t* p) {
+        if (!p)
+            return;
+        for (size_t i = 0; i < p->entry_count; ++i)
+            delete[] p->entries[i].data;
+        delete[] p->entries;
+        delete p;
+    }
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_UTILS_H_
diff --git a/keymaster/include/keymaster/asymmetric_key_factory.h b/keymaster/include/keymaster/asymmetric_key_factory.h
new file mode 100644
index 0000000..afcfc1c
--- /dev/null
+++ b/keymaster/include/keymaster/asymmetric_key_factory.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ASYMMETRIC_KEY_FACTORY_H_
+#define SYSTEM_KEYMASTER_ASYMMETRIC_KEY_FACTORY_H_
+
+#include <keymaster/key_factory.h>
+
+namespace keymaster {
+
+/**
+ * Abstract base for KeyFactories that handle asymmetric keys.
+ */
+class AsymmetricKey;
+class AsymmetricKeyFactory : public KeyFactory {
+  public:
+    explicit AsymmetricKeyFactory(const KeymasterContext* context) : KeyFactory(context) {}
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    virtual keymaster_error_t CreateEmptyKey(const AuthorizationSet& hw_enforced,
+                                             const AuthorizationSet& sw_enforced,
+                                             UniquePtr<AsymmetricKey>* key) const = 0;
+
+    virtual keymaster_algorithm_t keymaster_key_type() const = 0;
+    virtual int evp_key_type() const = 0;
+
+    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const;
+    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ASYMMETRIC_KEY_FACTORY_H_
diff --git a/keymaster/include/keymaster/authorization_set.h b/keymaster/include/keymaster/authorization_set.h
new file mode 100644
index 0000000..74daa8d
--- /dev/null
+++ b/keymaster/include/keymaster/authorization_set.h
@@ -0,0 +1,570 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_AUTHORIZATION_SET_H_
+#define SYSTEM_KEYMASTER_AUTHORIZATION_SET_H_
+
+#include <UniquePtr.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/keymaster_tags.h>
+#include <keymaster/serializable.h>
+
+namespace keymaster {
+
+class AuthorizationSetBuilder;
+
+/**
+ * An extension of the keymaster_key_param_set_t struct, which provides serialization memory
+ * management and methods for easy manipulation and construction.
+ */
+class AuthorizationSet : public Serializable, public keymaster_key_param_set_t {
+  public:
+    /**
+     * Construct an empty, dynamically-allocated, growable AuthorizationSet.  Does not actually
+     * allocate any storage until elements are added, so there is no cost to creating an
+     * AuthorizationSet with this constructor and then reinitializing it to point at pre-allocated
+     * buffers, with \p Reinitialize.
+     */
+    AuthorizationSet()
+        : elems_capacity_(0), indirect_data_(NULL), indirect_data_size_(0),
+          indirect_data_capacity_(0), error_(OK) {
+        elems_ = nullptr;
+        elems_size_ = 0;
+    }
+
+    /**
+     * Construct an AuthorizationSet from the provided array.  The AuthorizationSet copies the data
+     * from the provided array (and the data referenced by its embedded pointers, if any) into
+     * dynamically-allocated storage.  If allocation of the needed storage fails, \p is_valid() will
+     * return ALLOCATION_FAILURE. It is the responsibility of the caller to check before using the
+     * set, if allocations might fail.
+     */
+    AuthorizationSet(const keymaster_key_param_t* elems, size_t count) : indirect_data_(nullptr) {
+        elems_ = nullptr;
+        Reinitialize(elems, count);
+    }
+
+    explicit AuthorizationSet(const keymaster_key_param_set_t& set) : indirect_data_(nullptr) {
+        elems_ = nullptr;
+        Reinitialize(set.params, set.length);
+    }
+
+    explicit AuthorizationSet(const uint8_t* serialized_set, size_t serialized_size)
+        : indirect_data_(nullptr) {
+        elems_ = nullptr;
+        Deserialize(&serialized_set, serialized_set + serialized_size);
+    }
+
+    /**
+     * Construct an AuthorizationSet from the provided builder.  This extracts the data from the
+     * builder, rather than copying it, so after this call the builder is empty.
+     */
+    explicit AuthorizationSet(/* NOT const */ AuthorizationSetBuilder& builder);
+
+    // Copy constructor.
+    AuthorizationSet(const AuthorizationSet& set) : Serializable(), indirect_data_(nullptr) {
+        elems_ = nullptr;
+        Reinitialize(set.elems_, set.elems_size_);
+    }
+
+    /**
+     * Clear existing authorization set data
+     */
+    void Clear();
+
+    /**
+     * Reinitialize an AuthorizationSet as a dynamically-allocated, growable copy of the data in the
+     * provided array (and the data referenced by its embedded pointers, if any).  If the allocation
+     * of the needed storage fails this method will return false and \p is_valid() will return
+     * ALLOCATION_FAILURE.
+     */
+    bool Reinitialize(const keymaster_key_param_t* elems, size_t count);
+
+    bool Reinitialize(const AuthorizationSet& set) {
+        return Reinitialize(set.elems_, set.elems_size_);
+    }
+
+    bool Reinitialize(const keymaster_key_param_set_t& set) {
+        return Reinitialize(set.params, set.length);
+    }
+
+    ~AuthorizationSet();
+
+    enum Error {
+        OK,
+        ALLOCATION_FAILURE,
+        MALFORMED_DATA,
+    };
+
+    Error is_valid() const { return error_; }
+
+    /**
+     * Returns the size of the set.
+     */
+    size_t size() const { return elems_size_; }
+
+    /**
+     * Returns true if the set is empty.
+     */
+    bool empty() const { return size() == 0; }
+
+    /**
+     * Returns the total size of all indirect data referenced by set elements.
+     */
+    size_t indirect_size() const { return indirect_data_size_; }
+
+    /**
+     * Returns the data in the set, directly. Be careful with this.
+     */
+    const keymaster_key_param_t* data() const { return elems_; }
+
+    /**
+     * Sorts the set
+     */
+    void Sort();
+
+    /**
+     * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the
+     * AuthorizationSetBuilder).
+     */
+    void Deduplicate();
+
+    /**
+     * Returns the data in a keymaster_key_param_set_t, suitable for returning to C code.  For C
+     * compatibility, the contents are malloced, not new'ed, and so must be freed with free(), or
+     * better yet with keymaster_free_param_set, not delete.  The caller takes ownership.
+     */
+    void CopyToParamSet(keymaster_key_param_set_t* set) const;
+
+    /**
+     * Returns the offset of the next entry that matches \p tag, starting from the element after \p
+     * begin.  If not found, returns -1.
+     */
+    int find(keymaster_tag_t tag, int begin = -1) const;
+
+    /**
+     * Removes the entry at the specified index. Returns true if successful, false if the index was
+     * out of bounds.
+     */
+    bool erase(size_t index);
+
+    /**
+     * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration
+     */
+    const keymaster_key_param_t* begin() const { return elems_; }
+
+    /**
+     * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration
+     */
+    const keymaster_key_param_t* end() const { return elems_ + elems_size_; }
+
+    /**
+     * Returns the nth element of the set.
+     */
+    keymaster_key_param_t& operator[](int n);
+
+    /**
+     * Returns the nth element of the set.
+     */
+    keymaster_key_param_t operator[](int n) const;
+
+    /**
+     * Returns the number of \p tag entries.
+     */
+    size_t GetTagCount(keymaster_tag_t tag) const;
+
+    /**
+     * Returns true if the set contains the specified tag and value.
+     */
+    template <keymaster_tag_t Tag, typename T>
+    bool Contains(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T val) const {
+        return ContainsEnumValue(tag, val);
+    }
+
+    /**
+     * Returns true if the set contains the specified tag and value.
+     */
+    template <keymaster_tag_t Tag, typename T>
+    bool Contains(TypedEnumTag<KM_ENUM, Tag, T> tag, T val) const {
+        return ContainsEnumValue(tag, val);
+    }
+
+    /**
+     * If the specified integer-typed \p tag exists, places its value in \p val and returns true.
+     * If \p tag is not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t T>
+    inline bool GetTagValue(TypedTag<KM_UINT, T> tag, uint32_t* val) const {
+        return GetTagValueInt(tag, val);
+    }
+
+    /**
+     * If the specified instance of the specified integer-typed \p tag exists, places its value
+     * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
+     * false.
+     */
+    template <keymaster_tag_t Tag>
+    bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance, uint32_t* val) const {
+        return GetTagValueIntRep(tag, instance, val);
+    }
+
+    /**
+     * If the specified long-typed \p tag exists, places its value in \p val and returns true.
+     * If \p tag is not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t T>
+    inline bool GetTagValue(TypedTag<KM_ULONG, T> tag, uint64_t* val) const {
+        return GetTagValueLong(tag, val);
+    }
+
+    /**
+     * If the specified instance of the specified integer-typed \p tag exists, places its value
+     * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
+     * false.
+     */
+    template <keymaster_tag_t Tag>
+    bool GetTagValue(TypedTag<KM_ULONG_REP, Tag> tag, size_t instance, uint64_t* val) const {
+        return GetTagValueLongRep(tag, instance, val);
+    }
+
+    /**
+     * If the specified enumeration-typed \p tag exists, places its value in \p val and returns
+     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t Tag, typename T>
+    bool GetTagValue(TypedEnumTag<KM_ENUM, Tag, T> tag, T* val) const {
+        return GetTagValueEnum(tag, reinterpret_cast<uint32_t*>(val));
+    }
+
+    /**
+     * If the specified instance of the specified enumeration-typed \p tag exists, places its value
+     * in \p val and returns true.  If \p tag is not present, leaves \p val unmodified and returns
+     * false.
+     */
+    template <keymaster_tag_t Tag, typename T>
+    bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, size_t instance, T* val) const {
+        return GetTagValueEnumRep(tag, instance, reinterpret_cast<uint32_t*>(val));
+    }
+
+    /**
+     * If exactly one instance of the specified enumeration-typed \p tag exists, places its value in
+     * \p val and returns true.  If \p tag is not present or if multiple copies are present, leaves
+     * \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t Tag, typename T>
+    bool GetTagValue(TypedEnumTag<KM_ENUM_REP, Tag, T> tag, T* val) const {
+        if (GetTagCount(tag) != 1)
+            return false;
+        return GetTagValueEnumRep(tag, 0, reinterpret_cast<uint32_t*>(val));
+    }
+
+    /**
+     * If the specified date-typed \p tag exists, places its value in \p val and returns
+     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t Tag>
+    bool GetTagValue(TypedTag<KM_UINT_REP, Tag> tag, size_t instance,
+                     typename TypedTag<KM_UINT_REP, Tag>::value_type* val) const {
+        return GetTagValueIntRep(tag, instance, val);
+    }
+
+    /**
+     * If the specified bytes-typed \p tag exists, places its value in \p val and returns
+     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t Tag>
+    bool GetTagValue(TypedTag<KM_BYTES, Tag> tag, keymaster_blob_t* val) const {
+        return GetTagValueBlob(tag, val);
+    }
+
+    /**
+     * If the specified bignum-typed \p tag exists, places its value in \p val and returns
+     * true.  If \p tag is not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t Tag>
+    bool GetTagValue(TypedTag<KM_BIGNUM, Tag> tag, keymaster_blob_t* val) const {
+        return GetTagValueBlob(tag, val);
+    }
+
+    /**
+     * Returns true if the specified tag is present, and therefore has the value 'true'.
+     */
+    template <keymaster_tag_t Tag> bool GetTagValue(TypedTag<KM_BOOL, Tag> tag) const {
+        return GetTagValueBool(tag);
+    }
+
+    /**
+     * If the specified \p tag exists, places its value in \p val and returns true.  If \p tag is
+     * not present, leaves \p val unmodified and returns false.
+     */
+    template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
+    bool GetTagValue(TypedTag<Type, Tag> tag, typename TagValueType<Type>::value_type* val) const {
+        return GetTagValueLong(tag, val);
+    }
+
+    bool push_back(keymaster_key_param_t elem);
+
+    /**
+     * Grow the elements array to ensure it can contain \p count entries.  Preserves any existing
+     * entries.
+     */
+    bool reserve_elems(size_t count);
+
+    /**
+     * Grow the indirect data array to ensure it can contain \p length bytes.  Preserves any
+     * existing indirect data.
+     */
+    bool reserve_indirect(size_t length);
+
+    bool push_back(const keymaster_key_param_set_t& set);
+
+    /**
+     * Append the tag and enumerated value to the set.
+     */
+    template <keymaster_tag_t Tag, keymaster_tag_type_t Type, typename KeymasterEnum>
+    bool push_back(TypedEnumTag<Type, Tag, KeymasterEnum> tag, KeymasterEnum val) {
+        return push_back(Authorization(tag, val));
+    }
+
+    /**
+     * Append the boolean tag (value "true") to the set.
+     */
+    template <keymaster_tag_t Tag> bool push_back(TypedTag<KM_BOOL, Tag> tag) {
+        return push_back(Authorization(tag));
+    }
+
+    /**
+     * Append the tag and byte array to the set.  Copies the array into internal storage; does not
+     * take ownership of the passed-in array.
+     */
+    template <keymaster_tag_t Tag>
+    bool push_back(TypedTag<KM_BYTES, Tag> tag, const void* bytes, size_t bytes_len) {
+        return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
+    }
+
+    /**
+     * Append the tag and blob to the set.  Copies the blob contents into internal storage; does not
+     * take ownership of the blob's data.
+     */
+    template <keymaster_tag_t Tag>
+    bool push_back(TypedTag<KM_BYTES, Tag> tag, const keymaster_blob_t& blob) {
+        return push_back(tag, blob.data, blob.data_length);
+    }
+
+    /**
+     * Append the tag and bignum array to the set.  Copies the array into internal storage; does not
+     * take ownership of the passed-in array.
+     */
+    template <keymaster_tag_t Tag>
+    bool push_back(TypedTag<KM_BIGNUM, Tag> tag, const void* bytes, size_t bytes_len) {
+        return push_back(keymaster_param_blob(tag, static_cast<const uint8_t*>(bytes), bytes_len));
+    }
+
+    template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
+    bool push_back(TypedTag<Type, Tag> tag, typename TypedTag<Type, Tag>::value_type val) {
+        return push_back(Authorization(tag, val));
+    }
+
+    template <keymaster_tag_t Tag, keymaster_tag_type_t Type>
+    bool push_back(TypedTag<Type, Tag> tag, const void* bytes, size_t bytes_len) {
+        return push_back(Authorization(tag, bytes, bytes_len));
+    }
+
+    /* Virtual methods from Serializable */
+    size_t SerializedSize() const;
+    uint8_t* Serialize(uint8_t* serialized_set, const uint8_t* end) const;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);
+
+    size_t SerializedSizeOfElements() const;
+
+  private:
+    // Disallow assignment
+    void operator=(const AuthorizationSet&);
+
+    void FreeData();
+    void set_invalid(Error err);
+
+    static size_t ComputeIndirectDataSize(const keymaster_key_param_t* elems, size_t count);
+    void CopyIndirectData();
+    bool CheckIndirectData();
+
+    bool DeserializeIndirectData(const uint8_t** buf_ptr, const uint8_t* end);
+    bool DeserializeElementsData(const uint8_t** buf_ptr, const uint8_t* end);
+
+    bool GetTagValueEnum(keymaster_tag_t tag, uint32_t* val) const;
+    bool GetTagValueEnumRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
+    bool GetTagValueInt(keymaster_tag_t tag, uint32_t* val) const;
+    bool GetTagValueIntRep(keymaster_tag_t tag, size_t instance, uint32_t* val) const;
+    bool GetTagValueLong(keymaster_tag_t tag, uint64_t* val) const;
+    bool GetTagValueLongRep(keymaster_tag_t tag, size_t instance, uint64_t* val) const;
+    bool GetTagValueDate(keymaster_tag_t tag, uint64_t* val) const;
+    bool GetTagValueBlob(keymaster_tag_t tag, keymaster_blob_t* val) const;
+    bool GetTagValueBool(keymaster_tag_t tag) const;
+
+    bool ContainsEnumValue(keymaster_tag_t tag, uint32_t val) const;
+
+    // Define elems_ and elems_size_ as aliases to params and length, respectivley.  This is to
+    // avoid using the variables without the trailing underscore in the implementation.
+    keymaster_key_param_t*& elems_ = keymaster_key_param_set_t::params;
+    size_t& elems_size_ = keymaster_key_param_set_t::length;
+
+    size_t elems_capacity_;
+    uint8_t* indirect_data_;
+    size_t indirect_data_size_;
+    size_t indirect_data_capacity_;
+    Error error_;
+};
+
+class AuthorizationSetBuilder {
+  public:
+    template <typename TagType, typename ValueType>
+    AuthorizationSetBuilder& Authorization(TagType tag, ValueType value) {
+        set.push_back(tag, value);
+        return *this;
+    }
+
+    template <keymaster_tag_t Tag>
+    AuthorizationSetBuilder& Authorization(TypedTag<KM_BOOL, Tag> tag) {
+        set.push_back(tag);
+        return *this;
+    }
+
+    template <keymaster_tag_t Tag>
+    AuthorizationSetBuilder& Authorization(TypedTag<KM_INVALID, Tag> tag) {
+        keymaster_key_param_t param;
+        param.tag = tag;
+        set.push_back(param);
+        return *this;
+    }
+
+    template <keymaster_tag_t Tag>
+    AuthorizationSetBuilder& Authorization(TypedTag<KM_BYTES, Tag> tag, const uint8_t* data,
+                                           size_t data_length) {
+        set.push_back(tag, data, data_length);
+        return *this;
+    }
+
+    template <keymaster_tag_t Tag>
+    AuthorizationSetBuilder& Authorization(TypedTag<KM_BYTES, Tag> tag, const char* data,
+                                           size_t data_length) {
+        return Authorization(tag, reinterpret_cast<const uint8_t*>(data), data_length);
+    }
+
+    AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
+    AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
+    AuthorizationSetBuilder& AesKey(uint32_t key_size);
+    AuthorizationSetBuilder& HmacKey(uint32_t key_size);
+
+    AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
+    AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
+    AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
+    AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
+
+    AuthorizationSetBuilder& SigningKey();
+    AuthorizationSetBuilder& EncryptionKey();
+    AuthorizationSetBuilder& NoDigestOrPadding();
+    AuthorizationSetBuilder& EcbMode();
+
+    AuthorizationSetBuilder& Digest(keymaster_digest_t digest) {
+        return Authorization(TAG_DIGEST, digest);
+    }
+
+    AuthorizationSetBuilder& Padding(keymaster_padding_t padding) {
+        return Authorization(TAG_PADDING, padding);
+    }
+
+    AuthorizationSetBuilder& Deduplicate() {
+        set.Deduplicate();
+        return *this;
+    }
+
+    AuthorizationSet build() const { return set; }
+
+  private:
+    friend AuthorizationSet;
+    AuthorizationSet set;
+};
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
+                                                                uint64_t public_exponent) {
+    Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+    Authorization(TAG_KEY_SIZE, key_size);
+    Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
+    return *this;
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
+    Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC);
+    Authorization(TAG_KEY_SIZE, key_size);
+    return *this;
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
+    Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES);
+    return Authorization(TAG_KEY_SIZE, key_size);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
+    Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
+    Authorization(TAG_KEY_SIZE, key_size);
+    return SigningKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
+                                                                       uint64_t public_exponent) {
+    RsaKey(key_size, public_exponent);
+    return SigningKey();
+}
+
+inline AuthorizationSetBuilder&
+AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
+    RsaKey(key_size, public_exponent);
+    return EncryptionKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
+    EcdsaKey(key_size);
+    return SigningKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
+    AesKey(key_size);
+    return EncryptionKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
+    Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN);
+    return Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
+    Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
+    return Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
+    Authorization(TAG_DIGEST, KM_DIGEST_NONE);
+    return Authorization(TAG_PADDING, KM_PAD_NONE);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
+    return Authorization(TAG_BLOCK_MODE, KM_MODE_ECB);
+}
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEY_AUTHORIZATION_SET_H_
diff --git a/keymaster/include/keymaster/ec_key_factory.h b/keymaster/include/keymaster/ec_key_factory.h
new file mode 100644
index 0000000..aaeb548
--- /dev/null
+++ b/keymaster/include/keymaster/ec_key_factory.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_EC_KEY_FACTORY_H_
+#define SYSTEM_KEYMASTER_EC_KEY_FACTORY_H_
+
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+
+#include <keymaster/asymmetric_key_factory.h>
+
+namespace keymaster {
+
+class EcKeyFactory : public AsymmetricKeyFactory {
+  public:
+    explicit EcKeyFactory(const KeymasterContext* context) : AsymmetricKeyFactory(context) {}
+
+    keymaster_algorithm_t keymaster_key_type() const override { return KM_ALGORITHM_EC; }
+    int evp_key_type() const override { return EVP_PKEY_EC; }
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t CreateEmptyKey(const AuthorizationSet& hw_enforced,
+                                     const AuthorizationSet& sw_enforced,
+                                     UniquePtr<AsymmetricKey>* key) const override;
+
+    keymaster_error_t UpdateImportKeyDescription(const AuthorizationSet& key_description,
+                                                 keymaster_key_format_t key_format,
+                                                 const KeymasterKeyBlob& key_material,
+                                                 AuthorizationSet* updated_description,
+                                                 uint32_t* key_size) const;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+    static EC_GROUP* choose_group(size_t key_size_bits);
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_EC_KEY_FACTORY_H_
diff --git a/keymaster/include/keymaster/key_factory.h b/keymaster/include/keymaster/key_factory.h
new file mode 100644
index 0000000..18f69c4
--- /dev/null
+++ b/keymaster/include/keymaster/key_factory.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEY_FACTORY_H_
+#define SYSTEM_KEYMASTER_KEY_FACTORY_H_
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/authorization_set.h>
+
+namespace keymaster {
+
+class Key;
+class KeymasterContext;
+class OperationFactory;
+struct KeymasterKeyBlob;
+
+/**
+ * KeyFactory is a abstraction that encapsulats the knowledge of how to build and parse a specifiec
+ * subclass of Key.
+ */
+class KeyFactory {
+  public:
+    explicit KeyFactory(const KeymasterContext* context) : context_(context) {}
+    virtual ~KeyFactory() {}
+
+    // Factory methods.
+    virtual keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                          KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                          AuthorizationSet* sw_enforced) const = 0;
+
+    virtual keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                        keymaster_key_format_t input_key_material_format,
+                                        const KeymasterKeyBlob& input_key_material,
+                                        KeymasterKeyBlob* output_key_blob,
+                                        AuthorizationSet* hw_enforced,
+                                        AuthorizationSet* sw_enforced) const = 0;
+
+    virtual keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                                      const AuthorizationSet& additional_params,
+                                      const AuthorizationSet& hw_enforced,
+                                      const AuthorizationSet& sw_enforced,
+                                      UniquePtr<Key>* key) const = 0;
+
+    virtual OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const = 0;
+
+    // Informational methods.
+    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const = 0;
+    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const = 0;
+
+  protected:
+    const KeymasterContext* context_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEY_FACTORY_H_
diff --git a/keymaster/include/keymaster/keymaster_context.h b/keymaster/include/keymaster/keymaster_context.h
new file mode 100644
index 0000000..c9802e4
--- /dev/null
+++ b/keymaster/include/keymaster/keymaster_context.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_
+#define SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_
+
+#include <assert.h>
+
+#include <openssl/evp.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/keymaster_enforcement.h>
+
+namespace keymaster {
+
+class AuthorizationSet;
+class KeyFactory;
+class OperationFactory;
+struct KeymasterKeyBlob;
+
+/**
+ * KeymasterContext provides a singleton abstract interface that encapsulates various
+ * environment-dependent elements of AndroidKeymaster.
+ *
+ * AndroidKeymaster runs in multiple contexts.  Primarily:
+ *
+ * - In a trusted execution environment (TEE) as a "secure hardware" implementation.  In this
+ *   context keys are wrapped with an master key that never leaves the TEE, TEE-specific routines
+ *   are used for random number generation, all AndroidKeymaster-enforced authorizations are
+ *   considered hardware-enforced, and there's a bootloader-provided root of trust.
+ *
+ * - In the non-secure world as a software-only implementation.  In this context keys are not
+ *   encrypted (though they are integrity-checked) because there is no place to securely store a
+ *   key, OpenSSL is used for random number generation, no AndroidKeymaster-enforced authorizations
+ *   are considered hardware enforced and the root of trust is a static string.
+ *
+ * - In the non-secure world as a hybrid implementation fronting a less-capable hardware
+ *   implementation.  For example, a keymaster0 hardware implementation.  In this context keys are
+ *   not encrypted by AndroidKeymaster, but some may be opaque blobs provided by the backing
+ *   hardware, but blobs that lack the extended authorization lists of keymaster1.  In addition,
+ *   keymaster0 lacks many features of keymaster1, including modes of operation related to the
+ *   backing keymaster0 keys.  AndroidKeymaster must extend the blobs to add authorization lists,
+ *   and must provide the missing operation mode implementations in software, which means that
+ *   authorization lists are partially hardware-enforced (the bits that are enforced by the
+ *   underlying keymaster0) and partially software-enforced (the rest). OpenSSL is used for number
+ *   generation and the root of trust is a static string.
+ *
+ * More contexts are possible.
+ */
+class KeymasterContext {
+  public:
+    KeymasterContext() {}
+    virtual ~KeymasterContext(){};
+
+    virtual KeyFactory* GetKeyFactory(keymaster_algorithm_t algorithm) const = 0;
+    virtual OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
+                                                  keymaster_purpose_t purpose) const = 0;
+    virtual keymaster_algorithm_t* GetSupportedAlgorithms(size_t* algorithms_count) const = 0;
+
+    /**
+     * CreateKeyBlob takes authorization sets and key material and produces a key blob and hardware
+     * and software authorization lists ready to be returned to the AndroidKeymaster client
+     * (Keystore, generally).  The blob is integrity-checked and may be encrypted, depending on the
+     * needs of the context.
+    *
+     * This method is generally called only by KeyFactory subclassses.
+     */
+    virtual keymaster_error_t CreateKeyBlob(const AuthorizationSet& key_description,
+                                            keymaster_key_origin_t origin,
+                                            const KeymasterKeyBlob& key_material,
+                                            KeymasterKeyBlob* blob, AuthorizationSet* hw_enforced,
+                                            AuthorizationSet* sw_enforced) const = 0;
+
+    /**
+     * ParseKeyBlob takes a blob and extracts authorization sets and key material, returning an
+     * error if the blob fails integrity checking or decryption.  Note that the returned key
+     * material may itself be an opaque blob usable only by secure hardware (in the hybrid case).
+     *
+     * This method is called by AndroidKeymaster.
+     */
+    virtual keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob,
+                                           const AuthorizationSet& additional_params,
+                                           KeymasterKeyBlob* key_material,
+                                           AuthorizationSet* hw_enforced,
+                                           AuthorizationSet* sw_enforced) const = 0;
+
+    /**
+     * Take whatever environment-specific action is appropriate (if any) to delete the specified
+     * key.
+     */
+    virtual keymaster_error_t DeleteKey(const KeymasterKeyBlob& /* blob */) const {
+        return KM_ERROR_OK;
+    }
+
+    /**
+     * Take whatever environment-specific action is appropriate to delete all keys.
+     */
+    virtual keymaster_error_t DeleteAllKeys() const { return KM_ERROR_OK; }
+
+    /**
+     * Adds entropy to the Cryptographic Pseudo Random Number Generator used to generate key
+     * material, and other cryptographic protocol elements.  Note that if the underlying CPRNG
+     * tracks the size of its entropy pool, it should not assume that the provided data contributes
+     * any entropy, and it should also ensure that data provided through this interface cannot
+     * "poison" the CPRNG outputs, making them predictable.
+     */
+    virtual keymaster_error_t AddRngEntropy(const uint8_t* buf, size_t length) const = 0;
+
+    /**
+     * Generates \p length random bytes, placing them in \p buf.
+     */
+    virtual keymaster_error_t GenerateRandom(uint8_t* buf, size_t length) const = 0;
+
+    /**
+     * Return the enforcement policy for this context, or null if no enforcement should be done.
+     */
+    virtual KeymasterEnforcement* enforcement_policy() = 0;
+
+    /**
+     * Return the attestation signing key of the specified algorithm (KM_ALGORITHM_RSA or
+     * KM_ALGORITHM_EC).
+     */
+    virtual EVP_PKEY* AttestationKey(keymaster_algorithm_t algorithm,
+                                     keymaster_error_t* error) const = 0;
+
+    /**
+     * Return the certificate chain of the attestation signing key of the specified algorithm
+     * (KM_ALGORITHM_RSA or KM_ALGORITHM_EC).
+     */
+    virtual keymaster_cert_chain_t* AttestationChain(keymaster_algorithm_t algorithm,
+                                                     keymaster_error_t* error) const = 0;
+
+  private:
+    // Uncopyable.
+    KeymasterContext(const KeymasterContext&);
+    void operator=(const KeymasterContext&);
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_
diff --git a/keymaster/include/keymaster/keymaster_enforcement.h b/keymaster/include/keymaster/keymaster_enforcement.h
new file mode 100644
index 0000000..69ef5e3
--- /dev/null
+++ b/keymaster/include/keymaster/keymaster_enforcement.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
+#define ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
+
+#include <stdio.h>
+
+#include <keymaster/authorization_set.h>
+
+namespace keymaster {
+
+typedef uint64_t km_id_t;
+
+class KeymasterEnforcementContext {
+  public:
+    virtual ~KeymasterEnforcementContext() {}
+    /*
+     * Get current time.
+     */
+};
+
+class AccessTimeMap;
+class AccessCountMap;
+
+class KeymasterEnforcement {
+  public:
+    /**
+     * Construct a KeymasterEnforcement.
+     */
+    KeymasterEnforcement(uint32_t max_access_time_map_size, uint32_t max_access_count_map_size);
+    virtual ~KeymasterEnforcement();
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
+     */
+    keymaster_error_t AuthorizeOperation(const keymaster_purpose_t purpose, const km_id_t keyid,
+                                         const AuthorizationSet& auth_set,
+                                         const AuthorizationSet& operation_params,
+                                         keymaster_operation_handle_t op_handle,
+                                         bool is_begin_operation);
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params. Used for encrypt, decrypt sign, and verify.
+     */
+    keymaster_error_t AuthorizeBegin(const keymaster_purpose_t purpose, const km_id_t keyid,
+                                     const AuthorizationSet& auth_set,
+                                     const AuthorizationSet& operation_params);
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
+     */
+    keymaster_error_t AuthorizeUpdate(const AuthorizationSet& auth_set,
+                                      const AuthorizationSet& operation_params,
+                                      keymaster_operation_handle_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    }
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
+     */
+    keymaster_error_t AuthorizeFinish(const AuthorizationSet& auth_set,
+                                      const AuthorizationSet& operation_params,
+                                      keymaster_operation_handle_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    }
+
+    /**
+     * Creates a key ID for use in subsequent calls to AuthorizeOperation.  Clients needn't use this
+     * method of creating key IDs, as long as they use something consistent and unique.  This method
+     * hashes the key blob.
+     *
+     * Returns false if an error in the crypto library prevents creation of an ID.
+     */
+    static bool CreateKeyId(const keymaster_key_blob_t& key_blob, km_id_t* keyid);
+
+    //
+    // Methods that must be implemented by subclasses
+    //
+    // The time-related methods address the fact that different enforcement contexts may have
+    // different time-related capabilities.  In particular:
+    //
+    // - They may or may not be able to check dates against real-world clocks.
+    //
+    // - They may or may not be able to check timestampls against authentication trustlets (minters
+    //   of hw_auth_token_t structs).
+    //
+    // - They must have some time source for relative times, but may not be able to provide more
+    //   than reliability and monotonicity.
+
+    /*
+     * Returns true if the specified activation date has passed, or if activation cannot be
+     * enforced.
+     */
+    virtual bool activation_date_valid(uint64_t activation_date) const = 0;
+
+    /*
+     * Returns true if the specified expiration date has passed.  Returns false if it has not, or if
+     * expiration cannot be enforced.
+     */
+    virtual bool expiration_date_passed(uint64_t expiration_date) const = 0;
+
+    /*
+     * Returns true if the specified auth_token is older than the specified timeout.
+     */
+    virtual bool auth_token_timed_out(const hw_auth_token_t& token, uint32_t timeout) const = 0;
+
+    /*
+     * Get current time in seconds from some starting point.  This value is used to compute relative
+     * times between events.  It must be monotonically increasing, and must not skip or lag.  It
+     * need not have any relation to any external time standard (other than the duration of
+     * "second").
+     *
+     * On POSIX systems, it's recommented to use clock_gettime(CLOCK_MONOTONIC, ...) to implement
+     * this method.
+     */
+    virtual uint32_t get_current_time() const = 0;
+
+    /*
+     * Returns true if the specified auth_token has a valid signature, or if signature validation is
+     * not available.
+     */
+    virtual bool ValidateTokenSignature(const hw_auth_token_t& token) const = 0;
+
+  private:
+    keymaster_error_t AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
+                                              const AuthorizationSet& operation_params,
+                                              keymaster_operation_handle_t op_handle);
+
+    bool MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid);
+    bool MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses);
+    bool AuthTokenMatches(const AuthorizationSet& auth_set,
+                          const AuthorizationSet& operation_params, const uint64_t user_secure_id,
+                          const int auth_type_index, const int auth_timeout_index,
+                          const keymaster_operation_handle_t op_handle,
+                          bool is_begin_operation) const;
+
+    AccessTimeMap* access_time_map_;
+    AccessCountMap* access_count_map_;
+};
+
+}; /* namespace keymaster */
+
+#endif  // ANDROID_LIBRARY_KEYMASTER_ENFORCEMENT_H
diff --git a/keymaster/include/keymaster/keymaster_tags.h b/keymaster/include/keymaster/keymaster_tags.h
new file mode 100644
index 0000000..dcaf0da
--- /dev/null
+++ b/keymaster/include/keymaster/keymaster_tags.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEYMASTER_TAGS_H_
+#define SYSTEM_KEYMASTER_KEYMASTER_TAGS_H_
+
+/**
+ * This header contains various definitions that make working with keymaster tags safer and easier.
+ * It makes use of a fair amount of template metaprogramming, which is genarally a bad idea for
+ * maintainability, but in this case all of the metaprogramming serves the purpose of making it
+ * impossible to make certain classes of mistakes when operating on keymaster authorizations.  For
+ * example, it's an error to create a keymaster_param_t with tag == KM_TAG_PURPOSE and then to
+ * assign KM_ALGORITHM_RSA to the enumerated element of its union, but because "enumerated" is a
+ * uint32_t, there's no way for the compiler, ordinarily, to diagnose it.  Also, generic functions
+ * to manipulate authorizations of multiple types can't be written, because they need to know which
+ * union parameter to modify.
+ *
+ * The machinery in this header solves these problems.  The core elements are two templated classes,
+ * TypedTag and TypedEnumTag.  These classes are templated on a tag type and a tag value, and in the
+ * case of TypedEnumTag, an enumeration type as well.  Specializations are created for each
+ * keymaster tag, associating the tag type with the tag, and an instance of each specialization is
+ * created, and named the same as the keymaster tag, but with the KM_ prefix omitted.  Because the
+ * classes include a conversion operator to keymaster_tag_t, they can be used anywhere a
+ * keymaster_tag_t is expected.
+ *
+ * They also define a "value_type" typedef, which specifies the type of values associated with that
+ * particular tag.  This enables template functions to be written that check that the correct
+ * parameter type is used for a given tag, and that use the correct union entry for the tag type.  A
+ * very useful example is the overloaded "Authorization" function defined below, which takes tag and
+ * value arguments and correctly constructs a keyamster_param_t struct.
+ *
+ * Because the classes have no data members and all of their methods are inline, they have ZERO
+ * run-time cost in and of themselves.  The one way in which they can create code bloat is when
+ * template functions using them are expanded multiple times.  The standard method of creating
+ * trivial, inlined template functions which call non-templated functions which are compact but not
+ * type-safe, allows the program to have both the type-safety of the templates and the compactness
+ * of the non-templated functions, at the same time.
+ */
+
+#include <hardware/hw_auth_token.h>
+#include <hardware/keymaster_defs.h>
+
+namespace keymaster {
+
+// The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have.  We
+// need these old values to be able to support old keys that use them.
+static const keymaster_tag_t KM_TAG_DIGEST_OLD = static_cast<keymaster_tag_t>(KM_ENUM | 5);
+static const keymaster_tag_t KM_TAG_PADDING_OLD = static_cast<keymaster_tag_t>(KM_ENUM | 7);
+
+// Until we have C++11, fake std::static_assert.
+template <bool b> struct StaticAssert {};
+template <> struct StaticAssert<true> {
+    static void check() {}
+};
+
+// An unusable type that we can associate with tag types that don't have a simple value type.
+// That will prevent the associated type from being used inadvertently.
+class Void {
+    Void();
+    ~Void();
+};
+
+/**
+ * A template that defines the association between non-enumerated tag types and their value
+ * types.  For each tag type we define a specialized struct that contains a typedef "value_type".
+ */
+template <keymaster_tag_type_t tag_type> struct TagValueType {};
+template <> struct TagValueType<KM_ULONG> { typedef uint64_t value_type; };
+template <> struct TagValueType<KM_ULONG_REP> { typedef uint64_t value_type; };
+template <> struct TagValueType<KM_DATE> { typedef uint64_t value_type; };
+template <> struct TagValueType<KM_UINT> { typedef uint32_t value_type; };
+template <> struct TagValueType<KM_UINT_REP> { typedef uint32_t value_type; };
+template <> struct TagValueType<KM_INVALID> { typedef Void value_type; };
+template <> struct TagValueType<KM_BOOL> { typedef bool value_type; };
+template <> struct TagValueType<KM_BYTES> { typedef keymaster_blob_t value_type; };
+template <> struct TagValueType<KM_BIGNUM> { typedef keymaster_blob_t value_type; };
+
+/**
+ * TypedTag is a templatized version of keymaster_tag_t, which provides compile-time checking of
+ * keymaster tag types. Instances are convertible to keymaster_tag_t, so they can be used wherever
+ * keymaster_tag_t is expected, and because they encode the tag type it's possible to create
+ * function overloadings that only operate on tags with a particular type.
+ */
+template <keymaster_tag_type_t tag_type, keymaster_tag_t tag> class TypedTag {
+  public:
+    typedef typename TagValueType<tag_type>::value_type value_type;
+
+    inline TypedTag() {
+        // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type
+        // 'tag_type'.  Attempting to instantiate a tag with the wrong type will result in a compile
+        // error (no match for template specialization StaticAssert<false>), with no run-time cost.
+        StaticAssert<(tag & tag_type) == tag_type>::check();
+        StaticAssert<(tag_type != KM_ENUM) && (tag_type != KM_ENUM_REP)>::check();
+    }
+    inline operator keymaster_tag_t() { return tag; }
+    inline long masked_tag() { return static_cast<long>(keymaster_tag_mask_type(tag)); }
+};
+
+template <keymaster_tag_type_t tag_type, keymaster_tag_t tag, typename KeymasterEnum>
+class TypedEnumTag {
+  public:
+    typedef KeymasterEnum value_type;
+
+    inline TypedEnumTag() {
+        // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type
+        // 'tag_type'.  Attempting to instantiate a tag with the wrong type will result in a compile
+        // error (no match for template specialization StaticAssert<false>), with no run-time cost.
+        StaticAssert<(tag & tag_type) == tag_type>::check();
+        StaticAssert<(tag_type == KM_ENUM) || (tag_type == KM_ENUM_REP)>::check();
+    }
+    inline operator keymaster_tag_t() { return tag; }
+    inline long masked_tag() { return static_cast<long>(keymaster_tag_mask_type(tag)); }
+};
+
+#ifdef KEYMASTER_NAME_TAGS
+const char* StringifyTag(keymaster_tag_t tag);
+#endif
+
+// DECLARE_KEYMASTER_TAG is used to declare TypedTag instances for each non-enum keymaster tag.
+#define DECLARE_KEYMASTER_TAG(type, name) extern TypedTag<type, KM_##name> name
+
+DECLARE_KEYMASTER_TAG(KM_INVALID, TAG_INVALID);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_KEY_SIZE);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MAC_LENGTH);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_CALLER_NONCE);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MIN_MAC_LENGTH);
+DECLARE_KEYMASTER_TAG(KM_ULONG, TAG_RSA_PUBLIC_EXPONENT);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ECIES_SINGLE_HASH_MODE);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_INCLUDE_UNIQUE_ID);
+DECLARE_KEYMASTER_TAG(KM_DATE, TAG_ACTIVE_DATETIME);
+DECLARE_KEYMASTER_TAG(KM_DATE, TAG_ORIGINATION_EXPIRE_DATETIME);
+DECLARE_KEYMASTER_TAG(KM_DATE, TAG_USAGE_EXPIRE_DATETIME);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MIN_SECONDS_BETWEEN_OPS);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MAX_USES_PER_BOOT);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_USERS);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_USER_ID);
+DECLARE_KEYMASTER_TAG(KM_ULONG_REP, TAG_USER_SECURE_ID);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_NO_AUTH_REQUIRED);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_AUTH_TIMEOUT);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALLOW_WHILE_ON_BODY);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_APPLICATIONS);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_ID);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_DATA);
+DECLARE_KEYMASTER_TAG(KM_DATE, TAG_CREATION_DATETIME);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANT);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ROOT_OF_TRUST);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ASSOCIATED_DATA);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_NONCE);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_AUTH_TOKEN);
+DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_BOOTLOADER_ONLY);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_OS_VERSION);
+DECLARE_KEYMASTER_TAG(KM_UINT, TAG_OS_PATCHLEVEL);
+DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_UNIQUE_ID);
+
+// DECLARE_KEYMASTER_ENUM_TAG is used to declare TypedEnumTag instances for each enum keymaster tag.
+#define DECLARE_KEYMASTER_ENUM_TAG(type, name, enumtype)                                           \
+    extern TypedEnumTag<type, KM_##name, enumtype> name
+
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_PURPOSE, keymaster_purpose_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_ALGORITHM, keymaster_algorithm_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_BLOCK_MODE, keymaster_block_mode_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_DIGEST, keymaster_digest_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_DIGEST_OLD, keymaster_digest_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_PADDING, keymaster_padding_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_PADDING_OLD, keymaster_padding_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_BLOB_USAGE_REQUIREMENTS,
+                           keymaster_key_blob_usage_requirements_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_ORIGIN, keymaster_key_origin_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_USER_AUTH_TYPE, hw_authenticator_type_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_KDF, keymaster_kdf_t);
+DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_EC_CURVE, keymaster_ec_curve_t);
+
+//
+// Overloaded function "Authorization" to create keymaster_key_param_t objects for all of tags.
+//
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_BOOL, Tag> tag) {
+    return keymaster_param_bool(tag);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_UINT, Tag> tag, uint32_t value) {
+    return keymaster_param_int(tag, value);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_UINT_REP, Tag> tag, uint32_t value) {
+    return keymaster_param_int(tag, value);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_ULONG, Tag> tag, uint64_t value) {
+    return keymaster_param_long(tag, value);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_ULONG_REP, Tag> tag, uint64_t value) {
+    return keymaster_param_long(tag, value);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_DATE, Tag> tag, uint64_t value) {
+    return keymaster_param_date(tag, value);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_BYTES, Tag> tag, const void* bytes,
+                                           size_t bytes_len) {
+    return keymaster_param_blob(tag, reinterpret_cast<const uint8_t*>(bytes), bytes_len);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_BYTES, Tag> tag,
+                                           const keymaster_blob_t& blob) {
+    return keymaster_param_blob(tag, blob.data, blob.data_length);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_BIGNUM, Tag> tag, const void* bytes,
+                                           size_t bytes_len) {
+    return keymaster_param_blob(tag, reinterpret_cast<const uint8_t*>(bytes), bytes_len);
+}
+
+template <keymaster_tag_t Tag>
+inline keymaster_key_param_t Authorization(TypedTag<KM_BIGNUM, Tag> tag,
+                                           const keymaster_blob_t& blob) {
+    return keymaster_param_blob(tag, blob.data, blob.data_length);
+}
+
+template <keymaster_tag_t Tag, typename KeymasterEnum>
+inline keymaster_key_param_t Authorization(TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
+                                           KeymasterEnum value) {
+    return keymaster_param_enum(tag, value);
+}
+
+template <keymaster_tag_t Tag, typename KeymasterEnum>
+inline keymaster_key_param_t Authorization(TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
+                                           KeymasterEnum value) {
+    return keymaster_param_enum(tag, value);
+}
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEYMASTER_TAGS_H_
diff --git a/keymaster/include/keymaster/logger.h b/keymaster/include/keymaster/logger.h
new file mode 100644
index 0000000..a4fdea3
--- /dev/null
+++ b/keymaster/include/keymaster/logger.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_LOGGER_H_
+#define SYSTEM_KEYMASTER_LOGGER_H_
+
+#include <stdarg.h>
+
+namespace keymaster {
+
+class Logger {
+  public:
+    Logger() {}
+    virtual ~Logger() {}
+
+    enum LogLevel {
+        DEBUG_LVL,    // Messages used only for debugging
+        INFO_LVL,     // Informational messages; something is unusual but not wrong
+        WARNING_LVL,  // There's an indication of trouble, but it may be okay.
+        ERROR_LVL,    // A problem has occurred, but processing can continue
+        SEVERE_LVL,   // A severe problem has occurred; likely indicates a defect.
+    };
+
+    virtual int log_msg(LogLevel level, const char* fmt, va_list args) const = 0;
+
+    static int Log(LogLevel level, const char* fmt, va_list args);
+    static int Log(LogLevel level, const char* fmt, ...);
+    static int Debug(const char* fmt, ...);
+    static int Info(const char* fmt, ...);
+    static int Warning(const char* fmt, ...);
+    static int Error(const char* fmt, ...);
+    static int Severe(const char* fmt, ...);
+
+  protected:
+    static void set_instance(Logger* logger) { instance_ = logger; }
+
+  private:
+    // Disallow copying.
+    Logger(const Logger&);
+    void operator=(const Logger&);
+
+    static Logger* instance_;
+};
+
+#define STR(x) #x
+#define STRINGIFY(x) STR(x)
+#define FILE_LINE __FILE__ ", Line " STRINGIFY(__LINE__) ": "
+
+#define LOG_D(fmt, ...) Logger::Debug(FILE_LINE fmt, __VA_ARGS__)
+#define LOG_I(fmt, ...) Logger::Info(FILE_LINE fmt, __VA_ARGS__)
+#define LOG_W(fmt, ...) Logger::Warning(FILE_LINE fmt, __VA_ARGS__)
+#define LOG_E(fmt, ...) Logger::Error(FILE_LINE fmt, __VA_ARGS__)
+#define LOG_S(fmt, ...) Logger::Severe(FILE_LINE fmt, __VA_ARGS__)
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_LOGGER_H_
diff --git a/keymaster/include/keymaster/rsa_key_factory.h b/keymaster/include/keymaster/rsa_key_factory.h
new file mode 100644
index 0000000..f651652
--- /dev/null
+++ b/keymaster/include/keymaster/rsa_key_factory.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_RSA_KEY_FACTORY_H_
+#define SYSTEM_KEYMASTER_RSA_KEY_FACTORY_H_
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
+#include <keymaster/asymmetric_key_factory.h>
+
+namespace keymaster {
+
+class RsaKeyFactory : public AsymmetricKeyFactory {
+  public:
+    explicit RsaKeyFactory(const KeymasterContext* context) : AsymmetricKeyFactory(context) {}
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t CreateEmptyKey(const AuthorizationSet& hw_enforced,
+                                     const AuthorizationSet& sw_enforced,
+                                     UniquePtr<AsymmetricKey>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+    keymaster_algorithm_t keymaster_key_type() const override { return KM_ALGORITHM_RSA; }
+    int evp_key_type() const override { return EVP_PKEY_RSA; }
+
+  protected:
+    keymaster_error_t UpdateImportKeyDescription(const AuthorizationSet& key_description,
+                                                 keymaster_key_format_t import_key_format,
+                                                 const KeymasterKeyBlob& import_key_material,
+                                                 AuthorizationSet* updated_description,
+                                                 uint64_t* public_exponent,
+                                                 uint32_t* key_size) const;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_RSA_KEY_FACTORY_H_
diff --git a/keymaster/include/keymaster/serializable.h b/keymaster/include/keymaster/serializable.h
new file mode 100644
index 0000000..8748c55
--- /dev/null
+++ b/keymaster/include/keymaster/serializable.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_SERIALIZABLE_H_
+#define SYSTEM_KEYMASTER_SERIALIZABLE_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cstddef>
+#include <new>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+class Serializable {
+  public:
+    Serializable() {}
+    virtual ~Serializable() {}
+
+    /**
+     * Return the size of the serialized representation of this object.
+     */
+    virtual size_t SerializedSize() const = 0;
+
+    /**
+     * Serialize this object into the provided buffer.  Returns a pointer to the byte after the last
+     * written.  Will not write past \p end, which should point to \p buf + size of the buffer
+     * (i.e. one past the end of the buffer).
+     */
+    virtual uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const = 0;
+
+    /**
+     * Deserialize from the provided buffer, copying the data into newly-allocated storage.  Returns
+     * true if successful, and advances *buf past the bytes read.
+     */
+    virtual bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) = 0;
+
+  private:
+    // Disallow copying and assignment.
+    Serializable(const Serializable&);
+    void operator=(const Serializable&);
+};
+
+/*
+ * Utility functions for writing Serialize() methods
+ */
+
+/**
+ * Append a byte array to a buffer.  Note that by itself this function isn't very useful, because it
+ * provides no indication in the serialized buffer of what the array size is.  For writing arrays,
+ * see \p append_size_and_data_to_buf().
+ *
+ * Returns a pointer to the first byte after the data written.
+ */
+uint8_t* append_to_buf(uint8_t* buf, const uint8_t* end, const void* data, size_t data_len);
+
+/**
+ * Append some type of value convertible to a uint32_t to a buffer.  This is primarily used for
+ * writing enumerated values, and uint32_ts.
+ *
+ * Returns a pointer to the first byte after the data written.
+ */
+template <typename T>
+inline uint8_t* append_uint32_to_buf(uint8_t* buf, const uint8_t* end, T value) {
+    uint32_t val = static_cast<uint32_t>(value);
+    return append_to_buf(buf, end, &val, sizeof(val));
+}
+
+/**
+ * Append a uint64_t to a buffer.  Returns a pointer to the first byte after the data written.
+ */
+inline uint8_t* append_uint64_to_buf(uint8_t* buf, const uint8_t* end, uint64_t value) {
+    return append_to_buf(buf, end, &value, sizeof(value));
+}
+
+/**
+ * Appends a byte array to a buffer, prefixing it with a 32-bit size field.  Returns a pointer to
+ * the first byte after the data written.
+ *
+ * See copy_size_and_data_from_buf().
+ */
+inline uint8_t* append_size_and_data_to_buf(uint8_t* buf, const uint8_t* end, const void* data,
+                                            size_t data_len) {
+    buf = append_uint32_to_buf(buf, end, data_len);
+    return append_to_buf(buf, end, data, data_len);
+}
+
+/**
+ * Appends an array of values that are convertible to uint32_t as uint32ts to a buffer, prefixing a
+ * count so deserialization knows how many values to read.
+ *
+ * See copy_uint32_array_from_buf().
+ */
+template <typename T>
+inline uint8_t* append_uint32_array_to_buf(uint8_t* buf, const uint8_t* end, const T* data,
+                                           size_t count) {
+    // Check for overflow
+    if (count >= (UINT32_MAX / sizeof(uint32_t)) || buf + count * sizeof(uint32_t) < buf)
+        return buf;
+    buf = append_uint32_to_buf(buf, end, count);
+    for (size_t i = 0; i < count; ++i)
+        buf = append_uint32_to_buf(buf, end, static_cast<uint32_t>(data[i]));
+    return buf;
+}
+
+/*
+ * Utility functions for writing Deserialize() methods.
+ */
+
+/**
+ * Copy \p size bytes from \p *buf_ptr into \p dest.  If there are fewer than \p size bytes to read,
+ * returns false.  Advances *buf_ptr to the next byte to be read.
+ */
+bool copy_from_buf(const uint8_t** buf_ptr, const uint8_t* end, void* dest, size_t size);
+
+/**
+ * Extracts a uint32_t size from *buf_ptr, placing it in \p *size, and then reads *size bytes from
+ * *buf_ptr, placing them in newly-allocated storage in *dest.  If there aren't enough bytes in
+ * *buf_ptr, returns false.  Advances \p *buf_ptr to the next byte to be read.
+ *
+ * See \p append_size_and_data_to_buf().
+ */
+bool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, size_t* size,
+                                 UniquePtr<uint8_t[]>* dest);
+
+/**
+ * Copies a value convertible from uint32_t from \p *buf_ptr.  Returns false if there are less than
+ * four bytes remaining in \p *buf_ptr.  Advances \p *buf_ptr to the next byte to be read.
+ */
+template <typename T>
+inline bool copy_uint32_from_buf(const uint8_t** buf_ptr, const uint8_t* end, T* value) {
+    uint32_t val;
+    if (!copy_from_buf(buf_ptr, end, &val, sizeof(val)))
+        return false;
+    *value = static_cast<T>(val);
+    return true;
+}
+
+/**
+ * Copies a uint64_t from \p *buf_ptr.  Returns false if there are less than eight bytes remaining
+ * in \p *buf_ptr.  Advances \p *buf_ptr to the next byte to be read.
+ */
+inline bool copy_uint64_from_buf(const uint8_t** buf_ptr, const uint8_t* end, uint64_t* value) {
+    return copy_from_buf(buf_ptr, end, value, sizeof(*value));
+}
+
+/**
+ * Copies an array of values convertible to uint32_t from \p *buf_ptr, first reading a count of
+ * values to read. The count is returned in \p *count and the values returned in newly-allocated
+ * storage at *data.  Returns false if there are insufficient bytes at \p *buf_ptr.  Advances \p
+ * *buf_ptr to the next byte to be read.
+ */
+template <typename T>
+inline bool copy_uint32_array_from_buf(const uint8_t** buf_ptr, const uint8_t* end,
+                                       UniquePtr<T[]>* data, size_t* count) {
+    if (!copy_uint32_from_buf(buf_ptr, end, count))
+        return false;
+
+    const uint8_t* array_end = *buf_ptr + *count * sizeof(uint32_t);
+    if (*count >= UINT32_MAX / sizeof(uint32_t) || array_end < *buf_ptr || array_end > end)
+        return false;
+
+    data->reset(new (std::nothrow) T[*count]);
+    if (!data->get())
+        return false;
+    for (size_t i = 0; i < *count; ++i)
+        if (!copy_uint32_from_buf(buf_ptr, end, &(*data)[i]))
+            return false;
+    return true;
+}
+
+/**
+ * A simple buffer that supports reading and writing.  Manages its own memory.
+ */
+class Buffer : public Serializable {
+  public:
+    Buffer() : buffer_(NULL), buffer_size_(0), read_position_(0), write_position_(0) {}
+    explicit Buffer(size_t size) : buffer_(NULL) { Reinitialize(size); }
+    Buffer(const void* buf, size_t size) : buffer_(NULL) { Reinitialize(buf, size); }
+
+    // Grow the buffer so that at least \p size bytes can be written.
+    bool reserve(size_t size);
+
+    bool Reinitialize(size_t size);
+    bool Reinitialize(const void* buf, size_t size);
+
+    // Reinitialize with a copy of the provided buffer's readable data.
+    bool Reinitialize(const Buffer& buffer) {
+        return Reinitialize(buffer.peek_read(), buffer.available_read());
+    }
+
+    const uint8_t* begin() const { return peek_read(); }
+    const uint8_t* end() const { return peek_read() + available_read(); }
+
+    void Clear();
+
+    size_t available_write() const;
+    size_t available_read() const;
+    size_t buffer_size() const { return buffer_size_; }
+
+    bool write(const uint8_t* src, size_t write_length);
+    bool read(uint8_t* dest, size_t read_length);
+    const uint8_t* peek_read() const { return buffer_.get() + read_position_; }
+    bool advance_read(int distance) {
+        if (static_cast<size_t>(read_position_ + distance) <= write_position_) {
+            read_position_ += distance;
+            return true;
+        }
+        return false;
+    }
+    uint8_t* peek_write() { return buffer_.get() + write_position_; }
+    bool advance_write(int distance) {
+        if (static_cast<size_t>(write_position_ + distance) <= buffer_size_) {
+            write_position_ += distance;
+            return true;
+        }
+        return false;
+    }
+
+    size_t SerializedSize() const;
+    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const;
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end);
+
+  private:
+    // Disallow copy construction and assignment.
+    void operator=(const Buffer& other);
+    Buffer(const Buffer&);
+
+    UniquePtr<uint8_t[]> buffer_;
+    size_t buffer_size_;
+    size_t read_position_;
+    size_t write_position_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_SERIALIZABLE_H_
diff --git a/keymaster/include/keymaster/soft_keymaster_context.h b/keymaster/include/keymaster/soft_keymaster_context.h
new file mode 100644
index 0000000..2091d6f
--- /dev/null
+++ b/keymaster/include/keymaster/soft_keymaster_context.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_SOFT_KEYMASTER_CONTEXT_H_
+#define SYSTEM_KEYMASTER_SOFT_KEYMASTER_CONTEXT_H_
+
+#include <memory>
+#include <string>
+
+#include <openssl/evp.h>
+
+#include <hardware/keymaster0.h>
+#include <hardware/keymaster1.h>
+#include <keymaster/keymaster_context.h>
+
+namespace keymaster {
+
+class SoftKeymasterKeyRegistrations;
+class Keymaster0Engine;
+class Keymaster1Engine;
+
+/**
+ * SoftKeymasterContext provides the context for a non-secure implementation of AndroidKeymaster.
+ */
+class SoftKeymasterContext : public KeymasterContext {
+  public:
+    explicit SoftKeymasterContext(const std::string& root_of_trust = "SW");
+    ~SoftKeymasterContext() override;
+
+    /**
+     * Use the specified HW keymaster0 device for the operations it supports.  Takes ownership of
+     * the specified device (will call keymaster0_device->common.close());
+     */
+    keymaster_error_t SetHardwareDevice(keymaster0_device_t* keymaster0_device);
+
+    /**
+     * Use the specified HW keymaster1 device for performing undigested RSA and EC operations after
+     * digesting has been done in software.  Takes ownership of the specified device (will call
+     * keymaster1_device->common.close());
+     */
+    keymaster_error_t SetHardwareDevice(keymaster1_device_t* keymaster1_device);
+
+    KeyFactory* GetKeyFactory(keymaster_algorithm_t algorithm) const override;
+    OperationFactory* GetOperationFactory(keymaster_algorithm_t algorithm,
+                                          keymaster_purpose_t purpose) const override;
+    keymaster_algorithm_t* GetSupportedAlgorithms(size_t* algorithms_count) const override;
+    keymaster_error_t CreateKeyBlob(const AuthorizationSet& auths, keymaster_key_origin_t origin,
+                                    const KeymasterKeyBlob& key_material, KeymasterKeyBlob* blob,
+                                    AuthorizationSet* hw_enforced,
+                                    AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob,
+                                   const AuthorizationSet& additional_params,
+                                   KeymasterKeyBlob* key_material, AuthorizationSet* hw_enforced,
+                                   AuthorizationSet* sw_enforced) const override;
+    keymaster_error_t DeleteKey(const KeymasterKeyBlob& blob) const override;
+    keymaster_error_t DeleteAllKeys() const override;
+    keymaster_error_t AddRngEntropy(const uint8_t* buf, size_t length) const override;
+    keymaster_error_t GenerateRandom(uint8_t* buf, size_t length) const override;
+
+    EVP_PKEY* AttestationKey(keymaster_algorithm_t algorithm,
+                             keymaster_error_t* error) const override;
+    keymaster_cert_chain_t* AttestationChain(keymaster_algorithm_t algorithm,
+                                             keymaster_error_t* error) const override;
+
+    KeymasterEnforcement* enforcement_policy() override {
+        // SoftKeymaster does no enforcement; it's all done by Keystore.
+        return nullptr;
+    }
+
+  private:
+    keymaster_error_t ParseOldSoftkeymasterBlob(const KeymasterKeyBlob& blob,
+                                                KeymasterKeyBlob* key_material,
+                                                AuthorizationSet* hw_enforced,
+                                                AuthorizationSet* sw_enforced) const;
+    keymaster_error_t ParseKeymaster1HwBlob(const KeymasterKeyBlob& blob,
+                                            const AuthorizationSet& additional_params,
+                                            KeymasterKeyBlob* key_material,
+                                            AuthorizationSet* hw_enforced,
+                                            AuthorizationSet* sw_enforced) const;
+    keymaster_error_t ParseKeymaster0HwBlob(const KeymasterKeyBlob& blob,
+                                            KeymasterKeyBlob* key_material,
+                                            AuthorizationSet* hw_enforced,
+                                            AuthorizationSet* sw_enforced) const;
+    keymaster_error_t FakeKeyAuthorizations(EVP_PKEY* pubkey, AuthorizationSet* hw_enforced,
+                                            AuthorizationSet* sw_enforced) const;
+    keymaster_error_t BuildHiddenAuthorizations(const AuthorizationSet& input_set,
+                                                AuthorizationSet* hidden) const;
+
+    std::unique_ptr<Keymaster0Engine> km0_engine_;
+    std::unique_ptr<Keymaster1Engine> km1_engine_;
+    std::unique_ptr<KeyFactory> rsa_factory_;
+    std::unique_ptr<KeyFactory> ec_factory_;
+    std::unique_ptr<KeyFactory> aes_factory_;
+    std::unique_ptr<KeyFactory> hmac_factory_;
+    keymaster1_device* km1_dev_;
+    const std::string root_of_trust_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_SOFT_KEYMASTER_CONTEXT_H_
diff --git a/keymaster/include/keymaster/soft_keymaster_device.h b/keymaster/include/keymaster/soft_keymaster_device.h
new file mode 100644
index 0000000..4a734f1
--- /dev/null
+++ b/keymaster/include/keymaster/soft_keymaster_device.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_SOFT_KEYMASTER_DEVICE_H_
+#define SYSTEM_KEYMASTER_SOFT_KEYMASTER_DEVICE_H_
+
+#include <cstdlib>
+#include <map>
+#include <vector>
+
+#include <hardware/keymaster0.h>
+#include <hardware/keymaster1.h>
+#include <hardware/keymaster2.h>
+
+#include <keymaster/android_keymaster.h>
+#include <keymaster/soft_keymaster_context.h>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+class AuthorizationSet;
+
+/**
+ * Keymaster1 device implementation.
+ *
+ * This is a hybrid software/hardware implementation which wraps a keymaster0_device_t, forwarding
+ * RSA operations to secure hardware and doing everything else in software.
+ *
+ * IMPORTANT MAINTAINER NOTE: Pointers to instances of this class must be castable to hw_device_t
+ * and keymaster_device. This means it must remain a standard layout class (no virtual functions and
+ * no data members which aren't standard layout), and device_ must be the first data member.
+ * Assertions in the constructor validate compliance with those constraints.
+ */
+class SoftKeymasterDevice {
+  public:
+    SoftKeymasterDevice();
+
+    // Public only for testing.
+    explicit SoftKeymasterDevice(SoftKeymasterContext* context);
+
+    /**
+     * Set SoftKeymasterDevice to wrap the speicified HW keymaster0 device.  Takes ownership of the
+     * specified device (will call keymaster0_device->common.close());
+     */
+    keymaster_error_t SetHardwareDevice(keymaster0_device_t* keymaster0_device);
+
+    /**
+     * Set SoftKeymasterDevice to wrap specified HW keymaster1 device.  Takes ownership of the
+     * specified device (will call keymaster1_device->common.close());
+     */
+    keymaster_error_t SetHardwareDevice(keymaster1_device_t* keymaster1_device);
+
+    /**
+     * Returns true if a keymaster1_device_t has been set as the hardware device, and if that
+     * hardware device should be used directly.
+     */
+    bool Keymaster1DeviceIsGood();
+
+    hw_device_t* hw_device();
+    keymaster1_device_t* keymaster_device();
+    keymaster2_device_t* keymaster2_device();
+
+    // Public only for testing
+    void GetVersion(const GetVersionRequest& req, GetVersionResponse* rsp) {
+        impl_->GetVersion(req, rsp);
+    }
+
+    typedef std::pair<keymaster_algorithm_t, keymaster_purpose_t> AlgPurposePair;
+    typedef std::map<AlgPurposePair, std::vector<keymaster_digest_t>> DigestMap;
+
+  private:
+    void initialize_device_struct(uint32_t flags);
+    bool FindUnsupportedDigest(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
+                               const AuthorizationSet& params,
+                               keymaster_digest_t* unsupported) const;
+    bool RequiresSoftwareDigesting(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
+                                   const AuthorizationSet& params) const;
+    bool KeyRequiresSoftwareDigesting(const AuthorizationSet& key_description) const;
+
+    static void StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm,
+                                         AuthorizationSet* auth_set);
+    static keymaster_error_t GetPkcs8KeyAlgorithm(const uint8_t* key, size_t key_length,
+                                                  keymaster_algorithm_t* algorithm);
+
+    static int close_device(hw_device_t* dev);
+
+    /*
+     * These static methods are the functions referenced through the function pointers in
+     * keymaster_device.
+     */
+
+    // Keymaster1 methods
+    static keymaster_error_t get_supported_algorithms(const keymaster1_device_t* dev,
+                                                      keymaster_algorithm_t** algorithms,
+                                                      size_t* algorithms_length);
+    static keymaster_error_t get_supported_block_modes(const keymaster1_device_t* dev,
+                                                       keymaster_algorithm_t algorithm,
+                                                       keymaster_purpose_t purpose,
+                                                       keymaster_block_mode_t** modes,
+                                                       size_t* modes_length);
+    static keymaster_error_t get_supported_padding_modes(const keymaster1_device_t* dev,
+                                                         keymaster_algorithm_t algorithm,
+                                                         keymaster_purpose_t purpose,
+                                                         keymaster_padding_t** modes,
+                                                         size_t* modes_length);
+    static keymaster_error_t get_supported_digests(const keymaster1_device_t* dev,
+                                                   keymaster_algorithm_t algorithm,
+                                                   keymaster_purpose_t purpose,
+                                                   keymaster_digest_t** digests,
+                                                   size_t* digests_length);
+    static keymaster_error_t get_supported_import_formats(const keymaster1_device_t* dev,
+                                                          keymaster_algorithm_t algorithm,
+                                                          keymaster_key_format_t** formats,
+                                                          size_t* formats_length);
+    static keymaster_error_t get_supported_export_formats(const keymaster1_device_t* dev,
+                                                          keymaster_algorithm_t algorithm,
+                                                          keymaster_key_format_t** formats,
+                                                          size_t* formats_length);
+    static keymaster_error_t add_rng_entropy(const keymaster1_device_t* dev, const uint8_t* data,
+                                             size_t data_length);
+    static keymaster_error_t generate_key(const keymaster1_device_t* dev,
+                                          const keymaster_key_param_set_t* params,
+                                          keymaster_key_blob_t* key_blob,
+                                          keymaster_key_characteristics_t** characteristics);
+    static keymaster_error_t get_key_characteristics(const keymaster1_device_t* dev,
+                                                     const keymaster_key_blob_t* key_blob,
+                                                     const keymaster_blob_t* client_id,
+                                                     const keymaster_blob_t* app_data,
+                                                     keymaster_key_characteristics_t** character);
+    static keymaster_error_t import_key(const keymaster1_device_t* dev,  //
+                                        const keymaster_key_param_set_t* params,
+                                        keymaster_key_format_t key_format,
+                                        const keymaster_blob_t* key_data,
+                                        keymaster_key_blob_t* key_blob,
+                                        keymaster_key_characteristics_t** characteristics);
+    static keymaster_error_t export_key(const keymaster1_device_t* dev,  //
+                                        keymaster_key_format_t export_format,
+                                        const keymaster_key_blob_t* key_to_export,
+                                        const keymaster_blob_t* client_id,
+                                        const keymaster_blob_t* app_data,
+                                        keymaster_blob_t* export_data);
+    static keymaster_error_t delete_key(const keymaster1_device_t* dev,
+                                        const keymaster_key_blob_t* key);
+    static keymaster_error_t delete_all_keys(const keymaster1_device_t* dev);
+    static keymaster_error_t begin(const keymaster1_device_t* dev, keymaster_purpose_t purpose,
+                                   const keymaster_key_blob_t* key,
+                                   const keymaster_key_param_set_t* in_params,
+                                   keymaster_key_param_set_t* out_params,
+                                   keymaster_operation_handle_t* operation_handle);
+    static keymaster_error_t update(const keymaster1_device_t* dev,  //
+                                    keymaster_operation_handle_t operation_handle,
+                                    const keymaster_key_param_set_t* in_params,
+                                    const keymaster_blob_t* input, size_t* input_consumed,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_blob_t* output);
+    static keymaster_error_t finish(const keymaster1_device_t* dev,  //
+                                    keymaster_operation_handle_t operation_handle,
+                                    const keymaster_key_param_set_t* in_params,
+                                    const keymaster_blob_t* signature,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_blob_t* output);
+    static keymaster_error_t abort(const keymaster1_device_t* dev,
+                                   keymaster_operation_handle_t operation_handle);
+
+    // Keymaster2 methods
+    static keymaster_error_t add_rng_entropy(const keymaster2_device_t* dev, const uint8_t* data,
+                                             size_t data_length);
+    static keymaster_error_t generate_key(const keymaster2_device_t* dev,
+                                          const keymaster_key_param_set_t* params,
+                                          keymaster_key_blob_t* key_blob,
+                                          keymaster_key_characteristics_t* characteristics);
+    static keymaster_error_t get_key_characteristics(const keymaster2_device_t* dev,
+                                                     const keymaster_key_blob_t* key_blob,
+                                                     const keymaster_blob_t* client_id,
+                                                     const keymaster_blob_t* app_data,
+                                                     keymaster_key_characteristics_t* character);
+    static keymaster_error_t import_key(const keymaster2_device_t* dev,  //
+                                        const keymaster_key_param_set_t* params,
+                                        keymaster_key_format_t key_format,
+                                        const keymaster_blob_t* key_data,
+                                        keymaster_key_blob_t* key_blob,
+                                        keymaster_key_characteristics_t* characteristics);
+    static keymaster_error_t export_key(const keymaster2_device_t* dev,  //
+                                        keymaster_key_format_t export_format,
+                                        const keymaster_key_blob_t* key_to_export,
+                                        const keymaster_blob_t* client_id,
+                                        const keymaster_blob_t* app_data,
+                                        keymaster_blob_t* export_data);
+    static keymaster_error_t attest_key(const keymaster2_device_t* dev,
+                                        const keymaster_key_blob_t* key_to_attest,
+                                        const keymaster_key_param_set_t* attest_params,
+                                        keymaster_cert_chain_t* cert_chain);
+    static keymaster_error_t delete_key(const keymaster2_device_t* dev,
+                                        const keymaster_key_blob_t* key);
+    static keymaster_error_t delete_all_keys(const keymaster2_device_t* dev);
+    static keymaster_error_t begin(const keymaster2_device_t* dev, keymaster_purpose_t purpose,
+                                   const keymaster_key_blob_t* key,
+                                   const keymaster_key_param_set_t* in_params,
+                                   keymaster_key_param_set_t* out_params,
+                                   keymaster_operation_handle_t* operation_handle);
+    static keymaster_error_t update(const keymaster2_device_t* dev,  //
+                                    keymaster_operation_handle_t operation_handle,
+                                    const keymaster_key_param_set_t* in_params,
+                                    const keymaster_blob_t* input, size_t* input_consumed,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_blob_t* output);
+    static keymaster_error_t finish(const keymaster2_device_t* dev,  //
+                                    keymaster_operation_handle_t operation_handle,
+                                    const keymaster_key_param_set_t* in_params,
+                                    const keymaster_blob_t* input,
+                                    const keymaster_blob_t* signature,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_blob_t* output);
+    static keymaster_error_t abort(const keymaster2_device_t* dev,
+                                   keymaster_operation_handle_t operation_handle);
+
+    keymaster1_device_t km1_device_;
+    keymaster2_device_t km2_device_;
+
+    keymaster0_device_t* wrapped_km0_device_;
+    keymaster1_device_t* wrapped_km1_device_;
+    DigestMap km1_device_digests_;
+    SoftKeymasterContext* context_;
+    UniquePtr<AndroidKeymaster> impl_;
+    std::string module_name_;
+    hw_module_t updated_module_;
+};
+
+}  // namespace keymaster
+
+#endif  // EXTERNAL_KEYMASTER_TRUSTY_KEYMASTER_DEVICE_H_
diff --git a/keymaster/include/keymaster/soft_keymaster_logger.h b/keymaster/include/keymaster/soft_keymaster_logger.h
new file mode 100644
index 0000000..3be83b8
--- /dev/null
+++ b/keymaster/include/keymaster/soft_keymaster_logger.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_SOFT_KEYMASTER_LOGGER_H_
+#define SYSTEM_KEYMASTER_SOFT_KEYMASTER_LOGGER_H_
+
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+class SoftKeymasterLogger : public Logger
+{
+public:
+    SoftKeymasterLogger() { set_instance(this); }
+
+    virtual int log_msg(LogLevel level, const char* fmt, va_list args) const;
+};
+
+} // namespace keymaster
+
+#endif // SYSTEM_KEYMASTER_SOFT_KEYMASTER_LOGGER_H_
diff --git a/keymaster/integrity_assured_key_blob.cpp b/keymaster/integrity_assured_key_blob.cpp
new file mode 100644
index 0000000..5c317a3
--- /dev/null
+++ b/keymaster/integrity_assured_key_blob.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright 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.
+ */
+
+#include "integrity_assured_key_blob.h"
+
+#include <assert.h>
+
+#include <new>
+
+#include <openssl/hmac.h>
+#include <openssl/mem.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+
+#include "openssl_err.h"
+
+namespace keymaster {
+
+static const uint8_t BLOB_VERSION = 0;
+static const size_t HMAC_SIZE = 8;
+static const char HMAC_KEY[] = "IntegrityAssuredBlob0";
+
+inline size_t min(size_t a, size_t b) {
+    if (a < b)
+        return a;
+    return b;
+}
+
+class HmacCleanup {
+  public:
+    explicit HmacCleanup(HMAC_CTX* ctx) : ctx_(ctx) {}
+    ~HmacCleanup() { HMAC_CTX_cleanup(ctx_); }
+
+  private:
+    HMAC_CTX* ctx_;
+};
+
+static keymaster_error_t ComputeHmac(const uint8_t* serialized_data, size_t serialized_data_size,
+                                     const AuthorizationSet& hidden, uint8_t hmac[HMAC_SIZE]) {
+    size_t hidden_bytes_size = hidden.SerializedSize();
+    UniquePtr<uint8_t[]> hidden_bytes(new (std::nothrow) uint8_t[hidden_bytes_size]);
+    if (!hidden_bytes.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    hidden.Serialize(hidden_bytes.get(), hidden_bytes.get() + hidden_bytes_size);
+
+    HMAC_CTX ctx;
+    HMAC_CTX_init(&ctx);
+    const EVP_MD* md = EVP_sha256();
+    if (!HMAC_Init_ex(&ctx, HMAC_KEY, sizeof(HMAC_KEY), md, NULL /* engine */))
+        return TranslateLastOpenSslError();
+    HmacCleanup cleanup(&ctx);
+
+    uint8_t tmp[EVP_MAX_MD_SIZE];
+    unsigned tmp_len;
+    if (!HMAC_Update(&ctx, serialized_data, serialized_data_size) ||
+        !HMAC_Update(&ctx, hidden_bytes.get(), hidden_bytes_size) ||  //
+        !HMAC_Final(&ctx, tmp, &tmp_len))
+        return TranslateLastOpenSslError();
+
+    assert(tmp_len >= HMAC_SIZE);
+    memcpy(hmac, tmp, min(HMAC_SIZE, tmp_len));
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SerializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_material,
+                                                const AuthorizationSet& hidden,
+                                                const AuthorizationSet& hw_enforced,
+                                                const AuthorizationSet& sw_enforced,
+                                                KeymasterKeyBlob* key_blob) {
+    size_t size = 1 /* version */ +                //
+                  key_material.SerializedSize() +  //
+                  hw_enforced.SerializedSize() +   //
+                  sw_enforced.SerializedSize() +   //
+                  HMAC_SIZE;
+
+    if (!key_blob->Reset(size))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    uint8_t* p = key_blob->writable_data();
+    *p++ = BLOB_VERSION;
+    p = key_material.Serialize(p, key_blob->end());
+    p = hw_enforced.Serialize(p, key_blob->end());
+    p = sw_enforced.Serialize(p, key_blob->end());
+
+    return ComputeHmac(key_blob->key_material, p - key_blob->key_material, hidden, p);
+}
+
+keymaster_error_t DeserializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_blob,
+                                                  const AuthorizationSet& hidden,
+                                                  KeymasterKeyBlob* key_material,
+                                                  AuthorizationSet* hw_enforced,
+                                                  AuthorizationSet* sw_enforced) {
+    const uint8_t* p = key_blob.begin();
+    const uint8_t* end = key_blob.end();
+
+    if (p > end || p + HMAC_SIZE > end)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    uint8_t computed_hmac[HMAC_SIZE];
+    keymaster_error_t error = ComputeHmac(key_blob.begin(), key_blob.key_material_size - HMAC_SIZE,
+                                          hidden, computed_hmac);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (CRYPTO_memcmp(key_blob.end() - HMAC_SIZE, computed_hmac, HMAC_SIZE) != 0)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    return DeserializeIntegrityAssuredBlob_NoHmacCheck(key_blob, key_material, hw_enforced,
+                                                       sw_enforced);
+}
+
+keymaster_error_t DeserializeIntegrityAssuredBlob_NoHmacCheck(const KeymasterKeyBlob& key_blob,
+                                                              KeymasterKeyBlob* key_material,
+                                                              AuthorizationSet* hw_enforced,
+                                                              AuthorizationSet* sw_enforced) {
+    const uint8_t* p = key_blob.begin();
+    const uint8_t* end = key_blob.end() - HMAC_SIZE;
+
+    if (p > end)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    if (*p != BLOB_VERSION)
+        return KM_ERROR_INVALID_KEY_BLOB;
+    ++p;
+
+    if (!key_material->Deserialize(&p, end) ||  //
+        !hw_enforced->Deserialize(&p, end) ||   //
+        !sw_enforced->Deserialize(&p, end))
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster;
diff --git a/keymaster/integrity_assured_key_blob.h b/keymaster/integrity_assured_key_blob.h
new file mode 100644
index 0000000..6239a8a
--- /dev/null
+++ b/keymaster/integrity_assured_key_blob.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_INTEGRITY_ASSURED_KEY_BLOB_
+#define SYSTEM_KEYMASTER_INTEGRITY_ASSURED_KEY_BLOB_
+
+#include <hardware/keymaster_defs.h>
+
+namespace keymaster {
+
+class AuthorizationSet;
+class Buffer;
+struct KeymasterKeyBlob;
+
+keymaster_error_t SerializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_material,
+                                                const AuthorizationSet& hidden,
+                                                const AuthorizationSet& hw_enforced,
+                                                const AuthorizationSet& sw_enforced,
+                                                KeymasterKeyBlob* key_blob);
+
+keymaster_error_t DeserializeIntegrityAssuredBlob(const KeymasterKeyBlob& key_blob,
+                                                  const AuthorizationSet& hidden,
+                                                  KeymasterKeyBlob* key_material,
+                                                  AuthorizationSet* hw_enforced,
+                                                  AuthorizationSet* sw_enforced);
+
+keymaster_error_t DeserializeIntegrityAssuredBlob_NoHmacCheck(const KeymasterKeyBlob& key_blob,
+                                                              KeymasterKeyBlob* key_material,
+                                                              AuthorizationSet* hw_enforced,
+                                                              AuthorizationSet* sw_enforced);
+
+}  // namespace keymaster;
+
+#endif  // SYSTEM_KEYMASTER_INTEGRITY_ASSURED_KEY_BLOB_
diff --git a/keymaster/iso18033kdf.cpp b/keymaster/iso18033kdf.cpp
new file mode 100644
index 0000000..3de0fdf
--- /dev/null
+++ b/keymaster/iso18033kdf.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 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.
+ */
+
+#include "iso18033kdf.h"
+#include "openssl_utils.h"
+
+#include <algorithm>
+
+#include <openssl/evp.h>
+
+namespace keymaster {
+
+inline size_t min(size_t a, size_t b) {
+    return (a < b) ? a : b;
+}
+
+bool Iso18033Kdf::GenerateKey(const uint8_t* info, size_t info_len, uint8_t* output,
+                              size_t output_len) {
+    if (!is_initialized_ || output == nullptr)
+        return false;
+
+    /* Check whether output length is too long as specified in ISO/IEC 18033-2. */
+    if ((0xFFFFFFFFULL + start_counter_) * digest_size_ < (uint64_t)output_len)
+        return false;
+
+    EVP_MD_CTX ctx;
+    EvpMdCtxCleaner ctxCleaner(&ctx);
+    EVP_MD_CTX_init(&ctx);
+
+    size_t num_blocks = (output_len + digest_size_ - 1) / digest_size_;
+    UniquePtr<uint8_t[]> counter(new uint8_t[4]);
+    UniquePtr<uint8_t[]> digest_result(new uint8_t[digest_size_]);
+    if (counter.get() == nullptr || digest_result.get() == nullptr)
+        return false;
+    for (size_t block = 0; block < num_blocks; block++) {
+        switch (digest_type_) {
+        case KM_DIGEST_SHA1:
+            if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), nullptr /* default digest */))
+                return false;
+            break;
+        case KM_DIGEST_SHA_2_256:
+            if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), nullptr /* default digest */))
+                return false;
+            break;
+        default:
+            return false;
+        }
+
+        if (!EVP_DigestUpdate(&ctx, secret_key_.get(), secret_key_len_) ||
+            !Uint32ToBigEndianByteArray(block + start_counter_, counter.get()) ||
+            !EVP_DigestUpdate(&ctx, counter.get(), 4))
+            return false;
+
+        if (info != nullptr && info_len > 0) {
+            if (!EVP_DigestUpdate(&ctx, info, info_len))
+                return false;
+        }
+
+        /* OpenSSL does not accept size_t parameter. */
+        uint32_t uint32_digest_size_ = digest_size_;
+        if (!EVP_DigestFinal_ex(&ctx, digest_result.get(), &uint32_digest_size_) ||
+            uint32_digest_size_ != digest_size_)
+            return false;
+
+        size_t block_start = digest_size_ * block;
+        size_t block_length = min(digest_size_, output_len - block_start);
+        memcpy(output + block_start, digest_result.get(), block_length);
+    }
+    return true;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/iso18033kdf.h b/keymaster/iso18033kdf.h
new file mode 100644
index 0000000..40fd2d6
--- /dev/null
+++ b/keymaster/iso18033kdf.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_ISO18033KDF_H_
+#define SYSTEM_KEYMASTER_ISO18033KDF_H_
+
+#include "kdf.h"
+
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/serializable.h>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+/**
+ * A light implementation of ISO18033KDF as defined by ISO-18033-2 (www.shoup.net/iso/std6.pdf) and
+ * its slightly different variant ANSI-X9-42.
+ */
+class Iso18033Kdf : public Kdf {
+  public:
+    ~Iso18033Kdf() {}
+
+    bool Init(keymaster_digest_t digest_type, const uint8_t* secret, size_t secret_len) {
+        return Kdf::Init(digest_type, secret, secret_len, nullptr /* salt */, 0 /* salt_len */);
+    }
+
+    /**
+     * Generates ISO18033's derived key, as defined in ISO-18033-2 and ANSI-X9-42. In ISO 18033-2,
+     * KDF takes a secret and outputs:
+     *
+     * hash(secret || start_counter) || hash(secret|| start_counter + 1) || ...
+     *
+     * In ANSI-X9-42, KDF takes a secret and additional info, and outputs:
+     *
+     * hash(secret || start_counter || info) || hash(secret || start_counter + 1 || info) || ...
+     *
+     * Note that the KDFs are the same if the info field is considered optional.  In both cases the
+     * length of the output is specified by the caller, and the counter is encoded as a 4-element
+     * byte array.
+     */
+    bool GenerateKey(const uint8_t* info, size_t info_len, uint8_t* output,
+                     size_t output_len) override;
+
+  protected:
+    explicit Iso18033Kdf(uint32_t start_counter) : start_counter_(start_counter) {}
+
+  private:
+    uint32_t start_counter_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_ISO18033KDF_H_
diff --git a/keymaster/kdf.cpp b/keymaster/kdf.cpp
new file mode 100644
index 0000000..e196a0c
--- /dev/null
+++ b/keymaster/kdf.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright 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.
+ */
+
+#include "kdf.h"
+
+namespace keymaster {
+
+Kdf::Kdf() : is_initialized_(false) {}
+
+bool Kdf::Init(keymaster_digest_t digest_type, const uint8_t* secret, size_t secret_len,
+               const uint8_t* salt, size_t salt_len) {
+    is_initialized_ = false;
+
+    switch (digest_type) {
+    case KM_DIGEST_SHA1:
+        digest_size_ = 20;
+        digest_type_ = digest_type;
+        break;
+    case KM_DIGEST_SHA_2_256:
+        digest_size_ = 32;
+        digest_type_ = digest_type;
+        break;
+    default:
+        return false;
+    }
+
+    if (!secret || secret_len == 0)
+        return false;
+
+    secret_key_len_ = secret_len;
+    secret_key_.reset(dup_buffer(secret, secret_len));
+    if (!secret_key_.get())
+        return false;
+
+    salt_len_ = salt_len;
+    if (salt && salt_len > 0) {
+        salt_.reset(dup_buffer(salt, salt_len));
+        if (!salt_.get())
+            return false;
+    } else {
+        salt_.reset();
+    }
+
+    is_initialized_ = true;
+    return true;
+}
+
+bool Kdf::Uint32ToBigEndianByteArray(uint32_t number, uint8_t* output) {
+    if (!output)
+        return false;
+
+    output[0] = (number >> 24) & 0xff;
+    output[1] = (number >> 16) & 0xff;
+    output[2] = (number >> 8) & 0xff;
+    output[3] = (number)&0xff;
+    return true;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/kdf.h b/keymaster/kdf.h
new file mode 100644
index 0000000..b90d2bc
--- /dev/null
+++ b/keymaster/kdf.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KDF_H_
+#define SYSTEM_KEYMASTER_KDF_H_
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/serializable.h>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+/**
+ * A base class for wrapping different key derivation functions.
+ */
+class Kdf {
+  public:
+    virtual ~Kdf() { memset_s(secret_key_.get(), 0, secret_key_len_); };
+    Kdf();
+    bool Init(keymaster_digest_t digest_type, const uint8_t* secret, size_t secret_len,
+              const uint8_t* salt, size_t salt_len);
+    virtual bool GenerateKey(const uint8_t* info, size_t info_len, uint8_t* output,
+                             size_t output_len) = 0;
+
+  protected:
+    bool Uint32ToBigEndianByteArray(uint32_t number, uint8_t* output);
+    UniquePtr<uint8_t[]> secret_key_;
+    size_t secret_key_len_;
+    UniquePtr<uint8_t[]> salt_;
+    size_t salt_len_;
+    bool is_initialized_;
+    keymaster_digest_t digest_type_;
+    size_t digest_size_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KDF_H_
diff --git a/keymaster/kdf1.h b/keymaster/kdf1.h
new file mode 100644
index 0000000..fab1ef7
--- /dev/null
+++ b/keymaster/kdf1.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KDF1_H_
+#define SYSTEM_KEYMASTER_KDF1_H_
+
+#include "iso18033kdf.h"
+
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/serializable.h>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+/**
+ * Kdf1 is instance of Iso18033Kdf when the counter starts at 0.
+ */
+class Kdf1 : public Iso18033Kdf {
+  public:
+    Kdf1() : Iso18033Kdf(0) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KDF1_H_
diff --git a/keymaster/kdf1_test.cpp b/keymaster/kdf1_test.cpp
new file mode 100644
index 0000000..9c8b0d5
--- /dev/null
+++ b/keymaster/kdf1_test.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 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.
+ */
+
+#include "kdf1.h"
+#include <gtest/gtest.h>
+#include <string.h>
+
+#include "android_keymaster_test_utils.h"
+
+using std::string;
+
+namespace keymaster {
+
+namespace test {
+
+struct Kdf1Test {
+    const char* key_hex;
+    const char* expected_output_hex;
+    keymaster_digest_t digest_type;
+};
+
+static const Kdf1Test kKdf1Tests[] = {
+    {"032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778"
+     "e113b64e135cf4e2292c75efe5288edfda4",
+     "5f8de105b5e96b2e490ddecbd147dd1def7e3b8e0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d"
+     "800c46954840ff32052cdf0d640562bdfadfa263cfccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842"
+     "dbff8e13efee5b7e7e55bbe4d389647c686a9a9ab3fb889b2d7767d3837eea4e0a2f04",
+     KM_DIGEST_SHA1}};
+
+TEST(Kdf1Test, Kdf1) {
+    for (auto& test : kKdf1Tests) {
+        const string key = hex2str(test.key_hex);
+        const string expected_output = hex2str(test.expected_output_hex);
+        size_t output_len = expected_output.size();
+        uint8_t output[output_len];
+
+        Kdf1 kdf1;
+        ASSERT_TRUE(
+            kdf1.Init(test.digest_type, reinterpret_cast<const uint8_t*>(key.data()), key.size()));
+        ASSERT_TRUE(kdf1.GenerateKey(nullptr, 0, output, output_len));
+        EXPECT_EQ(0, memcmp(output, expected_output.data(), output_len));
+    }
+}
+
+}  // namespace test
+
+}  // namespace keymaster
diff --git a/keymaster/kdf2.h b/keymaster/kdf2.h
new file mode 100644
index 0000000..1df97ef
--- /dev/null
+++ b/keymaster/kdf2.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KDF2_H_
+#define SYSTEM_KEYMASTER_KDF2_H_
+
+#include "iso18033kdf.h"
+
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/serializable.h>
+
+#include <UniquePtr.h>
+
+namespace keymaster {
+
+/**
+ * Kdf2 is instance of Iso18033Kdf when the counter starts at 1.
+ */
+class Kdf2 : public Iso18033Kdf {
+  public:
+    Kdf2() : Iso18033Kdf(1) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KDF2_H_
diff --git a/keymaster/kdf2_test.cpp b/keymaster/kdf2_test.cpp
new file mode 100644
index 0000000..29ff40a
--- /dev/null
+++ b/keymaster/kdf2_test.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 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.
+ */
+
+#include "kdf2.h"
+#include <gtest/gtest.h>
+#include <string.h>
+
+#include "android_keymaster_test_utils.h"
+
+using std::string;
+
+namespace keymaster {
+
+namespace test {
+
+struct Kdf2Test {
+    const char* key_hex;
+    const char* info_hex;
+    const char* expected_output_hex;
+    keymaster_digest_t digest_type;
+};
+
+static const Kdf2Test kKdf2Tests[] = {
+    {"032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778"
+     "e113b64e135cf4e2292c75efe5288edfda4",
+     "",
+     "10a2403db42a8743cb989de86e668d168cbe6046e23ff26f741e87949a3bba1311ac179f819a3d18412e9eb45668f"
+     "2923c087c1299005f8d5fd42ca257bc93e8fee0c5a0d2a8aa70185401fbbd99379ec76c663e9a29d0b70f3fe261a5"
+     "9cdc24875a60b4aacb1319fa11c3365a8b79a44669f26fba933d012db213d7e3b16349",
+     KM_DIGEST_SHA_2_256},
+    {"032e45326fa859a72ec235acff929b15d1372e30b207255f0611b8f785d764374152e0ac009e509e7ba30cd2f1778"
+     "e113b64e135cf4e2292c75efe5288edfda4",
+     "",
+     "0e6a26eb7b956ccb8b3bdc1ca975bc57c3989e8fbad31a224655d800c46954840ff32052cdf0d640562bdfadfa263"
+     "cfccf3c52b29f2af4a1869959bc77f854cf15bd7a25192985a842dbff8e13efee5b7e7e55bbe4d389647c686a9a9a"
+     "b3fb889b2d7767d3837eea4e0a2f04b53ca8f50fb31225c1be2d0126c8c7a4753b0807",
+     KM_DIGEST_SHA1},
+    {"CA7C0F8C3FFA87A96E1B74AC8E6AF594347BB40A", "", "744AB703F5BC082E59185F6D049D2D367DB245C2",
+     KM_DIGEST_SHA1},
+    {"0499B502FC8B5BAFB0F4047E731D1F9FD8CD0D8881", "",
+     "03C62280C894E103C680B13CD4B4AE740A5EF0C72547292F82DC6B1777F47D63BA9D1EA73"
+     "2DBF386",
+     KM_DIGEST_SHA1},
+    {"5E10B967A95606853E528F04262AD18A4767C761163971391E17CB05A21668D4CE2B9F151617408042CE091958382"
+     "3FD346D1751FBE2341AF2EE0461B62F100FFAD4F723F70C18B38238ED183E9398C8CA517EE0CBBEFFF9C59471FE27"
+     "8093924089480DBC5A38E9A1A97D23038106847D0D22ECF85F49A861821199BAFCB0D74E6ACFFD7D142765EBF4C71"
+     "2414FE4B6AB957F4CB466B46601289BB82060428272842EE28F113CD11F39431CBFFD823254CE472E2105E49B3D7F"
+     "113B825076E6264585807BC46454665F27C5E4E1A4BD03470486322981FDC894CCA1E2930987C92C15A38BC42EB38"
+     "810E867C4432F07259EC00CDBBB0FB99E1727C706DA58DD",
+     "484D4143204B6579", "BC98EB018CB00EE26D1F97A15AE166912A7AC4C5", KM_DIGEST_SHA1},
+
+};
+
+TEST(Kdf2Test, Kdf2) {
+    for (auto& test : kKdf2Tests) {
+        const string key = hex2str(test.key_hex);
+        const string info = hex2str(test.info_hex);
+        const string expected_output = hex2str(test.expected_output_hex);
+        size_t output_len = expected_output.size();
+        uint8_t output[output_len];
+
+        Kdf2 kdf2;
+        ASSERT_TRUE(
+            kdf2.Init(test.digest_type, reinterpret_cast<const uint8_t*>(key.data()), key.size()));
+        ASSERT_TRUE(kdf2.GenerateKey(reinterpret_cast<const uint8_t*>(info.data()), info.size(),
+                                     output, output_len));
+        EXPECT_EQ(0, memcmp(output, expected_output.data(), output_len));
+    }
+}
+
+}  // namespace test
+
+}  // namespace keymaster
diff --git a/keymaster/kdf_test.cpp b/keymaster/kdf_test.cpp
new file mode 100644
index 0000000..f6f4a93
--- /dev/null
+++ b/keymaster/kdf_test.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 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.
+ */
+
+#include "kdf.h"
+#include <gtest/gtest.h>
+
+namespace keymaster {
+
+namespace test {
+
+class ForTestAbstractKdf : public Kdf {
+    bool GenerateKey(const uint8_t* /* info */, size_t /* info_len */, uint8_t* /* output */,
+                     size_t /* output_len */) {
+        return true;
+    }
+};
+
+TEST(KdfTest, Kdf) {
+    ForTestAbstractKdf kdf;
+    uint8_t key[128];
+    uint8_t salt[128];
+    ASSERT_TRUE(kdf.Init(KM_DIGEST_SHA1, key, 128, salt, 128));
+    ASSERT_TRUE(kdf.Init(KM_DIGEST_SHA_2_256, key, 128, salt, 128));
+    ASSERT_TRUE(kdf.Init(KM_DIGEST_SHA1, key, 128, nullptr, 0));
+    ASSERT_FALSE(kdf.Init(KM_DIGEST_MD5, key, 128, salt, 128));
+    ASSERT_FALSE(kdf.Init(KM_DIGEST_SHA1, nullptr, 0, salt, 128));
+    ASSERT_FALSE(kdf.Init(KM_DIGEST_SHA1, nullptr, 128, salt, 128));
+    ASSERT_FALSE(kdf.Init(KM_DIGEST_SHA1, key, 0, salt, 128));
+}
+
+}  // namespace test
+
+}  // namespace keymaster
diff --git a/keymaster/kem.h b/keymaster/kem.h
new file mode 100644
index 0000000..f2fa073
--- /dev/null
+++ b/keymaster/kem.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEM_H_
+#define SYSTEM_KEYMASTER_KEM_H_
+
+#include <keymaster/serializable.h>
+
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+// Kem is an abstract class that provides an interface to a key encapsulation
+// mechansim primitive. A key encapsulation mechanism works just like a
+// public-key encryption scheme, except that the encryption algorithm takes no
+// input other than the recipient’s public key. Instead, the encryption algorithm
+// generates a pair (K, C0), where K is a bit string of some specified length,
+// and C0 is an encryption of K, that is, the decryption algorithm applied to C0
+// yields K.
+class Kem {
+  public:
+    virtual ~Kem(){};
+
+    // For a key encapsulation mechanism, the goal of encryption is to take the recipient's public
+    // key, and to generate a pair (K, C0), where K is a bit string of some specified length,
+    // and C0 is an encryption of K.
+    virtual bool Encrypt(const Buffer& peer_public_value, Buffer* output_clear_key,
+                         Buffer* output_encrypted_key) = 0;
+    virtual bool Encrypt(const uint8_t* peer_public_value, size_t peer_public_value_len,
+                         Buffer* output_clear_key, Buffer* output_encrypted_key) = 0;
+
+    // Decrypt takes an encrypted key, and outputs its clear text.
+    // Decrypt takes ownership of \p private_key.
+    virtual bool Decrypt(EC_KEY* private_key, const Buffer& encrypted_key, Buffer* output_key) = 0;
+    virtual bool Decrypt(EC_KEY* private_key, const uint8_t* encrypted_key,
+                         size_t encrypted_key_len, Buffer* output_key) = 0;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEM_H_
diff --git a/keymaster/key.cpp b/keymaster/key.cpp
new file mode 100644
index 0000000..eb828e1
--- /dev/null
+++ b/keymaster/key.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <assert.h>
+
+#include "key.h"
+
+#include <openssl/x509.h>
+
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+Key::Key(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+         keymaster_error_t* error) {
+    assert(error);
+    authorizations_.push_back(hw_enforced);
+    authorizations_.push_back(sw_enforced);
+    *error = KM_ERROR_OK;
+    if (authorizations_.is_valid() != AuthorizationSet::OK)
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/key.h b/keymaster/key.h
new file mode 100644
index 0000000..9fb4063
--- /dev/null
+++ b/keymaster/key.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEY_H_
+#define SYSTEM_KEYMASTER_KEY_H_
+
+#include <UniquePtr.h>
+
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/keymaster_context.h>
+
+namespace keymaster {
+
+class Key {
+  public:
+    virtual ~Key() {}
+
+    /**
+     * Return a copy of raw key material, in the specified format.
+     */
+    virtual keymaster_error_t formatted_key_material(keymaster_key_format_t format,
+                                                     UniquePtr<uint8_t[]>* material,
+                                                     size_t* size) const = 0;
+
+    /**
+     * Generate an attestation certificate chain.
+     */
+    virtual keymaster_error_t GenerateAttestation(
+        const KeymasterContext& /* context */, const AuthorizationSet& /* attest_params */,
+        const AuthorizationSet& /* tee_enforced */, const AuthorizationSet& /* sw_enforced */,
+        keymaster_cert_chain_t* /* certificate_chain */) const {
+        return KM_ERROR_INCOMPATIBLE_ALGORITHM;
+    }
+
+    const AuthorizationSet& authorizations() const { return authorizations_; }
+
+  protected:
+    Key(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+        keymaster_error_t* error);
+
+  private:
+    AuthorizationSet authorizations_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEY_H_
diff --git a/keymaster/key_blob_test.cpp b/keymaster/key_blob_test.cpp
new file mode 100644
index 0000000..1e590f0
--- /dev/null
+++ b/keymaster/key_blob_test.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <algorithm>
+
+#include <gtest/gtest.h>
+
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+
+#include <keymaster/authorization_set.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/keymaster_tags.h>
+
+#include "android_keymaster_test_utils.h"
+#include "auth_encrypted_key_blob.h"
+#include "integrity_assured_key_blob.h"
+#include "ocb_utils.h"
+
+namespace keymaster {
+
+namespace test {
+
+const uint8_t master_key_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const uint8_t key_data[5] = {21, 22, 23, 24, 25};
+
+class KeyBlobTest : public testing::Test {
+  protected:
+    KeyBlobTest()
+        : master_key_(master_key_data, array_length(master_key_data)),
+          key_material_(key_data, array_length(key_data)) {
+        hw_enforced_.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+        hw_enforced_.push_back(TAG_KEY_SIZE, 256);
+        hw_enforced_.push_back(TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE);
+        hw_enforced_.push_back(TAG_MIN_SECONDS_BETWEEN_OPS, 10);
+        hw_enforced_.push_back(TAG_ALL_USERS);
+        hw_enforced_.push_back(TAG_NO_AUTH_REQUIRED);
+        hw_enforced_.push_back(TAG_ORIGIN, KM_ORIGIN_GENERATED);
+
+        sw_enforced_.push_back(TAG_ACTIVE_DATETIME, 10);
+        sw_enforced_.push_back(TAG_ORIGINATION_EXPIRE_DATETIME, 100);
+        sw_enforced_.push_back(TAG_CREATION_DATETIME, 10);
+
+        hidden_.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
+        hidden_.push_back(TAG_APPLICATION_ID, "my_app", 6);
+
+        nonce_.reserve(OCB_NONCE_LENGTH);
+        EXPECT_EQ(1, RAND_bytes(nonce_.peek_write(), OCB_NONCE_LENGTH));
+        nonce_.advance_write(OCB_NONCE_LENGTH);
+
+        tag_.reserve(OCB_TAG_LENGTH);
+    }
+
+    keymaster_error_t Encrypt() {
+        return OcbEncryptKey(hw_enforced_, sw_enforced_, hidden_, master_key_, key_material_,
+                             nonce_, &ciphertext_, &tag_);
+    }
+
+    keymaster_error_t Decrypt() {
+        return OcbDecryptKey(hw_enforced_, sw_enforced_, hidden_, master_key_, ciphertext_, nonce_,
+                             tag_, &decrypted_plaintext_);
+    }
+
+    keymaster_error_t Serialize() {
+        return SerializeAuthEncryptedBlob(ciphertext_, hw_enforced_, sw_enforced_, nonce_, tag_,
+                                          &serialized_blob_);
+    }
+
+    keymaster_error_t Deserialize() {
+        return DeserializeAuthEncryptedBlob(serialized_blob_, &ciphertext_, &hw_enforced_,
+                                            &sw_enforced_, &nonce_, &tag_);
+    }
+
+    AuthorizationSet hw_enforced_;
+    AuthorizationSet sw_enforced_;
+    AuthorizationSet hidden_;
+    Buffer nonce_, tag_;
+
+    KeymasterKeyBlob master_key_;
+    KeymasterKeyBlob key_material_;
+    KeymasterKeyBlob ciphertext_;
+    KeymasterKeyBlob decrypted_plaintext_;
+    KeymasterKeyBlob serialized_blob_;
+};
+
+TEST_F(KeyBlobTest, EncryptDecrypt) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // key_data shouldn't be anywhere in the blob, ciphertext should.
+    EXPECT_EQ(serialized_blob_.end(), std::search(serialized_blob_.begin(), serialized_blob_.end(),
+                                                  key_material_.begin(), key_material_.end()));
+    EXPECT_NE(serialized_blob_.end(), std::search(serialized_blob_.begin(), serialized_blob_.end(),
+                                                  ciphertext_.begin(), ciphertext_.end()));
+
+    ciphertext_.Clear();
+    nonce_.Clear();
+    tag_.Clear();
+    AuthorizationSet hw2;
+    AuthorizationSet sw2;
+
+    ASSERT_EQ(KM_ERROR_OK, DeserializeAuthEncryptedBlob(serialized_blob_, &ciphertext_, &hw2, &sw2,
+                                                        &nonce_, &tag_));
+    KeymasterKeyBlob plaintext;
+    OcbDecryptKey(hw2, sw2, hidden_, master_key_, ciphertext_, nonce_, tag_, &plaintext);
+
+    EXPECT_EQ(hw_enforced_, hw2);
+    EXPECT_EQ(sw_enforced_, sw2);
+
+    ASSERT_EQ(key_material_.key_material_size, plaintext.key_material_size);
+    EXPECT_EQ(0, memcmp(plaintext.begin(), key_material_.begin(), plaintext.key_material_size));
+}
+
+TEST_F(KeyBlobTest, WrongKeyLength) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // Modify the key length, shouldn't be able to parse.
+    serialized_blob_.writable_data()[1 /* version */ + 4 /* nonce len */ + 12 /* nonce */ + 3]++;
+
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Deserialize());
+}
+
+TEST_F(KeyBlobTest, WrongNonce) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // Find the nonce, then modify it.
+    auto nonce_ptr =
+        std::search(serialized_blob_.begin(), serialized_blob_.end(), nonce_.begin(), nonce_.end());
+    ASSERT_NE(nonce_ptr, serialized_blob_.end());
+    EXPECT_EQ(serialized_blob_.end(),
+              std::search(nonce_ptr + 1, serialized_blob_.end(), nonce_.begin(), nonce_.end()));
+    (*const_cast<uint8_t*>(nonce_ptr))++;
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
+}
+
+TEST_F(KeyBlobTest, WrongTag) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // Find the tag, them modify it.
+    auto tag_ptr =
+        std::search(serialized_blob_.begin(), serialized_blob_.end(), tag_.begin(), tag_.end());
+    ASSERT_NE(tag_ptr, serialized_blob_.end());
+    EXPECT_EQ(serialized_blob_.end(),
+              std::search(tag_ptr + 1, serialized_blob_.end(), tag_.begin(), tag_.end()));
+    (*const_cast<uint8_t*>(tag_ptr))++;
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
+}
+
+TEST_F(KeyBlobTest, WrongCiphertext) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // Find the ciphertext, them modify it.
+    auto ciphertext_ptr = std::search(serialized_blob_.begin(), serialized_blob_.end(),
+                                      ciphertext_.begin(), ciphertext_.end());
+    ASSERT_NE(ciphertext_ptr, serialized_blob_.end());
+    EXPECT_EQ(serialized_blob_.end(), std::search(ciphertext_ptr + 1, serialized_blob_.end(),
+                                                  ciphertext_.begin(), ciphertext_.end()));
+    (*const_cast<uint8_t*>(ciphertext_ptr))++;
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
+}
+
+TEST_F(KeyBlobTest, WrongMasterKey) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    uint8_t wrong_master_data[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    KeymasterKeyBlob wrong_master(wrong_master_data, array_length(wrong_master_data));
+
+    // Decrypting with wrong master key should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              OcbDecryptKey(hw_enforced_, sw_enforced_, hidden_, wrong_master, ciphertext_, nonce_,
+                            tag_, &decrypted_plaintext_));
+}
+
+TEST_F(KeyBlobTest, WrongHwEnforced) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // Find enforced serialization data and modify it.
+    size_t hw_enforced_size = hw_enforced_.SerializedSize();
+    UniquePtr<uint8_t[]> hw_enforced_data(new uint8_t[hw_enforced_size]);
+    hw_enforced_.Serialize(hw_enforced_data.get(), hw_enforced_data.get() + hw_enforced_size);
+
+    auto hw_enforced_ptr =
+        std::search(serialized_blob_.begin(), serialized_blob_.end(), hw_enforced_data.get(),
+                    hw_enforced_data.get() + hw_enforced_size);
+    ASSERT_NE(serialized_blob_.end(), hw_enforced_ptr);
+    EXPECT_EQ(serialized_blob_.end(),
+              std::search(hw_enforced_ptr + 1, serialized_blob_.end(), hw_enforced_data.get(),
+                          hw_enforced_data.get() + hw_enforced_size));
+    (*(const_cast<uint8_t*>(hw_enforced_ptr) + hw_enforced_size - 1))++;
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
+}
+
+TEST_F(KeyBlobTest, WrongSwEnforced) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    // Find enforced serialization data and modify it.
+    size_t sw_enforced_size = sw_enforced_.SerializedSize();
+    UniquePtr<uint8_t[]> sw_enforced_data(new uint8_t[sw_enforced_size]);
+    sw_enforced_.Serialize(sw_enforced_data.get(), sw_enforced_data.get() + sw_enforced_size);
+
+    auto sw_enforced_ptr =
+        std::search(serialized_blob_.begin(), serialized_blob_.end(), sw_enforced_data.get(),
+                    sw_enforced_data.get() + sw_enforced_size);
+    ASSERT_NE(serialized_blob_.end(), sw_enforced_ptr);
+    EXPECT_EQ(serialized_blob_.end(),
+              std::search(sw_enforced_ptr + 1, serialized_blob_.end(), sw_enforced_data.get(),
+                          sw_enforced_data.get() + sw_enforced_size));
+    (*(const_cast<uint8_t*>(sw_enforced_ptr) + sw_enforced_size - 1))++;
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, Decrypt());
+}
+
+TEST_F(KeyBlobTest, EmptyHidden) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    AuthorizationSet wrong_hidden;
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              OcbDecryptKey(hw_enforced_, sw_enforced_, wrong_hidden, master_key_, ciphertext_,
+                            nonce_, tag_, &decrypted_plaintext_));
+}
+
+TEST_F(KeyBlobTest, WrongRootOfTrust) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    AuthorizationSet wrong_hidden;
+    wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "bar", 2);
+    wrong_hidden.push_back(TAG_APPLICATION_ID, "my_app", 6);
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              OcbDecryptKey(hw_enforced_, sw_enforced_, wrong_hidden, master_key_, ciphertext_,
+                            nonce_, tag_, &decrypted_plaintext_));
+}
+
+TEST_F(KeyBlobTest, WrongAppId) {
+    ASSERT_EQ(KM_ERROR_OK, Encrypt());
+    ASSERT_EQ(KM_ERROR_OK, Serialize());
+
+    AuthorizationSet wrong_hidden;
+    wrong_hidden.push_back(TAG_ROOT_OF_TRUST, "foo", 3);
+    wrong_hidden.push_back(TAG_APPLICATION_ID, "your_app", 7);
+
+    // Deserialization shouldn't be affected, but decryption should fail.
+    ASSERT_EQ(KM_ERROR_OK, Deserialize());
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              OcbDecryptKey(hw_enforced_, sw_enforced_, wrong_hidden, master_key_, ciphertext_,
+                            nonce_, tag_, &decrypted_plaintext_));
+}
+
+// This test is especially useful when compiled for 32-bit mode and run under valgrind.
+TEST_F(KeyBlobTest, FuzzTest) {
+    time_t now = time(NULL);
+    std::cout << "Seeding rand() with " << now << " for fuzz test." << std::endl;
+    srand(now);
+
+    // Fill large buffer with random bytes.
+    const int kBufSize = 10000;
+    UniquePtr<uint8_t[]> buf(new uint8_t[kBufSize]);
+    for (size_t i = 0; i < kBufSize; ++i)
+        buf[i] = static_cast<uint8_t>(rand());
+
+    // Try to deserialize every offset with multiple methods.
+    size_t deserialize_auth_encrypted_success = 0;
+    for (size_t i = 0; i < kBufSize; ++i) {
+        keymaster_key_blob_t blob = {buf.get() + i, kBufSize - i};
+        KeymasterKeyBlob key_blob(blob);
+
+        // Integrity-assured blob.
+        ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+                  DeserializeIntegrityAssuredBlob(key_blob, hidden_, &key_material_, &hw_enforced_,
+                                                  &sw_enforced_));
+
+        // Auth-encrypted OCB blob.
+        keymaster_error_t error = DeserializeAuthEncryptedBlob(
+            key_blob, &ciphertext_, &hw_enforced_, &sw_enforced_, &nonce_, &tag_);
+        if (error == KM_ERROR_OK) {
+            // It's possible to deserialize successfully.  Decryption should always fail.
+            ++deserialize_auth_encrypted_success;
+            error = OcbDecryptKey(hw_enforced_, sw_enforced_, hidden_, master_key_, ciphertext_,
+                                  nonce_, tag_, &decrypted_plaintext_);
+        }
+        ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, error)
+            << "Somehow sucessfully parsed a blob with seed " << now << " at offset " << i;
+    }
+}
+
+TEST_F(KeyBlobTest, UnderflowTest) {
+    uint8_t buf[0];
+    keymaster_key_blob_t blob = {buf, 0};
+    KeymasterKeyBlob key_blob(blob);
+    EXPECT_NE(nullptr, key_blob.key_material);
+    EXPECT_EQ(0U, key_blob.key_material_size);
+
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              DeserializeIntegrityAssuredBlob(key_blob, hidden_, &key_material_, &hw_enforced_,
+                                              &sw_enforced_));
+
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              DeserializeAuthEncryptedBlob(key_blob, &ciphertext_, &hw_enforced_, &sw_enforced_,
+                                           &nonce_, &tag_));
+}
+
+TEST_F(KeyBlobTest, DupBufferToolarge) {
+    uint8_t buf[0];
+    keymaster_key_blob_t blob = {buf, 0};
+    blob.key_material_size = 16 * 1024 * 1024 + 1;
+    KeymasterKeyBlob key_blob(blob);
+    EXPECT_EQ(nullptr, key_blob.key_material);
+    EXPECT_EQ(0U, key_blob.key_material_size);
+
+    ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              DeserializeIntegrityAssuredBlob(key_blob, hidden_, &key_material_, &hw_enforced_,
+                                              &sw_enforced_));
+
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              DeserializeAuthEncryptedBlob(key_blob, &ciphertext_, &hw_enforced_, &sw_enforced_,
+                                           &nonce_, &tag_));
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/key_exchange.h b/keymaster/key_exchange.h
new file mode 100644
index 0000000..1019e20
--- /dev/null
+++ b/keymaster/key_exchange.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEY_EXCHANGE_H_
+#define SYSTEM_KEYMASTER_KEY_EXCHANGE_H_
+
+#include <openssl/ec.h>
+
+#include <keymaster/serializable.h>
+
+namespace keymaster {
+
+/**
+ * KeyExchange is an abstract class that provides an interface to a
+ * key-exchange primitive.
+ */
+class KeyExchange {
+  public:
+    virtual ~KeyExchange() {}
+
+    /**
+     * CalculateSharedKey computes the shared key between the local private key
+     * (which is implicitly known by a KeyExchange object) and a public value
+     * from the peer.
+     */
+    virtual bool CalculateSharedKey(const Buffer& peer_public_value, Buffer* shared_key) const = 0;
+    virtual bool CalculateSharedKey(const uint8_t* peer_public_value, size_t peer_public_value_len,
+                                    Buffer* shared_key) const = 0;
+
+    /**
+     * public_value writes to |public_value| the local public key which can be
+     * sent to a peer in order to complete a key exchange.
+     */
+    virtual bool public_value(Buffer* public_value) const = 0;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEY_EXCHANGE_H_
diff --git a/keymaster/keymaster0_engine.cpp b/keymaster/keymaster0_engine.cpp
new file mode 100644
index 0000000..bcd64e5
--- /dev/null
+++ b/keymaster/keymaster0_engine.cpp
@@ -0,0 +1,400 @@
+/*
+ * Copyright 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.
+ */
+
+#include "keymaster0_engine.h"
+
+#include <assert.h>
+
+#include <memory>
+
+#define LOG_TAG "Keymaster0Engine"
+#include <cutils/log.h>
+
+#include "keymaster/android_keymaster_utils.h"
+
+#include <openssl/bn.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+
+#include "openssl_utils.h"
+
+using std::shared_ptr;
+using std::unique_ptr;
+
+namespace keymaster {
+
+Keymaster0Engine* Keymaster0Engine::instance_ = nullptr;
+
+Keymaster0Engine::Keymaster0Engine(const keymaster0_device_t* keymaster0_device)
+    : keymaster0_device_(keymaster0_device), engine_(ENGINE_new()), supports_ec_(false) {
+    assert(!instance_);
+    instance_ = this;
+
+    rsa_index_ = RSA_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                      keyblob_dup, keyblob_free);
+    ec_key_index_ = EC_KEY_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                            keyblob_dup, keyblob_free);
+
+    rsa_method_.common.references = 0;
+    rsa_method_.common.is_static = 1;
+    rsa_method_.app_data = nullptr;
+    rsa_method_.init = nullptr;
+    rsa_method_.finish = nullptr;
+    rsa_method_.size = nullptr;
+    rsa_method_.sign = nullptr;
+    rsa_method_.verify = nullptr;
+    rsa_method_.encrypt = nullptr;
+    rsa_method_.sign_raw = nullptr;
+    rsa_method_.decrypt = nullptr;
+    rsa_method_.verify_raw = nullptr;
+    rsa_method_.private_transform = Keymaster0Engine::rsa_private_transform;
+    rsa_method_.mod_exp = nullptr;
+    rsa_method_.bn_mod_exp = BN_mod_exp_mont;
+    rsa_method_.flags = RSA_FLAG_OPAQUE;
+    rsa_method_.keygen = nullptr;
+    rsa_method_.supports_digest = nullptr;
+
+    ENGINE_set_RSA_method(engine_, &rsa_method_, sizeof(rsa_method_));
+
+    if ((keymaster0_device_->flags & KEYMASTER_SUPPORTS_EC) != 0) {
+        supports_ec_ = true;
+
+        ecdsa_method_.common.references = 0;
+        ecdsa_method_.common.is_static = 1;
+        ecdsa_method_.app_data = nullptr;
+        ecdsa_method_.init = nullptr;
+        ecdsa_method_.finish = nullptr;
+        ecdsa_method_.group_order_size = nullptr;
+        ecdsa_method_.sign = Keymaster0Engine::ecdsa_sign;
+        ecdsa_method_.verify = nullptr;
+        ecdsa_method_.flags = ECDSA_FLAG_OPAQUE;
+
+        ENGINE_set_ECDSA_method(engine_, &ecdsa_method_, sizeof(ecdsa_method_));
+    }
+}
+
+Keymaster0Engine::~Keymaster0Engine() {
+    if (keymaster0_device_)
+        keymaster0_device_->common.close(
+            reinterpret_cast<hw_device_t*>(const_cast<keymaster0_device_t*>(keymaster0_device_)));
+    ENGINE_free(engine_);
+    instance_ = nullptr;
+}
+
+bool Keymaster0Engine::GenerateRsaKey(uint64_t public_exponent, uint32_t public_modulus,
+                                      KeymasterKeyBlob* key_material) const {
+    assert(key_material);
+    keymaster_rsa_keygen_params_t params;
+    params.public_exponent = public_exponent;
+    params.modulus_size = public_modulus;
+
+    uint8_t* key_blob = 0;
+    if (keymaster0_device_->generate_keypair(keymaster0_device_, TYPE_RSA, &params, &key_blob,
+                                             &key_material->key_material_size) < 0) {
+        ALOGE("Error generating RSA key pair with keymaster0 device");
+        return false;
+    }
+    unique_ptr<uint8_t, Malloc_Delete> key_blob_deleter(key_blob);
+    key_material->key_material = dup_buffer(key_blob, key_material->key_material_size);
+    return true;
+}
+
+bool Keymaster0Engine::GenerateEcKey(uint32_t key_size, KeymasterKeyBlob* key_material) const {
+    assert(key_material);
+    keymaster_ec_keygen_params_t params;
+    params.field_size = key_size;
+
+    uint8_t* key_blob = 0;
+    if (keymaster0_device_->generate_keypair(keymaster0_device_, TYPE_EC, &params, &key_blob,
+                                             &key_material->key_material_size) < 0) {
+        ALOGE("Error generating EC key pair with keymaster0 device");
+        return false;
+    }
+    unique_ptr<uint8_t, Malloc_Delete> key_blob_deleter(key_blob);
+    key_material->key_material = dup_buffer(key_blob, key_material->key_material_size);
+    return true;
+}
+
+bool Keymaster0Engine::ImportKey(keymaster_key_format_t key_format,
+                                 const KeymasterKeyBlob& to_import,
+                                 KeymasterKeyBlob* imported_key) const {
+    assert(imported_key);
+    if (key_format != KM_KEY_FORMAT_PKCS8)
+        return false;
+
+    uint8_t* key_blob = 0;
+    if (keymaster0_device_->import_keypair(keymaster0_device_, to_import.key_material,
+                                           to_import.key_material_size, &key_blob,
+                                           &imported_key->key_material_size) < 0) {
+        ALOGW("Error importing keypair with keymaster0 device");
+        return false;
+    }
+    unique_ptr<uint8_t, Malloc_Delete> key_blob_deleter(key_blob);
+    imported_key->key_material = dup_buffer(key_blob, imported_key->key_material_size);
+    return true;
+}
+
+bool Keymaster0Engine::DeleteKey(const KeymasterKeyBlob& blob) const {
+    if (!keymaster0_device_->delete_keypair)
+        return true;
+    return (keymaster0_device_->delete_keypair(keymaster0_device_, blob.key_material,
+                                               blob.key_material_size) == 0);
+}
+
+bool Keymaster0Engine::DeleteAllKeys() const {
+    if (!keymaster0_device_->delete_all)
+        return true;
+    return (keymaster0_device_->delete_all(keymaster0_device_) == 0);
+}
+
+static keymaster_key_blob_t* duplicate_blob(const uint8_t* key_data, size_t key_data_size) {
+    unique_ptr<uint8_t[]> key_material_copy(dup_buffer(key_data, key_data_size));
+    if (!key_material_copy)
+        return nullptr;
+
+    unique_ptr<keymaster_key_blob_t> blob_copy(new (std::nothrow) keymaster_key_blob_t);
+    if (!blob_copy.get())
+        return nullptr;
+    blob_copy->key_material_size = key_data_size;
+    blob_copy->key_material = key_material_copy.release();
+    return blob_copy.release();
+}
+
+inline keymaster_key_blob_t* duplicate_blob(const keymaster_key_blob_t& blob) {
+    return duplicate_blob(blob.key_material, blob.key_material_size);
+}
+
+RSA* Keymaster0Engine::BlobToRsaKey(const KeymasterKeyBlob& blob) const {
+    // Create new RSA key (with engine methods) and insert blob
+    unique_ptr<RSA, RSA_Delete> rsa(RSA_new_method(engine_));
+    if (!rsa)
+        return nullptr;
+
+    keymaster_key_blob_t* blob_copy = duplicate_blob(blob);
+    if (!blob_copy->key_material || !RSA_set_ex_data(rsa.get(), rsa_index_, blob_copy))
+        return nullptr;
+
+    // Copy public key into new RSA key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(GetKeymaster0PublicKey(blob));
+    if (!pkey)
+        return nullptr;
+    unique_ptr<RSA, RSA_Delete> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+    if (!public_rsa)
+        return nullptr;
+    rsa->n = BN_dup(public_rsa->n);
+    rsa->e = BN_dup(public_rsa->e);
+    if (!rsa->n || !rsa->e)
+        return nullptr;
+
+    return rsa.release();
+}
+
+EC_KEY* Keymaster0Engine::BlobToEcKey(const KeymasterKeyBlob& blob) const {
+    // Create new EC key (with engine methods) and insert blob
+    unique_ptr<EC_KEY, EC_KEY_Delete> ec_key(EC_KEY_new_method(engine_));
+    if (!ec_key)
+        return nullptr;
+
+    keymaster_key_blob_t* blob_copy = duplicate_blob(blob);
+    if (!blob_copy->key_material || !EC_KEY_set_ex_data(ec_key.get(), ec_key_index_, blob_copy))
+        return nullptr;
+
+    // Copy public key into new EC key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(GetKeymaster0PublicKey(blob));
+    if (!pkey)
+        return nullptr;
+
+    unique_ptr<EC_KEY, EC_KEY_Delete> public_ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (!public_ec_key)
+        return nullptr;
+
+    if (!EC_KEY_set_group(ec_key.get(), EC_KEY_get0_group(public_ec_key.get())) ||
+        !EC_KEY_set_public_key(ec_key.get(), EC_KEY_get0_public_key(public_ec_key.get())))
+        return nullptr;
+
+    return ec_key.release();
+}
+
+const keymaster_key_blob_t* Keymaster0Engine::RsaKeyToBlob(const RSA* rsa) const {
+    return reinterpret_cast<keymaster_key_blob_t*>(RSA_get_ex_data(rsa, rsa_index_));
+}
+
+const keymaster_key_blob_t* Keymaster0Engine::EcKeyToBlob(const EC_KEY* ec_key) const {
+    return reinterpret_cast<keymaster_key_blob_t*>(EC_KEY_get_ex_data(ec_key, ec_key_index_));
+}
+
+/* static */
+int Keymaster0Engine::keyblob_dup(CRYPTO_EX_DATA* /* to */, const CRYPTO_EX_DATA* /* from */,
+                                  void** from_d, int /* index */, long /* argl */,
+                                  void* /* argp */) {
+    keymaster_key_blob_t* blob = reinterpret_cast<keymaster_key_blob_t*>(*from_d);
+    if (!blob)
+        return 1;
+    *from_d = duplicate_blob(*blob);
+    if (*from_d)
+        return 1;
+    return 0;
+}
+
+/* static */
+void Keymaster0Engine::keyblob_free(void* /* parent */, void* ptr, CRYPTO_EX_DATA* /* data */,
+                                    int /* index*/, long /* argl */, void* /* argp */) {
+    keymaster_key_blob_t* blob = reinterpret_cast<keymaster_key_blob_t*>(ptr);
+    if (blob) {
+        delete[] blob->key_material;
+        delete blob;
+    }
+}
+
+/* static */
+int Keymaster0Engine::rsa_private_transform(RSA* rsa, uint8_t* out, const uint8_t* in, size_t len) {
+    ALOGV("rsa_private_transform(%p, %p, %p, %u)", rsa, out, in, (unsigned)len);
+
+    assert(instance_);
+    return instance_->RsaPrivateTransform(rsa, out, in, len);
+}
+
+/* static */
+int Keymaster0Engine::ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                                 unsigned int* sig_len, EC_KEY* ec_key) {
+    ALOGV("ecdsa_sign(%p, %u, %p)", digest, (unsigned)digest_len, ec_key);
+    assert(instance_);
+    return instance_->EcdsaSign(digest, digest_len, sig, sig_len, ec_key);
+}
+
+bool Keymaster0Engine::Keymaster0Sign(const void* signing_params, const keymaster_key_blob_t& blob,
+                                      const uint8_t* data, const size_t data_length,
+                                      unique_ptr<uint8_t[], Malloc_Delete>* signature,
+                                      size_t* signature_length) const {
+    uint8_t* signed_data;
+    int err = keymaster0_device_->sign_data(keymaster0_device_, signing_params, blob.key_material,
+                                            blob.key_material_size, data, data_length, &signed_data,
+                                            signature_length);
+    if (err < 0) {
+        ALOGE("Keymaster0 signing failed with error %d", err);
+        return false;
+    }
+
+    signature->reset(signed_data);
+    return true;
+}
+
+EVP_PKEY* Keymaster0Engine::GetKeymaster0PublicKey(const KeymasterKeyBlob& blob) const {
+    uint8_t* pub_key_data;
+    size_t pub_key_data_length;
+    int err = keymaster0_device_->get_keypair_public(keymaster0_device_, blob.key_material,
+                                                     blob.key_material_size, &pub_key_data,
+                                                     &pub_key_data_length);
+    if (err < 0) {
+        ALOGE("Error %d extracting public key", err);
+        return nullptr;
+    }
+    unique_ptr<uint8_t, Malloc_Delete> pub_key(pub_key_data);
+
+    const uint8_t* p = pub_key_data;
+    return d2i_PUBKEY(nullptr /* allocate new struct */, &p, pub_key_data_length);
+}
+
+static bool data_too_large_for_public_modulus(const uint8_t* data, size_t len, const RSA* rsa) {
+    unique_ptr<BIGNUM, BIGNUM_Delete> input_as_bn(
+        BN_bin2bn(data, len, nullptr /* allocate result */));
+    return input_as_bn && BN_ucmp(input_as_bn.get(), rsa->n) >= 0;
+}
+
+int Keymaster0Engine::RsaPrivateTransform(RSA* rsa, uint8_t* out, const uint8_t* in,
+                                          size_t len) const {
+    const keymaster_key_blob_t* key_blob = RsaKeyToBlob(rsa);
+    if (key_blob == NULL) {
+        ALOGE("key had no key_blob!");
+        return 0;
+    }
+
+    keymaster_rsa_sign_params_t sign_params = {DIGEST_NONE, PADDING_NONE};
+    unique_ptr<uint8_t[], Malloc_Delete> signature;
+    size_t signature_length;
+    if (!Keymaster0Sign(&sign_params, *key_blob, in, len, &signature, &signature_length)) {
+        if (data_too_large_for_public_modulus(in, len, rsa)) {
+            ALOGE("Keymaster0 signing failed because data is too large.");
+            OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+        } else {
+            // We don't know what error code is correct; force an "unknown error" return
+            OPENSSL_PUT_ERROR(USER, KM_ERROR_UNKNOWN_ERROR);
+        }
+        return 0;
+    }
+    Eraser eraser(signature.get(), signature_length);
+
+    if (signature_length > len) {
+        /* The result of the RSA operation can never be larger than the size of
+         * the modulus so we assume that the result has extra zeros on the
+         * left. This provides attackers with an oracle, but there's nothing
+         * that we can do about it here. */
+        memcpy(out, signature.get() + signature_length - len, len);
+    } else if (signature_length < len) {
+        /* If the keymaster0 implementation returns a short value we assume that
+         * it's because it removed leading zeros from the left side. This is
+         * bad because it provides attackers with an oracle but we cannot do
+         * anything about a broken keymaster0 implementation here. */
+        memset(out, 0, len);
+        memcpy(out + len - signature_length, signature.get(), signature_length);
+    } else {
+        memcpy(out, signature.get(), len);
+    }
+
+    ALOGV("rsa=%p keystore_rsa_priv_dec successful", rsa);
+    return 1;
+}
+
+int Keymaster0Engine::EcdsaSign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                                unsigned int* sig_len, EC_KEY* ec_key) const {
+    const keymaster_key_blob_t* key_blob = EcKeyToBlob(ec_key);
+    if (key_blob == NULL) {
+        ALOGE("key had no key_blob!");
+        return 0;
+    }
+
+    // Truncate digest if it's too long
+    size_t max_input_len = (ec_group_size_bits(ec_key) + 7) / 8;
+    if (digest_len > max_input_len)
+        digest_len = max_input_len;
+
+    keymaster_ec_sign_params_t sign_params = {DIGEST_NONE};
+    unique_ptr<uint8_t[], Malloc_Delete> signature;
+    size_t signature_length;
+    if (!Keymaster0Sign(&sign_params, *key_blob, digest, digest_len, &signature,
+                        &signature_length)) {
+        // We don't know what error code is correct; force an "unknown error" return
+        OPENSSL_PUT_ERROR(USER, KM_ERROR_UNKNOWN_ERROR);
+        return 0;
+    }
+    Eraser eraser(signature.get(), signature_length);
+
+    if (signature_length == 0) {
+        ALOGW("No valid signature returned");
+        return 0;
+    } else if (signature_length > ECDSA_size(ec_key)) {
+        ALOGW("Signature is too large");
+        return 0;
+    } else {
+        memcpy(sig, signature.get(), signature_length);
+        *sig_len = signature_length;
+    }
+
+    ALOGV("ecdsa_sign(%p, %u, %p) => success", digest, (unsigned)digest_len, ec_key);
+    return 1;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/keymaster0_engine.h b/keymaster/keymaster0_engine.h
new file mode 100644
index 0000000..aedd85c
--- /dev/null
+++ b/keymaster/keymaster0_engine.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEYMASTER0_ENGINE_H_
+#define SYSTEM_KEYMASTER_KEYMASTER0_ENGINE_H_
+
+#include <memory>
+
+#include <openssl/ec.h>
+#include <openssl/engine.h>
+#include <openssl/ex_data.h>
+#include <openssl/rsa.h>
+
+#include <hardware/keymaster0.h>
+#include <hardware/keymaster_defs.h>
+
+namespace keymaster {
+
+struct KeymasterKeyBlob;
+
+/* Keymaster0Engine is a BoringSSL ENGINE that implements RSA & EC by forwarding the requested
+ * operations to a keymaster0 module. */
+class Keymaster0Engine {
+  public:
+    /**
+     * Create a Keymaster0Engine, wrapping the provided keymaster0_device.  The engine takes
+     * ownership of the device, and will close it during destruction.
+     */
+    explicit Keymaster0Engine(const keymaster0_device_t* keymaster0_device);
+    ~Keymaster0Engine();
+
+    bool supports_ec() const { return supports_ec_; }
+
+    bool GenerateRsaKey(uint64_t public_exponent, uint32_t public_modulus,
+                        KeymasterKeyBlob* key_material) const;
+    bool GenerateEcKey(uint32_t key_size, KeymasterKeyBlob* key_material) const;
+
+    bool ImportKey(keymaster_key_format_t key_format, const KeymasterKeyBlob& to_import,
+                   KeymasterKeyBlob* imported_key_material) const;
+    bool DeleteKey(const KeymasterKeyBlob& blob) const;
+    bool DeleteAllKeys() const;
+
+    RSA* BlobToRsaKey(const KeymasterKeyBlob& blob) const;
+    EC_KEY* BlobToEcKey(const KeymasterKeyBlob& blob) const;
+
+    const keymaster_key_blob_t* RsaKeyToBlob(const RSA* rsa) const;
+    const keymaster_key_blob_t* EcKeyToBlob(const EC_KEY* rsa) const;
+
+    const keymaster0_device_t* device() { return keymaster0_device_; }
+
+    EVP_PKEY* GetKeymaster0PublicKey(const KeymasterKeyBlob& blob) const;
+
+  private:
+    Keymaster0Engine(const Keymaster0Engine&);  // Uncopyable
+    void operator=(const Keymaster0Engine&);    // Unassignable
+
+    static int keyblob_dup(CRYPTO_EX_DATA* to, const CRYPTO_EX_DATA* from, void** from_d, int index,
+                           long argl, void* argp);
+    static void keyblob_free(void* parent, void* ptr, CRYPTO_EX_DATA* data, int index, long argl,
+                             void* argp);
+    static int rsa_private_transform(RSA* rsa, uint8_t* out, const uint8_t* in, size_t len);
+    static int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                          unsigned int* sig_len, EC_KEY* ec_key);
+
+    struct Malloc_Delete {
+        void operator()(void* p) { free(p); }
+    };
+
+    bool Keymaster0Sign(const void* signing_params, const keymaster_key_blob_t& key_blob,
+                        const uint8_t* data, const size_t data_length,
+                        std::unique_ptr<uint8_t[], Malloc_Delete>* signature,
+                        size_t* signature_length) const;
+
+    int RsaPrivateTransform(RSA* rsa, uint8_t* out, const uint8_t* in, size_t len) const;
+    int EcdsaSign(const uint8_t* digest, size_t digest_len, uint8_t* sig, unsigned int* sig_len,
+                  EC_KEY* ec_key) const;
+
+    const keymaster0_device_t* keymaster0_device_;
+    ENGINE* const engine_;
+    int rsa_index_, ec_key_index_;
+    bool supports_ec_;
+    RSA_METHOD rsa_method_;
+    ECDSA_METHOD ecdsa_method_;
+
+    static Keymaster0Engine* instance_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEYMASTER0_ENGINE_H_
diff --git a/keymaster/keymaster1_engine.cpp b/keymaster/keymaster1_engine.cpp
new file mode 100644
index 0000000..b20a434
--- /dev/null
+++ b/keymaster/keymaster1_engine.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright 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.
+ */
+
+#include "keymaster1_engine.h"
+
+#include <assert.h>
+
+#include <algorithm>
+#include <memory>
+
+#define LOG_TAG "Keymaster1Engine"
+#include <cutils/log.h>
+
+#include "keymaster/android_keymaster_utils.h"
+
+#include <openssl/bn.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+
+using std::shared_ptr;
+using std::unique_ptr;
+
+namespace keymaster {
+
+Keymaster1Engine* Keymaster1Engine::instance_ = nullptr;
+
+Keymaster1Engine::Keymaster1Engine(const keymaster1_device_t* keymaster1_device)
+    : keymaster1_device_(keymaster1_device), engine_(ENGINE_new()),
+      rsa_index_(RSA_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                      Keymaster1Engine::duplicate_key_data,
+                                      Keymaster1Engine::free_key_data)),
+      ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */, NULL /* argp */, NULL /* new_func */,
+                                            Keymaster1Engine::duplicate_key_data,
+                                            Keymaster1Engine::free_key_data)),
+      rsa_method_(BuildRsaMethod()), ecdsa_method_(BuildEcdsaMethod()) {
+    assert(rsa_index_ != -1);
+    assert(ec_key_index_ != -1);
+    assert(keymaster1_device);
+    assert(!instance_);
+
+    instance_ = this;
+
+    ENGINE_set_RSA_method(engine_.get(), &rsa_method_, sizeof(rsa_method_));
+    ENGINE_set_ECDSA_method(engine_.get(), &ecdsa_method_, sizeof(ecdsa_method_));
+}
+
+Keymaster1Engine::~Keymaster1Engine() {
+    keymaster1_device_->common.close(
+        reinterpret_cast<hw_device_t*>(const_cast<keymaster1_device_t*>(keymaster1_device_)));
+    instance_ = nullptr;
+}
+
+static void ConvertCharacteristics(keymaster_key_characteristics_t* characteristics,
+                                   AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) {
+    unique_ptr<keymaster_key_characteristics_t, Characteristics_Delete> characteristics_deleter(
+        characteristics);
+    if (hw_enforced)
+        hw_enforced->Reinitialize(characteristics->hw_enforced);
+    if (sw_enforced)
+        sw_enforced->Reinitialize(characteristics->sw_enforced);
+}
+
+keymaster_error_t Keymaster1Engine::GenerateKey(const AuthorizationSet& key_description,
+                                                KeymasterKeyBlob* key_blob,
+                                                AuthorizationSet* hw_enforced,
+                                                AuthorizationSet* sw_enforced) const {
+    assert(key_blob);
+
+    keymaster_key_characteristics_t* characteristics;
+    keymaster_key_blob_t blob;
+    keymaster_error_t error = keymaster1_device_->generate_key(keymaster1_device_, &key_description,
+                                                               &blob, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<uint8_t, Malloc_Delete> blob_deleter(const_cast<uint8_t*>(blob.key_material));
+    key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size);
+    key_blob->key_material_size = blob.key_material_size;
+
+    ConvertCharacteristics(characteristics, hw_enforced, sw_enforced);
+    return error;
+}
+
+keymaster_error_t Keymaster1Engine::ImportKey(const AuthorizationSet& key_description,
+                                              keymaster_key_format_t input_key_material_format,
+                                              const KeymasterKeyBlob& input_key_material,
+                                              KeymasterKeyBlob* output_key_blob,
+                                              AuthorizationSet* hw_enforced,
+                                              AuthorizationSet* sw_enforced) const {
+    assert(output_key_blob);
+
+    keymaster_key_characteristics_t* characteristics;
+    const keymaster_blob_t input_key = {input_key_material.key_material,
+                                        input_key_material.key_material_size};
+    keymaster_key_blob_t blob;
+    keymaster_error_t error = keymaster1_device_->import_key(keymaster1_device_, &key_description,
+                                                             input_key_material_format, &input_key,
+                                                             &blob, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<uint8_t, Malloc_Delete> blob_deleter(const_cast<uint8_t*>(blob.key_material));
+    output_key_blob->key_material = dup_buffer(blob.key_material, blob.key_material_size);
+    output_key_blob->key_material_size = blob.key_material_size;
+
+    ConvertCharacteristics(characteristics, hw_enforced, sw_enforced);
+    return error;
+}
+
+keymaster_error_t Keymaster1Engine::DeleteKey(const KeymasterKeyBlob& blob) const {
+    if (!keymaster1_device_->delete_key)
+        return KM_ERROR_OK;
+    return keymaster1_device_->delete_key(keymaster1_device_, &blob);
+}
+
+keymaster_error_t Keymaster1Engine::DeleteAllKeys() const {
+    if (!keymaster1_device_->delete_all_keys)
+        return KM_ERROR_OK;
+    return keymaster1_device_->delete_all_keys(keymaster1_device_);
+}
+
+RSA* Keymaster1Engine::BuildRsaKey(const KeymasterKeyBlob& blob,
+                                   const AuthorizationSet& additional_params,
+                                   keymaster_error_t* error) const {
+    // Create new RSA key (with engine methods) and add metadata
+    unique_ptr<RSA, RSA_Delete> rsa(RSA_new_method(engine_.get()));
+    if (!rsa) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    KeyData* key_data = new KeyData(blob, additional_params);
+    if (!RSA_set_ex_data(rsa.get(), rsa_index_, key_data)) {
+        *error = TranslateLastOpenSslError();
+        delete key_data;
+        return nullptr;
+    }
+
+    // Copy public key into new RSA key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        GetKeymaster1PublicKey(key_data->key_material, key_data->begin_params, error));
+    if (!pkey) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    unique_ptr<RSA, RSA_Delete> public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+    if (!public_rsa) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    rsa->n = BN_dup(public_rsa->n);
+    rsa->e = BN_dup(public_rsa->e);
+    if (!rsa->n || !rsa->e) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    *error = KM_ERROR_OK;
+    return rsa.release();
+}
+
+EC_KEY* Keymaster1Engine::BuildEcKey(const KeymasterKeyBlob& blob,
+                                     const AuthorizationSet& additional_params,
+                                     keymaster_error_t* error) const {
+    // Create new EC key (with engine methods) and insert blob
+    unique_ptr<EC_KEY, EC_KEY_Delete> ec_key(EC_KEY_new_method(engine_.get()));
+    if (!ec_key) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    KeyData* key_data = new KeyData(blob, additional_params);
+    if (!EC_KEY_set_ex_data(ec_key.get(), ec_key_index_, key_data)) {
+        *error = TranslateLastOpenSslError();
+        delete key_data;
+        return nullptr;
+    }
+
+    // Copy public key into new EC key
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(
+        GetKeymaster1PublicKey(blob, additional_params, error));
+    if (!pkey) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    unique_ptr<EC_KEY, EC_KEY_Delete> public_ec_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (!public_ec_key) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    if (!EC_KEY_set_group(ec_key.get(), EC_KEY_get0_group(public_ec_key.get())) ||
+        !EC_KEY_set_public_key(ec_key.get(), EC_KEY_get0_public_key(public_ec_key.get()))) {
+        *error = TranslateLastOpenSslError();
+        return nullptr;
+    }
+
+    *error = KM_ERROR_OK;
+    return ec_key.release();
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(EVP_PKEY* key) const {
+    switch (EVP_PKEY_type(key->type)) {
+    case EVP_PKEY_RSA: {
+        unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(key));
+        return GetData(rsa.get());
+    }
+
+    case EVP_PKEY_EC: {
+        unique_ptr<EC_KEY, EC_KEY_Delete> ec_key(EVP_PKEY_get1_EC_KEY(key));
+        return GetData(ec_key.get());
+    }
+
+    default:
+        return nullptr;
+    };
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(const RSA* rsa) const {
+    if (!rsa)
+        return nullptr;
+    return reinterpret_cast<KeyData*>(RSA_get_ex_data(rsa, rsa_index_));
+}
+
+Keymaster1Engine::KeyData* Keymaster1Engine::GetData(const EC_KEY* ec_key) const {
+    if (!ec_key)
+        return nullptr;
+    return reinterpret_cast<KeyData*>(EC_KEY_get_ex_data(ec_key, ec_key_index_));
+}
+
+/* static */
+int Keymaster1Engine::duplicate_key_data(CRYPTO_EX_DATA* /* to */, const CRYPTO_EX_DATA* /* from */,
+                                         void** from_d, int /* index */, long /* argl */,
+                                         void* /* argp */) {
+    KeyData* data = reinterpret_cast<KeyData*>(*from_d);
+    if (!data)
+        return 1;
+
+    // Default copy ctor is good.
+    *from_d = new KeyData(*data);
+    if (*from_d)
+        return 1;
+    return 0;
+}
+
+/* static */
+void Keymaster1Engine::free_key_data(void* /* parent */, void* ptr, CRYPTO_EX_DATA* /* data */,
+                                     int /* index*/, long /* argl */, void* /* argp */) {
+    delete reinterpret_cast<KeyData*>(ptr);
+}
+
+keymaster_error_t Keymaster1Engine::Keymaster1Finish(const KeyData* key_data,
+                                                     const keymaster_blob_t& input,
+                                                     keymaster_blob_t* output) {
+    if (key_data->op_handle == 0)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    size_t input_consumed;
+    // Note: devices are required to consume all input in a single update call for undigested
+    // signing operations and encryption operations.  No need to loop here.
+    keymaster_error_t error =
+        device()->update(device(), key_data->op_handle, &key_data->finish_params, &input,
+                         &input_consumed, nullptr /* out_params */, nullptr /* output */);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return device()->finish(device(), key_data->op_handle, &key_data->finish_params,
+                            nullptr /* signature */, nullptr /* out_params */, output);
+}
+
+/* static */
+int Keymaster1Engine::rsa_sign_raw(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                                   const uint8_t* in, size_t in_len, int padding) {
+    KeyData* key_data = instance_->GetData(rsa);
+    if (!key_data)
+        return 0;
+
+    if (padding != key_data->expected_openssl_padding) {
+        LOG_E("Expected sign_raw with padding %d but got padding %d",
+              key_data->expected_openssl_padding, padding);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    keymaster_blob_t input = {in, in_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *out_len = std::min(output.data_length, max_out);
+    memcpy(out, output.data, *out_len);
+    return 1;
+}
+
+/* static */
+int Keymaster1Engine::rsa_decrypt(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                                  const uint8_t* in, size_t in_len, int padding) {
+    KeyData* key_data = instance_->GetData(rsa);
+    if (!key_data)
+        return 0;
+
+    if (padding != key_data->expected_openssl_padding) {
+        LOG_E("Expected sign_raw with padding %d but got padding %d",
+              key_data->expected_openssl_padding, padding);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    keymaster_blob_t input = {in, in_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *out_len = std::min(output.data_length, max_out);
+    memcpy(out, output.data, *out_len);
+    return 1;
+}
+
+/* static */
+int Keymaster1Engine::ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                                 unsigned int* sig_len, EC_KEY* ec_key) {
+    KeyData* key_data = instance_->GetData(ec_key);
+    if (!key_data)
+        return 0;
+
+    // Truncate digest if it's too long
+    size_t max_input_len = (ec_group_size_bits(ec_key) + 7) / 8;
+    if (digest_len > max_input_len)
+        digest_len = max_input_len;
+
+    keymaster_blob_t input = {digest, digest_len};
+    keymaster_blob_t output;
+    key_data->error = instance_->Keymaster1Finish(key_data, input, &output);
+    if (key_data->error != KM_ERROR_OK)
+        return 0;
+    unique_ptr<uint8_t, Malloc_Delete> output_deleter(const_cast<uint8_t*>(output.data));
+
+    *sig_len = std::min(output.data_length, ECDSA_size(ec_key));
+    memcpy(sig, output.data, *sig_len);
+    return 1;
+}
+
+EVP_PKEY* Keymaster1Engine::GetKeymaster1PublicKey(const KeymasterKeyBlob& blob,
+                                                   const AuthorizationSet& additional_params,
+                                                   keymaster_error_t* error) const {
+    keymaster_blob_t client_id = {nullptr, 0};
+    keymaster_blob_t app_data = {nullptr, 0};
+    keymaster_blob_t* client_id_ptr = nullptr;
+    keymaster_blob_t* app_data_ptr = nullptr;
+    if (additional_params.GetTagValue(TAG_APPLICATION_ID, &client_id))
+        client_id_ptr = &client_id;
+    if (additional_params.GetTagValue(TAG_APPLICATION_DATA, &app_data))
+        app_data_ptr = &app_data;
+
+    keymaster_blob_t export_data = {nullptr, 0};
+    *error = keymaster1_device_->export_key(keymaster1_device_, KM_KEY_FORMAT_X509, &blob,
+                                            client_id_ptr, app_data_ptr, &export_data);
+    if (*error != KM_ERROR_OK)
+        return nullptr;
+
+    unique_ptr<uint8_t, Malloc_Delete> pub_key(const_cast<uint8_t*>(export_data.data));
+
+    const uint8_t* p = export_data.data;
+    return d2i_PUBKEY(nullptr /* allocate new struct */, &p, export_data.data_length);
+}
+
+RSA_METHOD Keymaster1Engine::BuildRsaMethod() {
+    RSA_METHOD method = {};
+
+    method.common.is_static = 1;
+    method.sign_raw = Keymaster1Engine::rsa_sign_raw;
+    method.decrypt = Keymaster1Engine::rsa_decrypt;
+    method.bn_mod_exp = BN_mod_exp_mont;
+    method.flags = RSA_FLAG_OPAQUE;
+
+    return method;
+}
+
+ECDSA_METHOD Keymaster1Engine::BuildEcdsaMethod() {
+    ECDSA_METHOD method = {};
+
+    method.common.is_static = 1;
+    method.sign = Keymaster1Engine::ecdsa_sign;
+    method.flags = ECDSA_FLAG_OPAQUE;
+
+    return method;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/keymaster1_engine.h b/keymaster/keymaster1_engine.h
new file mode 100644
index 0000000..9e2f13e
--- /dev/null
+++ b/keymaster/keymaster1_engine.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_KEYMASTER1_ENGINE_H_
+#define SYSTEM_KEYMASTER_KEYMASTER1_ENGINE_H_
+
+#include <memory>
+
+#include <openssl/ec.h>
+#include <openssl/engine.h>
+#include <openssl/ex_data.h>
+#include <openssl/rsa.h>
+
+#include <hardware/keymaster1.h>
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+class Keymaster1Engine {
+  public:
+    /**
+     * Create a Keymaster1Engine, wrapping the provided keymaster1_device.  The engine takes
+     * ownership of the device, and will close it during destruction.
+     */
+    explicit Keymaster1Engine(const keymaster1_device_t* keymaster1_device);
+    ~Keymaster1Engine();
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_material, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const;
+
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const;
+    keymaster_error_t DeleteKey(const KeymasterKeyBlob& blob) const;
+    keymaster_error_t DeleteAllKeys() const;
+
+    struct KeyData {
+        KeyData(const KeymasterKeyBlob& blob, const AuthorizationSet& params)
+            : op_handle(0), begin_params(params), key_material(blob), error(KM_ERROR_OK),
+              expected_openssl_padding(-1) {}
+
+        keymaster_operation_handle_t op_handle;
+        AuthorizationSet begin_params;
+        AuthorizationSet finish_params;
+        KeymasterKeyBlob key_material;
+        keymaster_error_t error;
+        int expected_openssl_padding;
+    };
+
+    RSA* BuildRsaKey(const KeymasterKeyBlob& blob, const AuthorizationSet& additional_params,
+                     keymaster_error_t* error) const;
+    EC_KEY* BuildEcKey(const KeymasterKeyBlob& blob, const AuthorizationSet& additional_params,
+                       keymaster_error_t* error) const;
+
+    KeyData* GetData(EVP_PKEY* key) const;
+    KeyData* GetData(const RSA* rsa) const;
+    KeyData* GetData(const EC_KEY* rsa) const;
+
+    const keymaster1_device_t* device() const { return keymaster1_device_; }
+
+    EVP_PKEY* GetKeymaster1PublicKey(const KeymasterKeyBlob& blob,
+                                     const AuthorizationSet& additional_params,
+                                     keymaster_error_t* error) const;
+
+  private:
+    Keymaster1Engine(const Keymaster1Engine&);  // Uncopyable
+    void operator=(const Keymaster1Engine&);    // Unassignable
+
+    RSA_METHOD BuildRsaMethod();
+    ECDSA_METHOD BuildEcdsaMethod();
+    void ConfigureEngineForRsa();
+    void ConfigureEngineForEcdsa();
+
+    keymaster_error_t Keymaster1Finish(const KeyData* key_data, const keymaster_blob_t& input,
+                                       keymaster_blob_t* output);
+
+    static int duplicate_key_data(CRYPTO_EX_DATA* to, const CRYPTO_EX_DATA* from, void** from_d,
+                                  int index, long argl, void* argp);
+    static void free_key_data(void* parent, void* ptr, CRYPTO_EX_DATA* data, int index, long argl,
+                              void* argp);
+
+    static int rsa_sign_raw(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                            const uint8_t* in, size_t in_len, int padding);
+    static int rsa_decrypt(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out,
+                           const uint8_t* in, size_t in_len, int padding);
+    static int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                          unsigned int* sig_len, EC_KEY* ec_key);
+
+    const keymaster1_device_t* const keymaster1_device_;
+    const std::unique_ptr<ENGINE, ENGINE_Delete> engine_;
+    const int rsa_index_;
+    const int ec_key_index_;
+
+    const RSA_METHOD rsa_method_;
+    const ECDSA_METHOD ecdsa_method_;
+
+    static Keymaster1Engine* instance_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_KEYMASTER1_ENGINE_H_
diff --git a/keymaster/keymaster_enforcement.cpp b/keymaster/keymaster_enforcement.cpp
new file mode 100644
index 0000000..7696d89
--- /dev/null
+++ b/keymaster/keymaster_enforcement.cpp
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <keymaster/keymaster_enforcement.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+
+#include <hardware/hw_auth_token.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+
+#include "List.h"
+
+using android::List;
+
+namespace keymaster {
+
+class AccessTimeMap {
+  public:
+    explicit AccessTimeMap(uint32_t max_size) : max_size_(max_size) {}
+
+    /* If the key is found, returns true and fills \p last_access_time.  If not found returns
+     * false. */
+    bool LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const;
+
+    /* Updates the last key access time with the currentTime parameter.  Adds the key if
+     * needed, returning false if key cannot be added because list is full. */
+    bool UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout);
+
+  private:
+    struct AccessTime {
+        km_id_t keyid;
+        uint32_t access_time;
+        uint32_t timeout;
+    };
+    android::List<AccessTime> last_access_list_;
+    const uint32_t max_size_;
+};
+
+class AccessCountMap {
+  public:
+    explicit AccessCountMap(uint32_t max_size) : max_size_(max_size) {}
+
+    /* If the key is found, returns true and fills \p count.  If not found returns
+     * false. */
+    bool KeyAccessCount(km_id_t keyid, uint32_t* count) const;
+
+    /* Increments key access count, adding an entry if the key has never been used.  Returns
+     * false if the list has reached maximum size. */
+    bool IncrementKeyAccessCount(km_id_t keyid);
+
+  private:
+    struct AccessCount {
+        km_id_t keyid;
+        uint64_t access_count;
+    };
+    android::List<AccessCount> access_count_list_;
+    const uint32_t max_size_;
+};
+
+bool is_public_key_algorithm(const AuthorizationSet& auth_set) {
+    keymaster_algorithm_t algorithm;
+    return auth_set.GetTagValue(TAG_ALGORITHM, &algorithm) &&
+           (algorithm == KM_ALGORITHM_RSA || algorithm == KM_ALGORITHM_EC);
+}
+
+static keymaster_error_t authorized_purpose(const keymaster_purpose_t purpose,
+                                            const AuthorizationSet& auth_set) {
+    switch (purpose) {
+    case KM_PURPOSE_VERIFY:
+    case KM_PURPOSE_ENCRYPT:
+    case KM_PURPOSE_SIGN:
+    case KM_PURPOSE_DECRYPT:
+        if (auth_set.Contains(TAG_PURPOSE, purpose))
+            return KM_ERROR_OK;
+        return KM_ERROR_INCOMPATIBLE_PURPOSE;
+
+    default:
+        return KM_ERROR_UNSUPPORTED_PURPOSE;
+    }
+}
+
+inline bool is_origination_purpose(keymaster_purpose_t purpose) {
+    return purpose == KM_PURPOSE_ENCRYPT || purpose == KM_PURPOSE_SIGN;
+}
+
+inline bool is_usage_purpose(keymaster_purpose_t purpose) {
+    return purpose == KM_PURPOSE_DECRYPT || purpose == KM_PURPOSE_VERIFY;
+}
+
+KeymasterEnforcement::KeymasterEnforcement(uint32_t max_access_time_map_size,
+                                           uint32_t max_access_count_map_size)
+    : access_time_map_(new (std::nothrow) AccessTimeMap(max_access_time_map_size)),
+      access_count_map_(new (std::nothrow) AccessCountMap(max_access_count_map_size)) {}
+
+KeymasterEnforcement::~KeymasterEnforcement() {
+    delete access_time_map_;
+    delete access_count_map_;
+}
+
+keymaster_error_t KeymasterEnforcement::AuthorizeOperation(const keymaster_purpose_t purpose,
+                                                           const km_id_t keyid,
+                                                           const AuthorizationSet& auth_set,
+                                                           const AuthorizationSet& operation_params,
+                                                           keymaster_operation_handle_t op_handle,
+                                                           bool is_begin_operation) {
+    if (is_public_key_algorithm(auth_set)) {
+        switch (purpose) {
+        case KM_PURPOSE_ENCRYPT:
+        case KM_PURPOSE_VERIFY:
+            /* Public key operations are always authorized. */
+            return KM_ERROR_OK;
+
+        case KM_PURPOSE_DECRYPT:
+        case KM_PURPOSE_SIGN:
+        case KM_PURPOSE_DERIVE_KEY:
+            break;
+        };
+    };
+
+    if (is_begin_operation)
+        return AuthorizeBegin(purpose, keyid, auth_set, operation_params);
+    else
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+}
+
+// For update and finish the only thing to check is user authentication, and then only if it's not
+// timeout-based.
+keymaster_error_t
+KeymasterEnforcement::AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
+                                              const AuthorizationSet& operation_params,
+                                              keymaster_operation_handle_t op_handle) {
+    int auth_type_index = -1;
+    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
+        switch (auth_set[pos].tag) {
+        case KM_TAG_NO_AUTH_REQUIRED:
+        case KM_TAG_AUTH_TIMEOUT:
+            // If no auth is required or if auth is timeout-based, we have nothing to check.
+            return KM_ERROR_OK;
+
+        case KM_TAG_USER_AUTH_TYPE:
+            auth_type_index = pos;
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    // Note that at this point we should be able to assume that authentication is required, because
+    // authentication is required if KM_TAG_NO_AUTH_REQUIRED is absent.  However, there are legacy
+    // keys which have no authentication-related tags, so we assume that absence is equivalent to
+    // presence of KM_TAG_NO_AUTH_REQUIRED.
+    //
+    // So, if we found KM_TAG_USER_AUTH_TYPE or if we find KM_TAG_USER_SECURE_ID then authentication
+    // is required.  If we find neither, then we assume authentication is not required and return
+    // success.
+    bool authentication_required = (auth_type_index != -1);
+    for (auto& param : auth_set) {
+        if (param.tag == KM_TAG_USER_SECURE_ID) {
+            authentication_required = true;
+            int auth_timeout_index = -1;
+            if (AuthTokenMatches(auth_set, operation_params, param.long_integer, auth_type_index,
+                                 auth_timeout_index, op_handle, false /* is_begin_operation */))
+                return KM_ERROR_OK;
+        }
+    }
+
+    if (authentication_required)
+        return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t KeymasterEnforcement::AuthorizeBegin(const keymaster_purpose_t purpose,
+                                                       const km_id_t keyid,
+                                                       const AuthorizationSet& auth_set,
+                                                       const AuthorizationSet& operation_params) {
+    // Find some entries that may be needed to handle KM_TAG_USER_SECURE_ID
+    int auth_timeout_index = -1;
+    int auth_type_index = -1;
+    int no_auth_required_index = -1;
+    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
+        switch (auth_set[pos].tag) {
+        case KM_TAG_AUTH_TIMEOUT:
+            auth_timeout_index = pos;
+            break;
+        case KM_TAG_USER_AUTH_TYPE:
+            auth_type_index = pos;
+            break;
+        case KM_TAG_NO_AUTH_REQUIRED:
+            no_auth_required_index = pos;
+            break;
+        default:
+            break;
+        }
+    }
+
+    keymaster_error_t error = authorized_purpose(purpose, auth_set);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    // If successful, and if key has a min time between ops, this will be set to the time limit
+    uint32_t min_ops_timeout = UINT32_MAX;
+
+    bool update_access_count = false;
+    bool caller_nonce_authorized_by_key = false;
+    bool authentication_required = false;
+    bool auth_token_matched = false;
+
+    for (auto& param : auth_set) {
+
+        // KM_TAG_PADDING_OLD and KM_TAG_DIGEST_OLD aren't actually members of the enum, so we can't
+        // switch on them.  There's nothing to validate for them, though, so just ignore them.
+        if (param.tag == KM_TAG_PADDING_OLD || param.tag == KM_TAG_DIGEST_OLD)
+            continue;
+
+        switch (param.tag) {
+
+        case KM_TAG_ACTIVE_DATETIME:
+            if (!activation_date_valid(param.date_time))
+                return KM_ERROR_KEY_NOT_YET_VALID;
+            break;
+
+        case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
+            if (is_origination_purpose(purpose) && expiration_date_passed(param.date_time))
+                return KM_ERROR_KEY_EXPIRED;
+            break;
+
+        case KM_TAG_USAGE_EXPIRE_DATETIME:
+            if (is_usage_purpose(purpose) && expiration_date_passed(param.date_time))
+                return KM_ERROR_KEY_EXPIRED;
+            break;
+
+        case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+            min_ops_timeout = param.integer;
+            if (!MinTimeBetweenOpsPassed(min_ops_timeout, keyid))
+                return KM_ERROR_KEY_RATE_LIMIT_EXCEEDED;
+            break;
+
+        case KM_TAG_MAX_USES_PER_BOOT:
+            update_access_count = true;
+            if (!MaxUsesPerBootNotExceeded(keyid, param.integer))
+                return KM_ERROR_KEY_MAX_OPS_EXCEEDED;
+            break;
+
+        case KM_TAG_USER_SECURE_ID:
+            if (no_auth_required_index != -1) {
+                // Key has both KM_TAG_USER_SECURE_ID and KM_TAG_NO_AUTH_REQUIRED
+                return KM_ERROR_INVALID_KEY_BLOB;
+            }
+
+            if (auth_timeout_index != -1) {
+                authentication_required = true;
+                if (AuthTokenMatches(auth_set, operation_params, param.long_integer,
+                                     auth_type_index, auth_timeout_index, 0 /* op_handle */,
+                                     true /* is_begin_operation */))
+                    auth_token_matched = true;
+            }
+            break;
+
+        case KM_TAG_CALLER_NONCE:
+            caller_nonce_authorized_by_key = true;
+            break;
+
+        /* Tags should never be in key auths. */
+        case KM_TAG_INVALID:
+        case KM_TAG_AUTH_TOKEN:
+        case KM_TAG_ROOT_OF_TRUST:
+        case KM_TAG_APPLICATION_DATA:
+            return KM_ERROR_INVALID_KEY_BLOB;
+
+        /* Tags used for cryptographic parameters in keygen.  Nothing to enforce. */
+        case KM_TAG_PURPOSE:
+        case KM_TAG_ALGORITHM:
+        case KM_TAG_KEY_SIZE:
+        case KM_TAG_BLOCK_MODE:
+        case KM_TAG_DIGEST:
+        case KM_TAG_MAC_LENGTH:
+        case KM_TAG_PADDING:
+        case KM_TAG_NONCE:
+        case KM_TAG_MIN_MAC_LENGTH:
+        case KM_TAG_KDF:
+        case KM_TAG_EC_CURVE:
+
+        /* Tags not used for operations. */
+        case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+        case KM_TAG_EXPORTABLE:
+
+        /* Algorithm specific parameters not used for access control. */
+        case KM_TAG_RSA_PUBLIC_EXPONENT:
+        case KM_TAG_ECIES_SINGLE_HASH_MODE:
+
+        /* Informational tags. */
+        case KM_TAG_CREATION_DATETIME:
+        case KM_TAG_ORIGIN:
+        case KM_TAG_ROLLBACK_RESISTANT:
+
+        /* Tags handled when KM_TAG_USER_SECURE_ID is handled */
+        case KM_TAG_NO_AUTH_REQUIRED:
+        case KM_TAG_USER_AUTH_TYPE:
+        case KM_TAG_AUTH_TIMEOUT:
+
+        /* Tag to provide data to operations. */
+        case KM_TAG_ASSOCIATED_DATA:
+
+        /* Tags that are implicitly verified by secure side */
+        case KM_TAG_ALL_APPLICATIONS:
+        case KM_TAG_APPLICATION_ID:
+        case KM_TAG_OS_VERSION:
+        case KM_TAG_OS_PATCHLEVEL:
+
+        /* Ignored pending removal */
+        case KM_TAG_USER_ID:
+        case KM_TAG_ALL_USERS:
+
+        /* TODO(swillden): Handle these */
+        case KM_TAG_INCLUDE_UNIQUE_ID:
+        case KM_TAG_UNIQUE_ID:
+        case KM_TAG_RESET_SINCE_ID_ROTATION:
+        case KM_TAG_ALLOW_WHILE_ON_BODY:
+            break;
+
+        case KM_TAG_BOOTLOADER_ONLY:
+            return KM_ERROR_INVALID_KEY_BLOB;
+        }
+    }
+
+    if (authentication_required && !auth_token_matched) {
+        LOG_E("Auth required but no matching auth token found", 0);
+        return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
+    }
+
+    if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) &&
+        operation_params.find(KM_TAG_NONCE) != -1)
+        return KM_ERROR_CALLER_NONCE_PROHIBITED;
+
+    if (min_ops_timeout != UINT32_MAX) {
+        if (!access_time_map_) {
+            LOG_S("Rate-limited keys table not allocated.  Rate-limited keys disabled", 0);
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        }
+
+        if (!access_time_map_->UpdateKeyAccessTime(keyid, get_current_time(), min_ops_timeout)) {
+            LOG_E("Rate-limited keys table full.  Entries will time out.", 0);
+            return KM_ERROR_TOO_MANY_OPERATIONS;
+        }
+    }
+
+    if (update_access_count) {
+        if (!access_count_map_) {
+            LOG_S("Usage-count limited keys tabel not allocated.  Count-limited keys disabled", 0);
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        }
+
+        if (!access_count_map_->IncrementKeyAccessCount(keyid)) {
+            LOG_E("Usage count-limited keys table full, until reboot.", 0);
+            return KM_ERROR_TOO_MANY_OPERATIONS;
+        }
+    }
+
+    return KM_ERROR_OK;
+}
+
+class EvpMdCtx {
+  public:
+    EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
+    ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
+
+    EVP_MD_CTX* get() { return &ctx_; }
+
+  private:
+    EVP_MD_CTX ctx_;
+};
+
+/* static */
+bool KeymasterEnforcement::CreateKeyId(const keymaster_key_blob_t& key_blob, km_id_t* keyid) {
+    EvpMdCtx ctx;
+
+    uint8_t hash[EVP_MAX_MD_SIZE];
+    unsigned int hash_len;
+    if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
+        EVP_DigestUpdate(ctx.get(), key_blob.key_material, key_blob.key_material_size) &&
+        EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
+        assert(hash_len >= sizeof(*keyid));
+        memcpy(keyid, hash, sizeof(*keyid));
+        return true;
+    }
+
+    return false;
+}
+
+bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) {
+    if (!access_time_map_)
+        return false;
+
+    uint32_t last_access_time;
+    if (!access_time_map_->LastKeyAccessTime(keyid, &last_access_time))
+        return true;
+    return min_time_between <= static_cast<int64_t>(get_current_time()) - last_access_time;
+}
+
+bool KeymasterEnforcement::MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses) {
+    if (!access_count_map_)
+        return false;
+
+    uint32_t key_access_count;
+    if (!access_count_map_->KeyAccessCount(keyid, &key_access_count))
+        return true;
+    return key_access_count < max_uses;
+}
+
+bool KeymasterEnforcement::AuthTokenMatches(const AuthorizationSet& auth_set,
+                                            const AuthorizationSet& operation_params,
+                                            const uint64_t user_secure_id,
+                                            const int auth_type_index, const int auth_timeout_index,
+                                            const keymaster_operation_handle_t op_handle,
+                                            bool is_begin_operation) const {
+    assert(auth_type_index < static_cast<int>(auth_set.size()));
+    assert(auth_timeout_index < static_cast<int>(auth_set.size()));
+
+    keymaster_blob_t auth_token_blob;
+    if (!operation_params.GetTagValue(TAG_AUTH_TOKEN, &auth_token_blob)) {
+        LOG_E("Authentication required, but auth token not provided", 0);
+        return false;
+    }
+
+    if (auth_token_blob.data_length != sizeof(hw_auth_token_t)) {
+        LOG_E("Bug: Auth token is the wrong size (%d expected, %d found)", sizeof(hw_auth_token_t),
+              auth_token_blob.data_length);
+        return false;
+    }
+
+    hw_auth_token_t auth_token;
+    memcpy(&auth_token, auth_token_blob.data, sizeof(hw_auth_token_t));
+    if (auth_token.version != HW_AUTH_TOKEN_VERSION) {
+        LOG_E("Bug: Auth token is the version %d (or is not an auth token). Expected %d",
+              auth_token.version, HW_AUTH_TOKEN_VERSION);
+        return false;
+    }
+
+    if (!ValidateTokenSignature(auth_token)) {
+        LOG_E("Auth token signature invalid", 0);
+        return false;
+    }
+
+    if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) {
+        LOG_E("Auth token has the challenge %llu, need %llu", auth_token.challenge, op_handle);
+        return false;
+    }
+
+    if (user_secure_id != auth_token.user_id && user_secure_id != auth_token.authenticator_id) {
+        LOG_I("Auth token SIDs %llu and %llu do not match key SID %llu", auth_token.user_id,
+              auth_token.authenticator_id, user_secure_id);
+        return false;
+    }
+
+    if (auth_type_index < 0 || auth_type_index > static_cast<int>(auth_set.size())) {
+        LOG_E("Auth required but no auth type found", 0);
+        return false;
+    }
+
+    assert(auth_set[auth_type_index].tag == KM_TAG_USER_AUTH_TYPE);
+    if (auth_set[auth_type_index].tag != KM_TAG_USER_AUTH_TYPE)
+        return false;
+
+    uint32_t key_auth_type_mask = auth_set[auth_type_index].integer;
+    uint32_t token_auth_type = ntoh(auth_token.authenticator_type);
+    if ((key_auth_type_mask & token_auth_type) == 0) {
+        LOG_E("Key requires match of auth type mask 0%uo, but token contained 0%uo",
+              key_auth_type_mask, token_auth_type);
+        return false;
+    }
+
+    if (auth_timeout_index != -1 && is_begin_operation) {
+        assert(auth_set[auth_timeout_index].tag == KM_TAG_AUTH_TIMEOUT);
+        if (auth_set[auth_timeout_index].tag != KM_TAG_AUTH_TIMEOUT)
+            return false;
+
+        if (auth_token_timed_out(auth_token, auth_set[auth_timeout_index].integer)) {
+            LOG_E("Auth token has timed out", 0);
+            return false;
+        }
+    }
+
+    // Survived the whole gauntlet.  We have authentage!
+    return true;
+}
+
+bool AccessTimeMap::LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const {
+    for (auto& entry : last_access_list_)
+        if (entry.keyid == keyid) {
+            *last_access_time = entry.access_time;
+            return true;
+        }
+    return false;
+}
+
+bool AccessTimeMap::UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout) {
+    List<AccessTime>::iterator iter;
+    for (iter = last_access_list_.begin(); iter != last_access_list_.end();) {
+        if (iter->keyid == keyid) {
+            iter->access_time = current_time;
+            return true;
+        }
+
+        // Expire entry if possible.
+        assert(current_time >= iter->access_time);
+        if (current_time - iter->access_time >= iter->timeout)
+            iter = last_access_list_.erase(iter);
+        else
+            ++iter;
+    }
+
+    if (last_access_list_.size() >= max_size_)
+        return false;
+
+    AccessTime new_entry;
+    new_entry.keyid = keyid;
+    new_entry.access_time = current_time;
+    new_entry.timeout = timeout;
+    last_access_list_.push_front(new_entry);
+    return true;
+}
+
+bool AccessCountMap::KeyAccessCount(km_id_t keyid, uint32_t* count) const {
+    for (auto& entry : access_count_list_)
+        if (entry.keyid == keyid) {
+            *count = entry.access_count;
+            return true;
+        }
+    return false;
+}
+
+bool AccessCountMap::IncrementKeyAccessCount(km_id_t keyid) {
+    for (auto& entry : access_count_list_)
+        if (entry.keyid == keyid) {
+            // Note that the 'if' below will always be true because KM_TAG_MAX_USES_PER_BOOT is a
+            // uint32_t, and as soon as entry.access_count reaches the specified maximum value
+            // operation requests will be rejected and access_count won't be incremented any more.
+            // And, besides, UINT64_MAX is huge.  But we ensure that it doesn't wrap anyway, out of
+            // an abundance of caution.
+            if (entry.access_count < UINT64_MAX)
+                ++entry.access_count;
+            return true;
+        }
+
+    if (access_count_list_.size() >= max_size_)
+        return false;
+
+    AccessCount new_entry;
+    new_entry.keyid = keyid;
+    new_entry.access_count = 1;
+    access_count_list_.push_front(new_entry);
+    return true;
+}
+}; /* namespace keymaster */
diff --git a/keymaster/keymaster_enforcement_test.cpp b/keymaster/keymaster_enforcement_test.cpp
new file mode 100644
index 0000000..3874744
--- /dev/null
+++ b/keymaster/keymaster_enforcement_test.cpp
@@ -0,0 +1,872 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <keymaster/android_keymaster.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/keymaster_enforcement.h>
+
+#include "android_keymaster_test_utils.h"
+
+namespace keymaster {
+namespace test {
+
+class TestKeymasterEnforcement : public KeymasterEnforcement {
+  public:
+    TestKeymasterEnforcement()
+        : KeymasterEnforcement(3, 3), current_time_(10000), report_token_valid_(true) {}
+
+    keymaster_error_t AuthorizeOperation(const keymaster_purpose_t purpose, const km_id_t keyid,
+                                         const AuthorizationSet& auth_set) {
+        AuthorizationSet empty_set;
+        return KeymasterEnforcement::AuthorizeOperation(
+            purpose, keyid, auth_set, empty_set, 0 /* op_handle */, true /* is_begin_operation */);
+    }
+    using KeymasterEnforcement::AuthorizeOperation;
+
+    uint32_t get_current_time() const override { return current_time_; }
+    bool activation_date_valid(uint64_t activation_date) const override {
+        // Convert java date to time_t, non-portably.
+        time_t activation_time = activation_date / 1000;
+        return difftime(time(NULL), activation_time) >= 0;
+    }
+    bool expiration_date_passed(uint64_t expiration_date) const override {
+        // Convert jave date to time_t, non-portably.
+        time_t expiration_time = expiration_date / 1000;
+        return difftime(time(NULL), expiration_time) > 0;
+    }
+    bool auth_token_timed_out(const hw_auth_token_t& token, uint32_t timeout) const {
+        return current_time_ > ntoh(token.timestamp) + timeout;
+    }
+    bool ValidateTokenSignature(const hw_auth_token_t&) const override {
+        return report_token_valid_;
+    }
+
+    void tick(unsigned seconds = 1) { current_time_ += seconds; }
+    uint32_t current_time() { return current_time_; }
+    void set_report_token_valid(bool report_token_valid) {
+        report_token_valid_ = report_token_valid;
+    }
+
+  private:
+    uint32_t current_time_;
+    bool report_token_valid_;
+};
+
+class KeymasterBaseTest : public ::testing::Test {
+  protected:
+    KeymasterBaseTest() {
+        past_time = 0;
+
+        time_t t = time(NULL);
+        future_tm = localtime(&t);
+        future_tm->tm_year += 1;
+        future_time = static_cast<uint64_t>(mktime(future_tm)) * 1000;
+        sign_param = Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN);
+    }
+    virtual ~KeymasterBaseTest() {}
+
+    TestKeymasterEnforcement kmen;
+
+    tm past_tm;
+    tm* future_tm;
+    uint64_t past_time;
+    uint64_t future_time;
+    static const km_id_t key_id = 0xa;
+    static const uid_t uid = 0xf;
+    keymaster_key_param_t sign_param;
+};
+
+TEST_F(KeymasterBaseTest, TestValidKeyPeriodNoTags) {
+    keymaster_key_param_t params[] = {
+        sign_param,
+    };
+    AuthorizationSet single_auth_set(params, array_length(params));
+
+    keymaster_error_t kmer = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, single_auth_set);
+    ASSERT_EQ(KM_ERROR_OK, kmer);
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidActiveTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_NO_AUTH_REQUIRED), Authorization(TAG_ACTIVE_DATETIME, future_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    ASSERT_EQ(KM_ERROR_KEY_NOT_YET_VALID,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+
+    // Pubkey ops allowed.
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestValidActiveTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ACTIVE_DATETIME, past_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_valid_time = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+    ASSERT_EQ(KM_ERROR_OK, kmer_valid_time);
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidOriginationExpireTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, past_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+
+    // Pubkey ops allowed.
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidOriginationExpireTimeOnUsgae) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, past_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_invalid_origination =
+        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
+    ASSERT_EQ(KM_ERROR_OK, kmer_invalid_origination);
+}
+
+TEST_F(KeymasterBaseTest, TestValidOriginationExpireTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, future_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_valid_origination =
+        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+    ASSERT_EQ(KM_ERROR_OK, kmer_valid_origination);
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidUsageExpireTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES),
+        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_invalid_origination =
+        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
+    ASSERT_EQ(KM_ERROR_KEY_EXPIRED, kmer_invalid_origination);
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidPubkeyUsageExpireTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
+        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_invalid_origination =
+        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
+    // Pubkey ops allowed.
+    ASSERT_EQ(KM_ERROR_OK, kmer_invalid_origination);
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidUsageExpireTimeOnOrigination) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_USAGE_EXPIRE_DATETIME, past_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_invalid_origination =
+        kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+    ASSERT_EQ(KM_ERROR_OK, kmer_invalid_origination);
+}
+
+TEST_F(KeymasterBaseTest, TestValidUsageExpireTime) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_USAGE_EXPIRE_DATETIME, future_time),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer_valid_usage =
+        kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
+    ASSERT_EQ(KM_ERROR_OK, kmer_valid_usage);
+}
+
+TEST_F(KeymasterBaseTest, TestValidSingleUseAccesses) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+
+    ASSERT_EQ(KM_ERROR_OK, kmer1);
+    ASSERT_EQ(KM_ERROR_OK, kmer2);
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidMaxOps) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
+        Authorization(TAG_MAX_USES_PER_BOOT, 4),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    ASSERT_EQ(KM_ERROR_KEY_MAX_OPS_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    // Pubkey ops allowed.
+    ASSERT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestOverFlowMaxOpsTable) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_MAX_USES_PER_BOOT, 2),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 2 /* key_id */, auth_set));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 3 /* key_id */, auth_set));
+
+    // Key 4 should fail, because table is full.
+    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 4 /* key_id */, auth_set));
+
+    // Key 1 still works, because it's already in the table and hasn't reached max.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));
+
+    // Key 1 no longer works, because it's reached max.
+    EXPECT_EQ(KM_ERROR_KEY_MAX_OPS_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));
+
+    // Key 4 should fail, because table is (still and forever) full.
+    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 4 /* key_id */, auth_set));
+
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidTimeBetweenOps) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 10),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    keymaster_error_t kmer1 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+    keymaster_error_t kmer2 = kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set);
+    keymaster_error_t kmer3 = kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set);
+
+    ASSERT_EQ(KM_ERROR_OK, kmer1);
+    kmen.tick(2);
+    ASSERT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED, kmer2);
+
+    // Allowed because it's a pubkey op.
+    ASSERT_EQ(KM_ERROR_OK, kmer3);
+}
+
+TEST_F(KeymasterBaseTest, TestValidTimeBetweenOps) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 2),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+    kmen.tick();
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    kmen.tick();
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestOptTimeoutTableOverflow) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES),
+        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 4),
+        Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+
+    kmen.tick();
+
+    // Key 1 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
+
+    kmen.tick();
+
+    // Key 1 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+    // Key 2 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
+
+    kmen.tick();
+
+    // Key 1 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+    // Key 2 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
+    // Key 3 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
+    // Key 4 fails because the table is full
+    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));
+
+    kmen.tick();
+
+    // Key 4 succeeds because key 1 expired.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));
+
+    // Key 1 fails because the table is full... and key 1 is no longer in it.
+    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+    // Key 2 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
+    // Key 3 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
+
+    kmen.tick();
+
+    // Key 1 succeeds because key 2 expired
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+    // Key 2 fails because the table is full... and key 2 is no longer in it.
+    EXPECT_EQ(KM_ERROR_TOO_MANY_OPERATIONS,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
+    // Key 3 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
+    // Key 4 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 4 /* key_id */, auth_set));
+
+    kmen.tick(4);
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 2 /* key_id */, auth_set));
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 3 /* key_id */, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestPubkeyOptTimeoutTableOverflow) {
+    keymaster_key_param_t params[] = {
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
+        Authorization(TAG_MIN_SECONDS_BETWEEN_OPS, 4), Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
+    };
+
+    AuthorizationSet auth_set(params, array_length(params));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));
+
+    kmen.tick();
+
+    // Key 1 fails because it's too soon
+    EXPECT_EQ(KM_ERROR_KEY_RATE_LIMIT_EXCEEDED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, 1 /* key_id */, auth_set));
+    // Too soo, but pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, 1 /* key_id */, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidPurpose) {
+    keymaster_purpose_t invalidPurpose1 = static_cast<keymaster_purpose_t>(-1);
+    keymaster_purpose_t invalidPurpose2 = static_cast<keymaster_purpose_t>(4);
+
+    AuthorizationSet auth_set(
+        AuthorizationSetBuilder().Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
+
+    EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
+              kmen.AuthorizeOperation(invalidPurpose1, key_id, auth_set));
+    EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
+              kmen.AuthorizeOperation(invalidPurpose2, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestIncompatiblePurposeSymmetricKey) {
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE,
+              kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, auth_set));
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE,
+              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestIncompatiblePurposeAssymmetricKey) {
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+
+    // This one is allowed because it's a pubkey op.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, auth_set));
+    EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PURPOSE,
+              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidCallerNonce) {
+    AuthorizationSet no_caller_nonce(AuthorizationSetBuilder()
+                                         .Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT)
+                                         .Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT)
+                                         .Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
+    AuthorizationSet caller_nonce(AuthorizationSetBuilder()
+                                      .Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT)
+                                      .Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT)
+                                      .Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
+                                      .Authorization(TAG_CALLER_NONCE));
+    AuthorizationSet begin_params(AuthorizationSetBuilder().Authorization(TAG_NONCE, "foo", 3));
+
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, caller_nonce, begin_params,
+                                      0 /* challenge */, true /* is_begin_operation */));
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, caller_nonce, begin_params,
+                                      0 /* challenge */, true /* is_begin_operation */));
+    EXPECT_EQ(KM_ERROR_CALLER_NONCE_PROHIBITED,
+              kmen.AuthorizeOperation(KM_PURPOSE_ENCRYPT, key_id, no_caller_nonce, begin_params,
+                                      0 /* challenge */, true /* is_begin_operation */));
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_DECRYPT, key_id, no_caller_nonce, begin_params,
+                                      0 /* challenge */, true /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestBootloaderOnly) {
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_BOOTLOADER_ONLY));
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestInvalidTag) {
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_INVALID)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpSuccess) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpInvalidTokenSignature) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC)
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    kmen.set_report_token_valid(false);
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      token.challenge, false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpWrongChallenge) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                      token.challenge + 1 /* doesn't match token */,
+                                      false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpNoAuthType) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      token.challenge, false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpWrongAuthType) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(
+        AuthorizationSetBuilder()
+            .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+            .Authorization(TAG_USER_SECURE_ID, token.user_id)
+            .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_FINGERPRINT /* doesn't match token */)
+            .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      token.challenge, false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpWrongSid) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(
+        AuthorizationSetBuilder()
+            .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+            .Authorization(TAG_USER_SECURE_ID, token.user_id + 1 /* doesn't match token */)
+            .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+            .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+    // Pubkey op allowed.
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      token.challenge, false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpSuccessAlternateSid) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 10;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_USER_SECURE_ID, token.authenticator_id)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthPerOpMissingToken) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = 0;
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+
+    // During begin we can skip the auth token
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                                   token.challenge, true /* is_begin_operation */));
+    // Afterwards we must have authentication
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+    // Pubkey ops allowed
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      token.challenge, false /* is_begin_operation */));
+
+    auth_set.Reinitialize(AuthorizationSetBuilder()
+                              .Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES)
+                              .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                              .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                              .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN)
+                              .build());
+
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      token.challenge, false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestAuthAndNoAuth) {
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_USER_SECURE_ID, 1)
+                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set));
+}
+
+TEST_F(KeymasterBaseTest, TestTimedAuthSuccess) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = hton(kmen.current_time());
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_AUTH_TIMEOUT, 1)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                      0 /* irrelevant */, false /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestTimedAuthTimedOut) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = hton(static_cast<uint64_t>(kmen.current_time()));
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_AUTH_TIMEOUT, 1)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+    op_params.push_back(Authorization(TAG_AUTH_TOKEN, &token, sizeof(token)));
+
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                      0 /* irrelevant */, false /* is_begin_operation */));
+
+    kmen.tick(1);
+
+    // token still good
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                      0 /* irrelevant */, false /* is_begin_operation */));
+
+    kmen.tick(1);
+
+    // token expired, not allowed during begin.
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                      0 /* irrelevant */, true /* is_begin_operation */));
+
+    // token expired, afterwards it's okay.
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params,
+                                      0 /* irrelevant */, false /* is_begin_operation */));
+
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                      0 /* irrelevant */, true /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestTimedAuthMissingToken) {
+    hw_auth_token_t token;
+    memset(&token, 0, sizeof(token));
+    token.version = HW_AUTH_TOKEN_VERSION;
+    token.challenge = 99;
+    token.user_id = 9;
+    token.authenticator_id = 0;
+    token.authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token.timestamp = hton(static_cast<uint64_t>(kmen.current_time()));
+
+    AuthorizationSet auth_set(AuthorizationSetBuilder()
+                                  .Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA)
+                                  .Authorization(TAG_USER_SECURE_ID, token.user_id)
+                                  .Authorization(TAG_AUTH_TIMEOUT, 1)
+                                  .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_ANY)
+                                  .Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
+
+    AuthorizationSet op_params;
+
+    // Unlike auth-per-op, must have the auth token during begin.
+    EXPECT_EQ(KM_ERROR_KEY_USER_NOT_AUTHENTICATED,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      true /* is_begin_operation */));
+
+    // Later we don't check (though begin would fail, so there wouldn't be a later).
+    EXPECT_EQ(KM_ERROR_OK,
+              kmen.AuthorizeOperation(KM_PURPOSE_SIGN, key_id, auth_set, op_params, token.challenge,
+                                      false /* is_begin_operation */));
+
+    // Pubkey ops allowed.
+    EXPECT_EQ(KM_ERROR_OK, kmen.AuthorizeOperation(KM_PURPOSE_VERIFY, key_id, auth_set, op_params,
+                                                   token.challenge, true /* is_begin_operation */));
+}
+
+TEST_F(KeymasterBaseTest, TestCreateKeyId) {
+    keymaster_key_blob_t blob = {reinterpret_cast<const uint8_t*>("foobar"), 6};
+
+    km_id_t key_id = 0;
+    EXPECT_TRUE(KeymasterEnforcement::CreateKeyId(blob, &key_id));
+    EXPECT_NE(0U, key_id);
+}
+
+}; /* namespace test */
+}; /* namespace keymaster */
diff --git a/keymaster/keymaster_tags.cpp b/keymaster/keymaster_tags.cpp
new file mode 100644
index 0000000..ce7156f
--- /dev/null
+++ b/keymaster/keymaster_tags.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/keymaster_tags.h>
+
+namespace keymaster {
+
+#ifdef KEYMASTER_NAME_TAGS
+const char* StringifyTag(keymaster_tag_t tag) {
+    switch (tag) {
+    case KM_TAG_INVALID:
+        return "KM_TAG_INVALID";
+    case KM_TAG_PURPOSE:
+        return "KM_TAG_PURPOSE";
+    case KM_TAG_ALGORITHM:
+        return "KM_TAG_ALGORITHM";
+    case KM_TAG_KEY_SIZE:
+        return "KM_TAG_KEY_SIZE";
+    case KM_TAG_BLOCK_MODE:
+        return "KM_TAG_BLOCK_MODE";
+    case KM_TAG_DIGEST:
+        return "KM_TAG_DIGEST";
+    case KM_TAG_PADDING:
+        return "KM_TAG_PADDING";
+    case KM_TAG_CALLER_NONCE:
+        return "KM_TAG_CALLER_NONCE";
+    case KM_TAG_MIN_MAC_LENGTH:
+        return "KM_TAG_MIN_MAC_LENGTH";
+    case KM_TAG_RSA_PUBLIC_EXPONENT:
+        return "KM_TAG_RSA_PUBLIC_EXPONENT";
+    case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+        return "KM_TAG_BLOB_USAGE_REQUIREMENTS";
+    case KM_TAG_BOOTLOADER_ONLY:
+        return "KM_TAG_BOOTLOADER_ONLY";
+    case KM_TAG_ACTIVE_DATETIME:
+        return "KM_TAG_ACTIVE_DATETIME";
+    case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
+        return "KM_TAG_ORIGINATION_EXPIRE_DATETIME";
+    case KM_TAG_USAGE_EXPIRE_DATETIME:
+        return "KM_TAG_USAGE_EXPIRE_DATETIME";
+    case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+        return "KM_TAG_MIN_SECONDS_BETWEEN_OPS";
+    case KM_TAG_MAX_USES_PER_BOOT:
+        return "KM_TAG_MAX_USES_PER_BOOT";
+    case KM_TAG_ALL_USERS:
+        return "KM_TAG_ALL_USERS";
+    case KM_TAG_USER_ID:
+        return "KM_TAG_USER_ID";
+    case KM_TAG_USER_SECURE_ID:
+        return "KM_TAG_USER_SECURE_ID";
+    case KM_TAG_NO_AUTH_REQUIRED:
+        return "KM_TAG_NO_AUTH_REQUIRED";
+    case KM_TAG_USER_AUTH_TYPE:
+        return "KM_TAG_USER_AUTH_TYPE";
+    case KM_TAG_AUTH_TIMEOUT:
+        return "KM_TAG_AUTH_TIMEOUT";
+    case KM_TAG_ALL_APPLICATIONS:
+        return "KM_TAG_ALL_APPLICATIONS";
+    case KM_TAG_APPLICATION_ID:
+        return "KM_TAG_APPLICATION_ID";
+    case KM_TAG_APPLICATION_DATA:
+        return "KM_TAG_APPLICATION_DATA";
+    case KM_TAG_CREATION_DATETIME:
+        return "KM_TAG_CREATION_DATETIME";
+    case KM_TAG_ORIGIN:
+        return "KM_TAG_ORIGIN";
+    case KM_TAG_ROLLBACK_RESISTANT:
+        return "KM_TAG_ROLLBACK_RESISTANT";
+    case KM_TAG_ROOT_OF_TRUST:
+        return "KM_TAG_ROOT_OF_TRUST";
+    case KM_TAG_ASSOCIATED_DATA:
+        return "KM_TAG_ASSOCIATED_DATA";
+    case KM_TAG_NONCE:
+        return "KM_TAG_NONCE";
+    case KM_TAG_AUTH_TOKEN:
+        return "KM_TAG_AUTH_TOKEN";
+    case KM_TAG_MAC_LENGTH:
+        return "KM_TAG_MAC_LENGTH";
+    case KM_TAG_KDF:
+        return "KM_TAG_KDF";
+    case KM_TAG_EC_CURVE:
+        return "KM_TAG_EC_CURVE";
+    case KM_TAG_ECIES_SINGLE_HASH_MODE:
+        return "KM_TAG_ECIES_SINGLE_HASH_MODE";
+    case KM_TAG_OS_VERSION:
+        return "KM_TAG_OS_VERSION";
+    case KM_TAG_OS_PATCHLEVEL:
+        return "KM_TAG_OS_PATCHLEVEL";
+    case KM_TAG_EXPORTABLE:
+        return "KM_TAG_EXPORTABLE";
+    case KM_TAG_UNIQUE_ID:
+        return "KM_TAG_UNIQUE_ID";
+    case KM_TAG_INCLUDE_UNIQUE_ID:
+        return "KM_TAG_INCLUDE_UNIQUE_ID";
+    case KM_TAG_RESET_SINCE_ID_ROTATION:
+        return "KM_TAG_RESET_SINCE_ID_ROTATION";
+    case KM_TAG_ALLOW_WHILE_ON_BODY:
+        return "KM_TAG_ALLOW_WHILE_ON_BODY";
+    }
+    return "<Unknown>";
+}
+#endif  // KEYMASTER_NAME_TAGS
+
+// DEFINE_KEYMASTER_TAG is used to create TypedTag instances for each non-enum keymaster tag.
+#define DEFINE_KEYMASTER_TAG(type, name) TypedTag<type, KM_##name> name
+
+DEFINE_KEYMASTER_TAG(KM_INVALID, TAG_INVALID);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_KEY_SIZE);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_MAC_LENGTH);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_CALLER_NONCE);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_MIN_MAC_LENGTH);
+DEFINE_KEYMASTER_TAG(KM_ULONG, TAG_RSA_PUBLIC_EXPONENT);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ECIES_SINGLE_HASH_MODE);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_INCLUDE_UNIQUE_ID);
+DEFINE_KEYMASTER_TAG(KM_DATE, TAG_ACTIVE_DATETIME);
+DEFINE_KEYMASTER_TAG(KM_DATE, TAG_ORIGINATION_EXPIRE_DATETIME);
+DEFINE_KEYMASTER_TAG(KM_DATE, TAG_USAGE_EXPIRE_DATETIME);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_MIN_SECONDS_BETWEEN_OPS);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_MAX_USES_PER_BOOT);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_USERS);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_USER_ID);
+DEFINE_KEYMASTER_TAG(KM_ULONG_REP, TAG_USER_SECURE_ID);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_NO_AUTH_REQUIRED);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_AUTH_TIMEOUT);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ALLOW_WHILE_ON_BODY);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_APPLICATIONS);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_ID);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_DATA);
+DEFINE_KEYMASTER_TAG(KM_DATE, TAG_CREATION_DATETIME);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANT);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ROOT_OF_TRUST);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_ASSOCIATED_DATA);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_NONCE);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_AUTH_TOKEN);
+DEFINE_KEYMASTER_TAG(KM_BOOL, TAG_BOOTLOADER_ONLY);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_OS_VERSION);
+DEFINE_KEYMASTER_TAG(KM_UINT, TAG_OS_PATCHLEVEL);
+DEFINE_KEYMASTER_TAG(KM_BYTES, TAG_UNIQUE_ID);
+
+// DEFINE_KEYMASTER_ENUM_TAG is used to create TypedEnumTag instances for each enum keymaster tag.
+
+#define DEFINE_KEYMASTER_ENUM_TAG(type, name, enumtype) TypedEnumTag<type, KM_##name, enumtype> name
+
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_PURPOSE, keymaster_purpose_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_ALGORITHM, keymaster_algorithm_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_BLOCK_MODE, keymaster_block_mode_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_DIGEST, keymaster_digest_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_DIGEST_OLD, keymaster_digest_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_PADDING, keymaster_padding_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_PADDING_OLD, keymaster_padding_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_BLOB_USAGE_REQUIREMENTS,
+                          keymaster_key_blob_usage_requirements_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_ORIGIN, keymaster_key_origin_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_USER_AUTH_TYPE, hw_authenticator_type_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_KDF, keymaster_kdf_t);
+DEFINE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_EC_CURVE, keymaster_ec_curve_t);
+
+}  // namespace keymaster
diff --git a/keymaster/km0_sw_rsa_512.blob b/keymaster/km0_sw_rsa_512.blob
new file mode 100644
index 0000000..7fee81c
--- /dev/null
+++ b/keymaster/km0_sw_rsa_512.blob
Binary files differ
diff --git a/keymaster/km1_sw_ecdsa_256.blob b/keymaster/km1_sw_ecdsa_256.blob
new file mode 100644
index 0000000..5b9a6f4
--- /dev/null
+++ b/keymaster/km1_sw_ecdsa_256.blob
Binary files differ
diff --git a/keymaster/km1_sw_rsa_512.blob b/keymaster/km1_sw_rsa_512.blob
new file mode 100644
index 0000000..db1730a
--- /dev/null
+++ b/keymaster/km1_sw_rsa_512.blob
Binary files differ
diff --git a/keymaster/km1_sw_rsa_512_unversioned.blob b/keymaster/km1_sw_rsa_512_unversioned.blob
new file mode 100644
index 0000000..e4f6a11
--- /dev/null
+++ b/keymaster/km1_sw_rsa_512_unversioned.blob
Binary files differ
diff --git a/keymaster/logger.cpp b/keymaster/logger.cpp
new file mode 100644
index 0000000..f86a68f
--- /dev/null
+++ b/keymaster/logger.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+Logger* Logger::instance_ = 0;
+
+/* static */
+int Logger::Log(LogLevel level, const char* fmt, va_list args) {
+    if (!instance_)
+        return 0;
+    return instance_->log_msg(level, fmt, args);
+}
+
+/* static */
+int Logger::Log(LogLevel level, const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int result = Log(level, fmt, args);
+    va_end(args);
+    return result;
+}
+
+/* static */
+int Logger::Debug(const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int result = Log(DEBUG_LVL, fmt, args);
+    va_end(args);
+    return result;
+}
+
+/* static */
+int Logger::Info(const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int result = Log(INFO_LVL, fmt, args);
+    va_end(args);
+    return result;
+}
+/* static */
+int Logger::Warning(const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int result = Log(WARNING_LVL, fmt, args);
+    va_end(args);
+    return result;
+}
+/* static */
+int Logger::Error(const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int result = Log(ERROR_LVL, fmt, args);
+    va_end(args);
+    return result;
+}
+/* static */
+int Logger::Severe(const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int result = Log(SEVERE_LVL, fmt, args);
+    va_end(args);
+    return result;
+}
+
+
+}  // namespace keymaster
diff --git a/keymaster/nist_curve_key_exchange.cpp b/keymaster/nist_curve_key_exchange.cpp
new file mode 100644
index 0000000..0dd3a54
--- /dev/null
+++ b/keymaster/nist_curve_key_exchange.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright 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.
+ */
+
+#include "nist_curve_key_exchange.h"
+
+#include <openssl/ec.h>
+#include <openssl/ecdh.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#include "openssl_err.h"
+
+namespace keymaster {
+
+NistCurveKeyExchange::NistCurveKeyExchange(EC_KEY* private_key, keymaster_error_t* error)
+    : private_key_(private_key) {
+    if (!private_key_.get() || !EC_KEY_check_key(private_key_.get())) {
+        *error = KM_ERROR_INVALID_ARGUMENT;
+        return;
+    }
+    *error = ExtractPublicKey();
+}
+
+/* static */
+NistCurveKeyExchange* NistCurveKeyExchange::GenerateKeyExchange(keymaster_ec_curve_t curve) {
+    int curve_name;
+    switch (curve) {
+    case KM_EC_CURVE_P_224:
+        curve_name = NID_secp224r1;
+        break;
+    case KM_EC_CURVE_P_256:
+        curve_name = NID_X9_62_prime256v1;
+        break;
+    case KM_EC_CURVE_P_384:
+        curve_name = NID_secp384r1;
+        break;
+    case KM_EC_CURVE_P_521:
+        curve_name = NID_secp521r1;
+        break;
+    default:
+        LOG_E("Not a NIST curve: %d", curve);
+        return nullptr;
+    }
+
+    UniquePtr<EC_KEY, EC_KEY_Delete> key(EC_KEY_new_by_curve_name(curve_name));
+    if (!key.get() || !EC_KEY_generate_key(key.get())) {
+        return nullptr;
+    }
+    keymaster_error_t error;
+    NistCurveKeyExchange* key_exchange = new NistCurveKeyExchange(key.release(), &error);
+    if (error != KM_ERROR_OK) {
+        return nullptr;
+    }
+    return key_exchange;
+}
+
+keymaster_error_t NistCurveKeyExchange::ExtractPublicKey() {
+    const EC_GROUP* group = EC_KEY_get0_group(private_key_.get());
+    size_t field_len_bits;
+    keymaster_error_t error = ec_get_group_size(group, &field_len_bits);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    shared_secret_len_ = (field_len_bits + 7) / 8;
+    public_key_len_ = 1 + 2 * shared_secret_len_;
+    public_key_.reset(new uint8_t[public_key_len_]);
+    if (EC_POINT_point2oct(group, EC_KEY_get0_public_key(private_key_.get()),
+                           POINT_CONVERSION_UNCOMPRESSED, public_key_.get(), public_key_len_,
+                           nullptr /* ctx */) != public_key_len_) {
+        return TranslateLastOpenSslError();
+    }
+    return KM_ERROR_OK;
+}
+
+bool NistCurveKeyExchange::CalculateSharedKey(const Buffer& peer_public_value,
+                                              Buffer* out_result) const {
+
+    return CalculateSharedKey(peer_public_value.peek_read(), peer_public_value.available_read(),
+                              out_result);
+}
+
+bool NistCurveKeyExchange::CalculateSharedKey(const uint8_t* peer_public_value,
+                                              size_t peer_public_value_len,
+                                              Buffer* out_result) const {
+    const EC_GROUP* group = EC_KEY_get0_group(private_key_.get());
+    UniquePtr<EC_POINT, EC_POINT_Delete> point(EC_POINT_new(group));
+    if (!point.get() ||
+        !EC_POINT_oct2point(/* also test if point is on curve */
+                            group, point.get(), peer_public_value, peer_public_value_len,
+                            nullptr /* ctx */) ||
+        !EC_POINT_is_on_curve(group, point.get(), nullptr /* ctx */)) {
+        LOG_E("Can't convert peer public value to point: %d", TranslateLastOpenSslError());
+        return false;
+    }
+
+    UniquePtr<uint8_t[]> result(new uint8_t[shared_secret_len_]);
+    if (ECDH_compute_key(result.get(), shared_secret_len_, point.get(), private_key_.get(),
+                         nullptr /* kdf */) != static_cast<int>(shared_secret_len_)) {
+        LOG_E("Can't compute ECDH shared key: %d", TranslateLastOpenSslError());
+        return false;
+    }
+
+    out_result->Reinitialize(result.get(), shared_secret_len_);
+    return true;
+}
+
+bool NistCurveKeyExchange::public_value(Buffer* public_value) const {
+    if (public_key_.get() != nullptr && public_key_len_ != 0) {
+        return public_value->Reinitialize(public_key_.get(), public_key_len_);
+    }
+    return false;
+}
+
+}  // namespace keymaster
\ No newline at end of file
diff --git a/keymaster/nist_curve_key_exchange.h b/keymaster/nist_curve_key_exchange.h
new file mode 100644
index 0000000..0a93882
--- /dev/null
+++ b/keymaster/nist_curve_key_exchange.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_NIST_CURVE_KEY_EXCHANGE_H_
+#define SYSTEM_KEYMASTER_NIST_CURVE_KEY_EXCHANGE_H_
+
+#include "key_exchange.h"
+
+#include <keymaster/authorization_set.h>
+#include <hardware/keymaster_defs.h>
+
+#include <UniquePtr.h>
+
+#include "openssl_utils.h"
+
+namespace keymaster {
+
+/**
+ * NistCurveKeyExchange implements a KeyExchange using elliptic-curve
+ * Diffie-Hellman on NIST curves: P-224, P-256, P-384 and P-521.
+ */
+class NistCurveKeyExchange : public KeyExchange {
+  public:
+    ~NistCurveKeyExchange() override {}
+
+    /**
+     * NistCurveKeyExchange takes ownership of \p private_key.
+     */
+    NistCurveKeyExchange(EC_KEY* private_key, keymaster_error_t* error);
+
+    /**
+     * GenerateKeyExchange generates a new public/private key pair on a NIST curve and returns
+     * a new key exchange object.
+     */
+    static NistCurveKeyExchange* GenerateKeyExchange(keymaster_ec_curve_t curve);
+
+    /**
+     * KeyExchange interface.
+     */
+    bool CalculateSharedKey(const uint8_t* peer_public_value, size_t peer_public_value_len,
+                            Buffer* shared_key) const override;
+    bool CalculateSharedKey(const Buffer& peer_public_value, Buffer* shared_key) const override;
+    bool public_value(Buffer* public_value) const override;
+
+    /* Caller takes ownership of \p private_key. */
+    EC_KEY* private_key() { return private_key_.release(); }
+
+  private:
+    keymaster_error_t ExtractPublicKey();
+
+    UniquePtr<EC_KEY, EC_KEY_Delete> private_key_;
+    UniquePtr<uint8_t[]> public_key_;
+    size_t public_key_len_;
+    size_t shared_secret_len_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_NIST_CURVE_KEY_EXCHANGE_H_
\ No newline at end of file
diff --git a/keymaster/nist_curve_key_exchange_test.cpp b/keymaster/nist_curve_key_exchange_test.cpp
new file mode 100644
index 0000000..39ea38b
--- /dev/null
+++ b/keymaster/nist_curve_key_exchange_test.cpp
@@ -0,0 +1,219 @@
+/*
+ * Copyright 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.
+ */
+
+#include "nist_curve_key_exchange.h"
+
+#include <gtest/gtest.h>
+#include <openssl/evp.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_utils.h>
+
+#include "android_keymaster_test_utils.h"
+
+using std::string;
+
+namespace keymaster {
+namespace test {
+
+StdoutLogger logger;
+
+static const keymaster_ec_curve_t kEcCurves[] = {KM_EC_CURVE_P_224, KM_EC_CURVE_P_256,
+                                                 KM_EC_CURVE_P_384, KM_EC_CURVE_P_521};
+
+/**
+ * SharedKey just tests that the basic key exchange identity holds: that both
+ * parties end up with the same key.
+ */
+TEST(NistCurveKeyExchange, SharedKey) {
+    for (auto& curve : kEcCurves) {
+        AuthorizationSet kex_description(
+            AuthorizationSetBuilder().Authorization(TAG_EC_CURVE, curve));
+        for (size_t j = 0; j < 5; j++) {
+            NistCurveKeyExchange* alice_keyex = NistCurveKeyExchange::GenerateKeyExchange(curve);
+            NistCurveKeyExchange* bob_keyex = NistCurveKeyExchange::GenerateKeyExchange(curve);
+
+            ASSERT_TRUE(alice_keyex != nullptr);
+            ASSERT_TRUE(bob_keyex != nullptr);
+
+            Buffer alice_public_value;
+            ASSERT_TRUE(alice_keyex->public_value(&alice_public_value));
+            Buffer bob_public_value;
+            ASSERT_TRUE(bob_keyex->public_value(&bob_public_value));
+
+            Buffer alice_shared, bob_shared;
+            ASSERT_TRUE(alice_keyex->CalculateSharedKey(bob_public_value, &alice_shared));
+            ASSERT_TRUE(bob_keyex->CalculateSharedKey(alice_public_value, &bob_shared));
+            EXPECT_EQ(alice_shared.available_read(), bob_shared.available_read());
+            EXPECT_EQ(0, memcmp(alice_shared.peek_read(), bob_shared.peek_read(),
+                                alice_shared.available_read()));
+        }
+    }
+}
+
+/*
+ * This test tries a key agreement with a false public key (i.e. with
+ * a point not on the curve.)
+ * The expected result of such a protocol should be that the
+ * key agreement fails and returns an error.
+*/
+static const char* kInvalidPublicKeys[] = {
+    "04"  // uncompressed public key
+    "deadbeef7f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287"
+    "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
+};
+
+TEST(NistCurveKeyExchange, InvalidPublicKey) {
+    for (auto& curve : kEcCurves) {
+        AuthorizationSet kex_description(
+            AuthorizationSetBuilder().Authorization(TAG_EC_CURVE, curve));
+        KeyExchange* key_exchange = NistCurveKeyExchange::GenerateKeyExchange(curve);
+        ASSERT_TRUE(key_exchange != nullptr);
+
+        string peer_public_key = hex2str(kInvalidPublicKeys[0]);
+        Buffer computed_shared_secret;
+        ASSERT_FALSE(key_exchange->CalculateSharedKey(
+            reinterpret_cast<const uint8_t*>(peer_public_key.data()), peer_public_key.size(),
+            &computed_shared_secret));
+    }
+}
+
+/**
+ * Test that key exchange fails when peer public key is the point at infinity.
+ */
+TEST(NistCurveKeyExchange, TestInfinity) {
+    for (auto& curve : kEcCurves) {
+        /* Obtain the point at infinity */
+        EC_GROUP* group = ec_get_group(curve);
+        EC_POINT* point_at_infinity = EC_POINT_new(group);
+        EC_POINT_set_to_infinity(group, point_at_infinity);
+        EXPECT_EQ(1, EC_POINT_is_on_curve(group, point_at_infinity, nullptr));
+        size_t field_len_in_bits;
+        ec_get_group_size(group, &field_len_in_bits);
+        size_t field_len = (field_len_in_bits + 7) / 8;
+        size_t public_key_len = (field_len * 2) + 1;
+        uint8_t* public_key = new uint8_t[public_key_len];
+        public_key_len = EC_POINT_point2oct(group, point_at_infinity, POINT_CONVERSION_UNCOMPRESSED,
+                                            public_key, public_key_len, nullptr /* ctx */);
+
+        /* Perform the key exchange */
+        AuthorizationSet kex_description(
+            AuthorizationSetBuilder().Authorization(TAG_EC_CURVE, curve));
+        NistCurveKeyExchange* key_exchange = NistCurveKeyExchange::GenerateKeyExchange(curve);
+        ASSERT_TRUE(key_exchange != nullptr);
+        Buffer computed_shared_secret;
+        /* It should fail */
+        ASSERT_FALSE(key_exchange->CalculateSharedKey(reinterpret_cast<const uint8_t*>(public_key),
+                                                      public_key_len, &computed_shared_secret));
+
+        /* Explicitly test that ECDH_compute_key fails when the public key is the point at infinity
+         */
+        UniquePtr<uint8_t[]> result(new uint8_t[field_len]);
+        EXPECT_EQ(-1 /* error */, ECDH_compute_key(result.get(), field_len, point_at_infinity,
+                                                   key_exchange->private_key(), nullptr /* kdf */));
+    }
+}
+
+/* Test vectors for P-256, downloaded from NIST. */
+struct NistCurveTest {
+    const keymaster_ec_curve_t curve;
+    const char* peer_public_key;
+    const char* my_private_key;
+    const char* shared_secret;
+};
+
+static const NistCurveTest kNistCurveTests[] = {
+    {
+        KM_EC_CURVE_P_256,
+        "04"  // uncompressed public key
+        "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287"
+        "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
+        // https://tools.ietf.org/html/rfc5915
+        "30770201010420"  // DER-encodeded EC private key header
+        "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"  // private key
+        "a00a06082a8648ce3d030107a144034200"  // DER-encoded curve OID,
+        "04"
+        "ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230"
+        "28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141",
+        "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b",
+    },
+    {
+        KM_EC_CURVE_P_256, "04"
+                           "809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae"
+                           "b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3",
+        // https://tools.ietf.org/html/rfc5915
+        "30770201010420"  // DER-encodeded EC private key header
+        "38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5"  // private key
+        "a00a06082a8648ce3d030107a144034200"  // DER-encoded curve OID,
+        "04"
+        "119f2f047902782ab0c9e27a54aff5eb9b964829ca99c06b02ddba95b0a3f6d0"
+        "8f52b726664cac366fc98ac7a012b2682cbd962e5acb544671d41b9445704d1d",
+        "057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67",
+    },
+    {
+        KM_EC_CURVE_P_256, "04"
+                           "df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed"
+                           "422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4",
+        // https://tools.ietf.org/html/rfc5915
+        "30770201010420"  // DER-encodeded EC private key header
+        "207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d"  // private key
+        "a00a06082a8648ce3d030107a144034200"  // DER-encoded curve OID,
+        "04"
+        "24277c33f450462dcb3d4801d57b9ced05188f16c28eda873258048cd1607e0d"
+        "c4789753e2b1f63b32ff014ec42cd6a69fac81dfe6d0d6fd4af372ae27c46f88",
+        "96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024",
+    },
+};
+
+/**
+ * Test that key exchange works with NIST test vectors.
+ */
+TEST(NistCurveKeyExchange, NistTestVectors) {
+    for (auto& test : kNistCurveTests) {
+        string private_key = hex2str(test.my_private_key);
+        string shared_secret = hex2str(test.shared_secret);
+
+        const uint8_t* private_key_data = reinterpret_cast<const uint8_t*>(private_key.data());
+        UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(
+            d2i_ECPrivateKey(nullptr, &private_key_data, private_key.size()));
+        ASSERT_TRUE(ec_key.get() && EC_KEY_check_key(ec_key.get()));
+
+        keymaster_error_t error;
+        NistCurveKeyExchange* key_exchange = new NistCurveKeyExchange(ec_key.release(), &error);
+        EXPECT_EQ(KM_ERROR_OK, error);
+        ASSERT_TRUE(key_exchange != nullptr);
+
+        Buffer computed_shared_secret;
+        string peer_public_key = hex2str(test.peer_public_key);
+        ASSERT_TRUE(key_exchange->CalculateSharedKey(
+            reinterpret_cast<const uint8_t*>(peer_public_key.data()), peer_public_key.size(),
+            &computed_shared_secret));
+        EXPECT_EQ(shared_secret.size(), computed_shared_secret.available_read());
+        EXPECT_EQ(0, memcmp(shared_secret.data(), computed_shared_secret.peek_read(),
+                            shared_secret.size()));
+
+        for (size_t i = 0; i < peer_public_key.size(); i++) {
+            // randomly flip some bits in the peer public key to make it invalid
+            peer_public_key[i] ^= 0xff;
+            ASSERT_FALSE(key_exchange->CalculateSharedKey(
+                reinterpret_cast<const uint8_t*>(peer_public_key.data()), peer_public_key.size(),
+                &computed_shared_secret));
+        }
+    }
+}
+
+}  // namespace test
+}  // namespace keymaster
diff --git a/keymaster/ocb.c b/keymaster/ocb.c
new file mode 100644
index 0000000..461fe9d
--- /dev/null
+++ b/keymaster/ocb.c
@@ -0,0 +1,1480 @@
+/*------------------------------------------------------------------------
+/ OCB Version 3 Reference Code (Optimized C)     Last modified 12-JUN-2013
+/-------------------------------------------------------------------------
+/ Copyright (c) 2013 Ted Krovetz.
+/
+/ Permission to use, copy, modify, and/or distribute this software for any
+/ purpose with or without fee is hereby granted, provided that the above
+/ copyright notice and this permission notice appear in all copies.
+/
+/ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+/ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+/ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+/ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+/ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+/ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+/ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/
+/ Phillip Rogaway holds patents relevant to OCB. See the following for
+/ his patent grant: http://www.cs.ucdavis.edu/~rogaway/ocb/grant.htm
+/
+/ Special thanks to Keegan McAllister for suggesting several good improvements
+/
+/ Comments are welcome: Ted Krovetz <ted@krovetz.net> - Dedicated to Laurel K
+/------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------- */
+/* Usage notes                                                             */
+/* ----------------------------------------------------------------------- */
+
+/* - When AE_PENDING is passed as the 'final' parameter of any function,
+/    the length parameters must be a multiple of (BPI*16).
+/  - When available, SSE or AltiVec registers are used to manipulate data.
+/    So, when on machines with these facilities, all pointers passed to
+/    any function should be 16-byte aligned.
+/  - Plaintext and ciphertext pointers may be equal (ie, plaintext gets
+/    encrypted in-place), but no other pair of pointers may be equal.
+/  - This code assumes all x86 processors have SSE2 and SSSE3 instructions
+/    when compiling under MSVC. If untrue, alter the #define.
+/  - This code is tested for C99 and recent versions of GCC and MSVC.      */
+
+/* ----------------------------------------------------------------------- */
+/* User configuration options                                              */
+/* ----------------------------------------------------------------------- */
+
+/* Set the AES key length to use and length of authentication tag to produce.
+/  Setting either to 0 requires the value be set at runtime via ae_init().
+/  Some optimizations occur for each when set to a fixed value.            */
+#define OCB_KEY_LEN 16 /* 0, 16, 24 or 32. 0 means set in ae_init */
+#define OCB_TAG_LEN 16 /* 0 to 16. 0 means set in ae_init         */
+
+/* This implementation has built-in support for multiple AES APIs. Set any
+/  one of the following to non-zero to specify which to use.               */
+#define USE_OPENSSL_AES 1   /* http://openssl.org                      */
+#define USE_REFERENCE_AES 0 /* Internet search: rijndael-alg-fst.c     */
+#define USE_AES_NI 0        /* Uses compiler's intrinsics              */
+
+/* During encryption and decryption, various "L values" are required.
+/  The L values can be precomputed during initialization (requiring extra
+/  space in ae_ctx), generated as needed (slightly slowing encryption and
+/  decryption), or some combination of the two. L_TABLE_SZ specifies how many
+/  L values to precompute. L_TABLE_SZ must be at least 3. L_TABLE_SZ*16 bytes
+/  are used for L values in ae_ctx. Plaintext and ciphertexts shorter than
+/  2^L_TABLE_SZ blocks need no L values calculated dynamically.            */
+#define L_TABLE_SZ 16
+
+/* Set L_TABLE_SZ_IS_ENOUGH non-zero iff you know that all plaintexts
+/  will be shorter than 2^(L_TABLE_SZ+4) bytes in length. This results
+/  in better performance.                                                  */
+#define L_TABLE_SZ_IS_ENOUGH 1
+
+/* ----------------------------------------------------------------------- */
+/* Includes and compiler specific definitions                              */
+/* ----------------------------------------------------------------------- */
+
+#include "ae.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Define standard sized integers                                          */
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+typedef __int64 int64_t;
+#else
+#include <stdint.h>
+#endif
+
+/* Compiler-specific intrinsics and fixes: bswap64, ntz                    */
+#if _MSC_VER
+#define inline __inline                           /* MSVC doesn't recognize "inline" in C */
+#define restrict __restrict                       /* MSVC doesn't recognize "restrict" in C */
+#define __SSE2__ (_M_IX86 || _M_AMD64 || _M_X64)  /* Assume SSE2  */
+#define __SSSE3__ (_M_IX86 || _M_AMD64 || _M_X64) /* Assume SSSE3 */
+#include <intrin.h>
+#pragma intrinsic(_byteswap_uint64, _BitScanForward, memcpy)
+#define bswap64(x) _byteswap_uint64(x)
+static inline unsigned ntz(unsigned x) {
+    _BitScanForward(&x, x);
+    return x;
+}
+#elif __GNUC__
+#define inline __inline__                   /* No "inline" in GCC ansi C mode */
+#define restrict __restrict__               /* No "restrict" in GCC ansi C mode */
+#define bswap64(x) __builtin_bswap64(x)     /* Assuming GCC 4.3+ */
+#define ntz(x) __builtin_ctz((unsigned)(x)) /* Assuming GCC 3.4+ */
+#else /* Assume some C99 features: stdint.h, inline, restrict */
+#define bswap32(x)                                                                                 \
+    ((((x)&0xff000000u) >> 24) | (((x)&0x00ff0000u) >> 8) | (((x)&0x0000ff00u) << 8) |             \
+     (((x)&0x000000ffu) << 24))
+
+static inline uint64_t bswap64(uint64_t x) {
+    union {
+        uint64_t u64;
+        uint32_t u32[2];
+    } in, out;
+    in.u64 = x;
+    out.u32[0] = bswap32(in.u32[1]);
+    out.u32[1] = bswap32(in.u32[0]);
+    return out.u64;
+}
+
+#if (L_TABLE_SZ <= 9) && (L_TABLE_SZ_IS_ENOUGH) /* < 2^13 byte texts */
+static inline unsigned ntz(unsigned x) {
+    static const unsigned char tz_table[] = {
+        0, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 6, 2, 3, 2, 4, 2, 3, 2, 5, 2,
+        3, 2, 4, 2, 3, 2, 7, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 6, 2, 3, 2,
+        4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 8, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2,
+        3, 2, 6, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2, 7, 2, 3, 2, 4, 2, 3, 2,
+        5, 2, 3, 2, 4, 2, 3, 2, 6, 2, 3, 2, 4, 2, 3, 2, 5, 2, 3, 2, 4, 2, 3, 2};
+    return tz_table[x / 4];
+}
+#else                                           /* From http://supertech.csail.mit.edu/papers/debruijn.pdf */
+static inline unsigned ntz(unsigned x) {
+    static const unsigned char tz_table[32] = {0,  1,  28, 2,  29, 14, 24, 3,  30, 22, 20,
+                                               15, 25, 17, 4,  8,  31, 27, 13, 23, 21, 19,
+                                               16, 7,  26, 12, 18, 6,  11, 5,  10, 9};
+    return tz_table[((uint32_t)((x & -x) * 0x077CB531u)) >> 27];
+}
+#endif
+#endif
+
+/* ----------------------------------------------------------------------- */
+/* Define blocks and operations -- Patch if incorrect on your compiler.    */
+/* ----------------------------------------------------------------------- */
+
+#if __SSE2__ && !KEYMASTER_CLANG_TEST_BUILD
+#include <xmmintrin.h> /* SSE instructions and _mm_malloc */
+#include <emmintrin.h> /* SSE2 instructions               */
+typedef __m128i block;
+#define xor_block(x, y) _mm_xor_si128(x, y)
+#define zero_block() _mm_setzero_si128()
+#define unequal_blocks(x, y) (_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)) != 0xffff)
+#if __SSSE3__ || USE_AES_NI
+#include <tmmintrin.h> /* SSSE3 instructions              */
+#define swap_if_le(b)                                                                              \
+    _mm_shuffle_epi8(b, _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))
+#else
+static inline block swap_if_le(block b) {
+    block a = _mm_shuffle_epi32(b, _MM_SHUFFLE(0, 1, 2, 3));
+    a = _mm_shufflehi_epi16(a, _MM_SHUFFLE(2, 3, 0, 1));
+    a = _mm_shufflelo_epi16(a, _MM_SHUFFLE(2, 3, 0, 1));
+    return _mm_xor_si128(_mm_srli_epi16(a, 8), _mm_slli_epi16(a, 8));
+}
+#endif
+static inline block gen_offset(uint64_t KtopStr[3], unsigned bot) {
+    block hi = _mm_load_si128((__m128i*)(KtopStr + 0));  /* hi = B A */
+    block lo = _mm_loadu_si128((__m128i*)(KtopStr + 1)); /* lo = C B */
+    __m128i lshift = _mm_cvtsi32_si128(bot);
+    __m128i rshift = _mm_cvtsi32_si128(64 - bot);
+    lo = _mm_xor_si128(_mm_sll_epi64(hi, lshift), _mm_srl_epi64(lo, rshift));
+#if __SSSE3__ || USE_AES_NI
+    return _mm_shuffle_epi8(lo, _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7));
+#else
+    return swap_if_le(_mm_shuffle_epi32(lo, _MM_SHUFFLE(1, 0, 3, 2)));
+#endif
+}
+static inline block double_block(block bl) {
+    const __m128i mask = _mm_set_epi32(135, 1, 1, 1);
+    __m128i tmp = _mm_srai_epi32(bl, 31);
+    tmp = _mm_and_si128(tmp, mask);
+    tmp = _mm_shuffle_epi32(tmp, _MM_SHUFFLE(2, 1, 0, 3));
+    bl = _mm_slli_epi32(bl, 1);
+    return _mm_xor_si128(bl, tmp);
+}
+#elif __ALTIVEC__
+#include <altivec.h>
+typedef vector unsigned block;
+#define xor_block(x, y) vec_xor(x, y)
+#define zero_block() vec_splat_u32(0)
+#define unequal_blocks(x, y) vec_any_ne(x, y)
+#define swap_if_le(b) (b)
+#if __PPC64__
+block gen_offset(uint64_t KtopStr[3], unsigned bot) {
+    union {
+        uint64_t u64[2];
+        block bl;
+    } rval;
+    rval.u64[0] = (KtopStr[0] << bot) | (KtopStr[1] >> (64 - bot));
+    rval.u64[1] = (KtopStr[1] << bot) | (KtopStr[2] >> (64 - bot));
+    return rval.bl;
+}
+#else
+/* Special handling: Shifts are mod 32, and no 64-bit types */
+block gen_offset(uint64_t KtopStr[3], unsigned bot) {
+    const vector unsigned k32 = {32, 32, 32, 32};
+    vector unsigned hi = *(vector unsigned*)(KtopStr + 0);
+    vector unsigned lo = *(vector unsigned*)(KtopStr + 2);
+    vector unsigned bot_vec;
+    if (bot < 32) {
+        lo = vec_sld(hi, lo, 4);
+    } else {
+        vector unsigned t = vec_sld(hi, lo, 4);
+        lo = vec_sld(hi, lo, 8);
+        hi = t;
+        bot = bot - 32;
+    }
+    if (bot == 0)
+        return hi;
+    *(unsigned*)&bot_vec = bot;
+    vector unsigned lshift = vec_splat(bot_vec, 0);
+    vector unsigned rshift = vec_sub(k32, lshift);
+    hi = vec_sl(hi, lshift);
+    lo = vec_sr(lo, rshift);
+    return vec_xor(hi, lo);
+}
+#endif
+static inline block double_block(block b) {
+    const vector unsigned char mask = {135, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+    const vector unsigned char perm = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
+    const vector unsigned char shift7 = vec_splat_u8(7);
+    const vector unsigned char shift1 = vec_splat_u8(1);
+    vector unsigned char c = (vector unsigned char)b;
+    vector unsigned char t = vec_sra(c, shift7);
+    t = vec_and(t, mask);
+    t = vec_perm(t, t, perm);
+    c = vec_sl(c, shift1);
+    return (block)vec_xor(c, t);
+}
+#elif __ARM_NEON__
+#include <arm_neon.h>
+typedef int8x16_t block; /* Yay! Endian-neutral reads! */
+#define xor_block(x, y) veorq_s8(x, y)
+#define zero_block() vdupq_n_s8(0)
+static inline int unequal_blocks(block a, block b) {
+    int64x2_t t = veorq_s64((int64x2_t)a, (int64x2_t)b);
+    return (vgetq_lane_s64(t, 0) | vgetq_lane_s64(t, 1)) != 0;
+}
+#define swap_if_le(b) (b) /* Using endian-neutral int8x16_t */
+/* KtopStr is reg correct by 64 bits, return mem correct */
+block gen_offset(uint64_t KtopStr[3], unsigned bot) {
+    const union {
+        unsigned x;
+        unsigned char endian;
+    } little = {1};
+    const int64x2_t k64 = {-64, -64};
+    uint64x2_t hi = *(uint64x2_t*)(KtopStr + 0); /* hi = A B */
+    uint64x2_t lo = *(uint64x2_t*)(KtopStr + 1); /* hi = B C */
+    int64x2_t ls = vdupq_n_s64(bot);
+    int64x2_t rs = vqaddq_s64(k64, ls);
+    block rval = (block)veorq_u64(vshlq_u64(hi, ls), vshlq_u64(lo, rs));
+    if (little.endian)
+        rval = vrev64q_s8(rval);
+    return rval;
+}
+static inline block double_block(block b) {
+    const block mask = {135, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+    block tmp = vshrq_n_s8(b, 7);
+    tmp = vandq_s8(tmp, mask);
+    tmp = vextq_s8(tmp, tmp, 1); /* Rotate high byte to end */
+    b = vshlq_n_s8(b, 1);
+    return veorq_s8(tmp, b);
+}
+#else
+typedef struct { uint64_t l, r; } block;
+static inline block xor_block(block x, block y) {
+    x.l ^= y.l;
+    x.r ^= y.r;
+    return x;
+}
+static inline block zero_block(void) {
+    const block t = {0, 0};
+    return t;
+}
+#define unequal_blocks(x, y) ((((x).l ^ (y).l) | ((x).r ^ (y).r)) != 0)
+static inline block swap_if_le(block b) {
+    const union {
+        unsigned x;
+        unsigned char endian;
+    } little = {1};
+    if (little.endian) {
+        block r;
+        r.l = bswap64(b.l);
+        r.r = bswap64(b.r);
+        return r;
+    } else
+        return b;
+}
+
+/* KtopStr is reg correct by 64 bits, return mem correct */
+block gen_offset(uint64_t KtopStr[3], unsigned bot) {
+    block rval;
+    if (bot != 0) {
+        rval.l = (KtopStr[0] << bot) | (KtopStr[1] >> (64 - bot));
+        rval.r = (KtopStr[1] << bot) | (KtopStr[2] >> (64 - bot));
+    } else {
+        rval.l = KtopStr[0];
+        rval.r = KtopStr[1];
+    }
+    return swap_if_le(rval);
+}
+
+#if __GNUC__ && __arm__
+static inline block double_block(block b) {
+    __asm__("adds %1,%1,%1\n\t"
+            "adcs %H1,%H1,%H1\n\t"
+            "adcs %0,%0,%0\n\t"
+            "adcs %H0,%H0,%H0\n\t"
+            "it cs\n\t"
+            "eorcs %1,%1,#135"
+            : "+r"(b.l), "+r"(b.r)
+            :
+            : "cc");
+    return b;
+}
+#else
+static inline block double_block(block b) {
+    uint64_t t = (uint64_t)((int64_t)b.l >> 63);
+    b.l = (b.l + b.l) ^ (b.r >> 63);
+    b.r = (b.r + b.r) ^ (t & 135);
+    return b;
+}
+#endif
+
+#endif
+
+/* ----------------------------------------------------------------------- */
+/* AES - Code uses OpenSSL API. Other implementations get mapped to it.    */
+/* ----------------------------------------------------------------------- */
+
+/*---------------*/
+#if USE_OPENSSL_AES
+/*---------------*/
+
+#include <openssl/aes.h> /* http://openssl.org/ */
+
+/* How to ECB encrypt an array of blocks, in place                         */
+static inline void AES_ecb_encrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
+    while (nblks) {
+        --nblks;
+        AES_encrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
+    }
+}
+
+static inline void AES_ecb_decrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
+    while (nblks) {
+        --nblks;
+        AES_decrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
+    }
+}
+
+#define BPI 4 /* Number of blocks in buffer per ECB call */
+
+/*-------------------*/
+#elif USE_REFERENCE_AES
+/*-------------------*/
+
+#include "rijndael-alg-fst.h" /* Barreto's Public-Domain Code */
+#if (OCB_KEY_LEN == 0)
+typedef struct {
+    uint32_t rd_key[60];
+    int rounds;
+} AES_KEY;
+#define ROUNDS(ctx) ((ctx)->rounds)
+#define AES_set_encrypt_key(x, y, z)                                                               \
+    do {                                                                                           \
+        rijndaelKeySetupEnc((z)->rd_key, x, y);                                                    \
+        (z)->rounds = y / 32 + 6;                                                                  \
+    } while (0)
+#define AES_set_decrypt_key(x, y, z)                                                               \
+    do {                                                                                           \
+        rijndaelKeySetupDec((z)->rd_key, x, y);                                                    \
+        (z)->rounds = y / 32 + 6;                                                                  \
+    } while (0)
+#else
+typedef struct { uint32_t rd_key[OCB_KEY_LEN + 28]; } AES_KEY;
+#define ROUNDS(ctx) (6 + OCB_KEY_LEN / 4)
+#define AES_set_encrypt_key(x, y, z) rijndaelKeySetupEnc((z)->rd_key, x, y)
+#define AES_set_decrypt_key(x, y, z) rijndaelKeySetupDec((z)->rd_key, x, y)
+#endif
+#define AES_encrypt(x, y, z) rijndaelEncrypt((z)->rd_key, ROUNDS(z), x, y)
+#define AES_decrypt(x, y, z) rijndaelDecrypt((z)->rd_key, ROUNDS(z), x, y)
+
+static void AES_ecb_encrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
+    while (nblks) {
+        --nblks;
+        AES_encrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
+    }
+}
+
+void AES_ecb_decrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
+    while (nblks) {
+        --nblks;
+        AES_decrypt((unsigned char*)(blks + nblks), (unsigned char*)(blks + nblks), key);
+    }
+}
+
+#define BPI 4 /* Number of blocks in buffer per ECB call */
+
+/*----------*/
+#elif USE_AES_NI
+/*----------*/
+
+#include <wmmintrin.h>
+
+#if (OCB_KEY_LEN == 0)
+typedef struct {
+    __m128i rd_key[15];
+    int rounds;
+} AES_KEY;
+#define ROUNDS(ctx) ((ctx)->rounds)
+#else
+typedef struct { __m128i rd_key[7 + OCB_KEY_LEN / 4]; } AES_KEY;
+#define ROUNDS(ctx) (6 + OCB_KEY_LEN / 4)
+#endif
+
+#define EXPAND_ASSIST(v1, v2, v3, v4, shuff_const, aes_const)                                      \
+    v2 = _mm_aeskeygenassist_si128(v4, aes_const);                                                 \
+    v3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(v3), _mm_castsi128_ps(v1), 16));         \
+    v1 = _mm_xor_si128(v1, v3);                                                                    \
+    v3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(v3), _mm_castsi128_ps(v1), 140));        \
+    v1 = _mm_xor_si128(v1, v3);                                                                    \
+    v2 = _mm_shuffle_epi32(v2, shuff_const);                                                       \
+    v1 = _mm_xor_si128(v1, v2)
+
+#define EXPAND192_STEP(idx, aes_const)                                                             \
+    EXPAND_ASSIST(x0, x1, x2, x3, 85, aes_const);                                                  \
+    x3 = _mm_xor_si128(x3, _mm_slli_si128(x3, 4));                                                 \
+    x3 = _mm_xor_si128(x3, _mm_shuffle_epi32(x0, 255));                                            \
+    kp[idx] = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(x0), 68));   \
+    kp[idx + 1] =                                                                                  \
+        _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(x0), _mm_castsi128_ps(x3), 78));          \
+    EXPAND_ASSIST(x0, x1, x2, x3, 85, (aes_const * 2));                                            \
+    x3 = _mm_xor_si128(x3, _mm_slli_si128(x3, 4));                                                 \
+    x3 = _mm_xor_si128(x3, _mm_shuffle_epi32(x0, 255));                                            \
+    kp[idx + 2] = x0;                                                                              \
+    tmp = x3
+
+static void AES_128_Key_Expansion(const unsigned char* userkey, void* key) {
+    __m128i x0, x1, x2;
+    __m128i* kp = (__m128i*)key;
+    kp[0] = x0 = _mm_loadu_si128((__m128i*)userkey);
+    x2 = _mm_setzero_si128();
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 1);
+    kp[1] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 2);
+    kp[2] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 4);
+    kp[3] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 8);
+    kp[4] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 16);
+    kp[5] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 32);
+    kp[6] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 64);
+    kp[7] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 128);
+    kp[8] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 27);
+    kp[9] = x0;
+    EXPAND_ASSIST(x0, x1, x2, x0, 255, 54);
+    kp[10] = x0;
+}
+
+static void AES_192_Key_Expansion(const unsigned char* userkey, void* key) {
+    __m128i x0, x1, x2, x3, tmp, *kp = (__m128i*)key;
+    kp[0] = x0 = _mm_loadu_si128((__m128i*)userkey);
+    tmp = x3 = _mm_loadu_si128((__m128i*)(userkey + 16));
+    x2 = _mm_setzero_si128();
+    EXPAND192_STEP(1, 1);
+    EXPAND192_STEP(4, 4);
+    EXPAND192_STEP(7, 16);
+    EXPAND192_STEP(10, 64);
+}
+
+static void AES_256_Key_Expansion(const unsigned char* userkey, void* key) {
+    __m128i x0, x1, x2, x3, *kp = (__m128i*)key;
+    kp[0] = x0 = _mm_loadu_si128((__m128i*)userkey);
+    kp[1] = x3 = _mm_loadu_si128((__m128i*)(userkey + 16));
+    x2 = _mm_setzero_si128();
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 1);
+    kp[2] = x0;
+    EXPAND_ASSIST(x3, x1, x2, x0, 170, 1);
+    kp[3] = x3;
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 2);
+    kp[4] = x0;
+    EXPAND_ASSIST(x3, x1, x2, x0, 170, 2);
+    kp[5] = x3;
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 4);
+    kp[6] = x0;
+    EXPAND_ASSIST(x3, x1, x2, x0, 170, 4);
+    kp[7] = x3;
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 8);
+    kp[8] = x0;
+    EXPAND_ASSIST(x3, x1, x2, x0, 170, 8);
+    kp[9] = x3;
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 16);
+    kp[10] = x0;
+    EXPAND_ASSIST(x3, x1, x2, x0, 170, 16);
+    kp[11] = x3;
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 32);
+    kp[12] = x0;
+    EXPAND_ASSIST(x3, x1, x2, x0, 170, 32);
+    kp[13] = x3;
+    EXPAND_ASSIST(x0, x1, x2, x3, 255, 64);
+    kp[14] = x0;
+}
+
+static int AES_set_encrypt_key(const unsigned char* userKey, const int bits, AES_KEY* key) {
+    if (bits == 128) {
+        AES_128_Key_Expansion(userKey, key);
+    } else if (bits == 192) {
+        AES_192_Key_Expansion(userKey, key);
+    } else if (bits == 256) {
+        AES_256_Key_Expansion(userKey, key);
+    }
+#if (OCB_KEY_LEN == 0)
+    key->rounds = 6 + bits / 32;
+#endif
+    return 0;
+}
+
+static void AES_set_decrypt_key_fast(AES_KEY* dkey, const AES_KEY* ekey) {
+    int j = 0;
+    int i = ROUNDS(ekey);
+#if (OCB_KEY_LEN == 0)
+    dkey->rounds = i;
+#endif
+    dkey->rd_key[i--] = ekey->rd_key[j++];
+    while (i)
+        dkey->rd_key[i--] = _mm_aesimc_si128(ekey->rd_key[j++]);
+    dkey->rd_key[i] = ekey->rd_key[j];
+}
+
+static int AES_set_decrypt_key(const unsigned char* userKey, const int bits, AES_KEY* key) {
+    AES_KEY temp_key;
+    AES_set_encrypt_key(userKey, bits, &temp_key);
+    AES_set_decrypt_key_fast(key, &temp_key);
+    return 0;
+}
+
+static inline void AES_encrypt(const unsigned char* in, unsigned char* out, const AES_KEY* key) {
+    int j, rnds = ROUNDS(key);
+    const __m128i* sched = ((__m128i*)(key->rd_key));
+    __m128i tmp = _mm_load_si128((__m128i*)in);
+    tmp = _mm_xor_si128(tmp, sched[0]);
+    for (j = 1; j < rnds; j++)
+        tmp = _mm_aesenc_si128(tmp, sched[j]);
+    tmp = _mm_aesenclast_si128(tmp, sched[j]);
+    _mm_store_si128((__m128i*)out, tmp);
+}
+
+static inline void AES_decrypt(const unsigned char* in, unsigned char* out, const AES_KEY* key) {
+    int j, rnds = ROUNDS(key);
+    const __m128i* sched = ((__m128i*)(key->rd_key));
+    __m128i tmp = _mm_load_si128((__m128i*)in);
+    tmp = _mm_xor_si128(tmp, sched[0]);
+    for (j = 1; j < rnds; j++)
+        tmp = _mm_aesdec_si128(tmp, sched[j]);
+    tmp = _mm_aesdeclast_si128(tmp, sched[j]);
+    _mm_store_si128((__m128i*)out, tmp);
+}
+
+static inline void AES_ecb_encrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
+    unsigned i, j, rnds = ROUNDS(key);
+    const __m128i* sched = ((__m128i*)(key->rd_key));
+    for (i = 0; i < nblks; ++i)
+        blks[i] = _mm_xor_si128(blks[i], sched[0]);
+    for (j = 1; j < rnds; ++j)
+        for (i = 0; i < nblks; ++i)
+            blks[i] = _mm_aesenc_si128(blks[i], sched[j]);
+    for (i = 0; i < nblks; ++i)
+        blks[i] = _mm_aesenclast_si128(blks[i], sched[j]);
+}
+
+static inline void AES_ecb_decrypt_blks(block* blks, unsigned nblks, AES_KEY* key) {
+    unsigned i, j, rnds = ROUNDS(key);
+    const __m128i* sched = ((__m128i*)(key->rd_key));
+    for (i = 0; i < nblks; ++i)
+        blks[i] = _mm_xor_si128(blks[i], sched[0]);
+    for (j = 1; j < rnds; ++j)
+        for (i = 0; i < nblks; ++i)
+            blks[i] = _mm_aesdec_si128(blks[i], sched[j]);
+    for (i = 0; i < nblks; ++i)
+        blks[i] = _mm_aesdeclast_si128(blks[i], sched[j]);
+}
+
+#define BPI 8 /* Number of blocks in buffer per ECB call   */
+/* Set to 4 for Westmere, 8 for Sandy Bridge */
+
+#endif
+
+/* ----------------------------------------------------------------------- */
+/* Define OCB context structure.                                           */
+/* ----------------------------------------------------------------------- */
+
+/*------------------------------------------------------------------------
+/ Each item in the OCB context is stored either "memory correct" or
+/ "register correct". On big-endian machines, this is identical. On
+/ little-endian machines, one must choose whether the byte-string
+/ is in the correct order when it resides in memory or in registers.
+/ It must be register correct whenever it is to be manipulated
+/ arithmetically, but must be memory correct whenever it interacts
+/ with the plaintext or ciphertext.
+/------------------------------------------------------------------------- */
+
+struct _ae_ctx {
+    block offset;        /* Memory correct               */
+    block checksum;      /* Memory correct               */
+    block Lstar;         /* Memory correct               */
+    block Ldollar;       /* Memory correct               */
+    block L[L_TABLE_SZ]; /* Memory correct               */
+    block ad_checksum;   /* Memory correct               */
+    block ad_offset;     /* Memory correct               */
+    block cached_Top;    /* Memory correct               */
+    uint64_t KtopStr[3]; /* Register correct, each item  */
+    uint32_t ad_blocks_processed;
+    uint32_t blocks_processed;
+    AES_KEY decrypt_key;
+    AES_KEY encrypt_key;
+#if (OCB_TAG_LEN == 0)
+    unsigned tag_len;
+#endif
+};
+
+/* ----------------------------------------------------------------------- */
+/* L table lookup (or on-the-fly generation)                               */
+/* ----------------------------------------------------------------------- */
+
+#if L_TABLE_SZ_IS_ENOUGH
+#define getL(_ctx, _tz) ((_ctx)->L[_tz])
+#else
+static block getL(const ae_ctx* ctx, unsigned tz) {
+    if (tz < L_TABLE_SZ)
+        return ctx->L[tz];
+    else {
+        unsigned i;
+        /* Bring L[MAX] into registers, make it register correct */
+        block rval = swap_if_le(ctx->L[L_TABLE_SZ - 1]);
+        rval = double_block(rval);
+        for (i = L_TABLE_SZ; i < tz; i++)
+            rval = double_block(rval);
+        return swap_if_le(rval); /* To memory correct */
+    }
+}
+#endif
+
+/* ----------------------------------------------------------------------- */
+/* Public functions                                                        */
+/* ----------------------------------------------------------------------- */
+
+/* 32-bit SSE2 and Altivec systems need to be forced to allocate memory
+   on 16-byte alignments. (I believe all major 64-bit systems do already.) */
+
+ae_ctx* ae_allocate(void* misc) {
+    void* p;
+    (void)misc; /* misc unused in this implementation */
+#if (__SSE2__ && !_M_X64 && !_M_AMD64 && !__amd64__)
+    p = _mm_malloc(sizeof(ae_ctx), 16);
+#elif(__ALTIVEC__ && !__PPC64__)
+    if (posix_memalign(&p, 16, sizeof(ae_ctx)) != 0)
+        p = NULL;
+#else
+    p = malloc(sizeof(ae_ctx));
+#endif
+    return (ae_ctx*)p;
+}
+
+void ae_free(ae_ctx* ctx) {
+#if (__SSE2__ && !_M_X64 && !_M_AMD64 && !__amd64__)
+    _mm_free(ctx);
+#else
+    free(ctx);
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+int ae_clear(ae_ctx* ctx) /* Zero ae_ctx and undo initialization          */
+{
+    memset(ctx, 0, sizeof(ae_ctx));
+    return AE_SUCCESS;
+}
+
+int ae_ctx_sizeof(void) {
+    return (int)sizeof(ae_ctx);
+}
+
+/* ----------------------------------------------------------------------- */
+
+int ae_init(ae_ctx* ctx, const void* key, int key_len, int nonce_len, int tag_len) {
+    unsigned i;
+    block tmp_blk;
+
+    if (nonce_len != 12)
+        return AE_NOT_SUPPORTED;
+
+/* Initialize encryption & decryption keys */
+#if (OCB_KEY_LEN > 0)
+    key_len = OCB_KEY_LEN;
+#endif
+    AES_set_encrypt_key((unsigned char*)key, key_len * 8, &ctx->encrypt_key);
+#if USE_AES_NI
+    AES_set_decrypt_key_fast(&ctx->decrypt_key, &ctx->encrypt_key);
+#else
+    AES_set_decrypt_key((unsigned char*)key, (int)(key_len * 8), &ctx->decrypt_key);
+#endif
+
+    /* Zero things that need zeroing */
+    ctx->cached_Top = ctx->ad_checksum = zero_block();
+    ctx->ad_blocks_processed = 0;
+
+    /* Compute key-dependent values */
+    AES_encrypt((unsigned char*)&ctx->cached_Top, (unsigned char*)&ctx->Lstar, &ctx->encrypt_key);
+    tmp_blk = swap_if_le(ctx->Lstar);
+    tmp_blk = double_block(tmp_blk);
+    ctx->Ldollar = swap_if_le(tmp_blk);
+    tmp_blk = double_block(tmp_blk);
+    ctx->L[0] = swap_if_le(tmp_blk);
+    for (i = 1; i < L_TABLE_SZ; i++) {
+        tmp_blk = double_block(tmp_blk);
+        ctx->L[i] = swap_if_le(tmp_blk);
+    }
+
+#if (OCB_TAG_LEN == 0)
+    ctx->tag_len = tag_len;
+#else
+    (void)tag_len; /* Suppress var not used error */
+#endif
+
+    return AE_SUCCESS;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static block gen_offset_from_nonce(ae_ctx* ctx, const void* nonce) {
+    const union {
+        unsigned x;
+        unsigned char endian;
+    } little = {1};
+    union {
+        uint32_t u32[4];
+        uint8_t u8[16];
+        block bl;
+    } tmp;
+    unsigned idx;
+
+/* Replace cached nonce Top if needed */
+#if (OCB_TAG_LEN > 0)
+    if (little.endian)
+        tmp.u32[0] = 0x01000000 + ((OCB_TAG_LEN * 8 % 128) << 1);
+    else
+        tmp.u32[0] = 0x00000001 + ((OCB_TAG_LEN * 8 % 128) << 25);
+#else
+    if (little.endian)
+        tmp.u32[0] = 0x01000000 + ((ctx->tag_len * 8 % 128) << 1);
+    else
+        tmp.u32[0] = 0x00000001 + ((ctx->tag_len * 8 % 128) << 25);
+#endif
+    tmp.u32[1] = ((uint32_t*)nonce)[0];
+    tmp.u32[2] = ((uint32_t*)nonce)[1];
+    tmp.u32[3] = ((uint32_t*)nonce)[2];
+    idx = (unsigned)(tmp.u8[15] & 0x3f);           /* Get low 6 bits of nonce  */
+    tmp.u8[15] = tmp.u8[15] & 0xc0;                /* Zero low 6 bits of nonce */
+    if (unequal_blocks(tmp.bl, ctx->cached_Top)) { /* Cached?       */
+        ctx->cached_Top = tmp.bl;                  /* Update cache, KtopStr    */
+        AES_encrypt(tmp.u8, (unsigned char*)&ctx->KtopStr, &ctx->encrypt_key);
+        if (little.endian) { /* Make Register Correct    */
+            ctx->KtopStr[0] = bswap64(ctx->KtopStr[0]);
+            ctx->KtopStr[1] = bswap64(ctx->KtopStr[1]);
+        }
+        ctx->KtopStr[2] = ctx->KtopStr[0] ^ (ctx->KtopStr[0] << 8) ^ (ctx->KtopStr[1] >> 56);
+    }
+    return gen_offset(ctx->KtopStr, idx);
+}
+
+static void process_ad(ae_ctx* ctx, const void* ad, int ad_len, int final) {
+    union {
+        uint32_t u32[4];
+        uint8_t u8[16];
+        block bl;
+    } tmp;
+    block ad_offset, ad_checksum;
+    const block* adp = (block*)ad;
+    unsigned i, k, tz, remaining;
+
+    ad_offset = ctx->ad_offset;
+    ad_checksum = ctx->ad_checksum;
+    i = ad_len / (BPI * 16);
+    if (i) {
+        unsigned ad_block_num = ctx->ad_blocks_processed;
+        do {
+            block ta[BPI], oa[BPI];
+            ad_block_num += BPI;
+            tz = ntz(ad_block_num);
+            oa[0] = xor_block(ad_offset, ctx->L[0]);
+            ta[0] = xor_block(oa[0], adp[0]);
+            oa[1] = xor_block(oa[0], ctx->L[1]);
+            ta[1] = xor_block(oa[1], adp[1]);
+            oa[2] = xor_block(ad_offset, ctx->L[1]);
+            ta[2] = xor_block(oa[2], adp[2]);
+#if BPI == 4
+            ad_offset = xor_block(oa[2], getL(ctx, tz));
+            ta[3] = xor_block(ad_offset, adp[3]);
+#elif BPI == 8
+            oa[3] = xor_block(oa[2], ctx->L[2]);
+            ta[3] = xor_block(oa[3], adp[3]);
+            oa[4] = xor_block(oa[1], ctx->L[2]);
+            ta[4] = xor_block(oa[4], adp[4]);
+            oa[5] = xor_block(oa[0], ctx->L[2]);
+            ta[5] = xor_block(oa[5], adp[5]);
+            oa[6] = xor_block(ad_offset, ctx->L[2]);
+            ta[6] = xor_block(oa[6], adp[6]);
+            ad_offset = xor_block(oa[6], getL(ctx, tz));
+            ta[7] = xor_block(ad_offset, adp[7]);
+#endif
+            AES_ecb_encrypt_blks(ta, BPI, &ctx->encrypt_key);
+            ad_checksum = xor_block(ad_checksum, ta[0]);
+            ad_checksum = xor_block(ad_checksum, ta[1]);
+            ad_checksum = xor_block(ad_checksum, ta[2]);
+            ad_checksum = xor_block(ad_checksum, ta[3]);
+#if (BPI == 8)
+            ad_checksum = xor_block(ad_checksum, ta[4]);
+            ad_checksum = xor_block(ad_checksum, ta[5]);
+            ad_checksum = xor_block(ad_checksum, ta[6]);
+            ad_checksum = xor_block(ad_checksum, ta[7]);
+#endif
+            adp += BPI;
+        } while (--i);
+        ctx->ad_blocks_processed = ad_block_num;
+        ctx->ad_offset = ad_offset;
+        ctx->ad_checksum = ad_checksum;
+    }
+
+    if (final) {
+        block ta[BPI];
+
+        /* Process remaining associated data, compute its tag contribution */
+        remaining = ((unsigned)ad_len) % (BPI * 16);
+        if (remaining) {
+            k = 0;
+#if (BPI == 8)
+            if (remaining >= 64) {
+                tmp.bl = xor_block(ad_offset, ctx->L[0]);
+                ta[0] = xor_block(tmp.bl, adp[0]);
+                tmp.bl = xor_block(tmp.bl, ctx->L[1]);
+                ta[1] = xor_block(tmp.bl, adp[1]);
+                ad_offset = xor_block(ad_offset, ctx->L[1]);
+                ta[2] = xor_block(ad_offset, adp[2]);
+                ad_offset = xor_block(ad_offset, ctx->L[2]);
+                ta[3] = xor_block(ad_offset, adp[3]);
+                remaining -= 64;
+                k = 4;
+            }
+#endif
+            if (remaining >= 32) {
+                ad_offset = xor_block(ad_offset, ctx->L[0]);
+                ta[k] = xor_block(ad_offset, adp[k]);
+                ad_offset = xor_block(ad_offset, getL(ctx, ntz(k + 2)));
+                ta[k + 1] = xor_block(ad_offset, adp[k + 1]);
+                remaining -= 32;
+                k += 2;
+            }
+            if (remaining >= 16) {
+                ad_offset = xor_block(ad_offset, ctx->L[0]);
+                ta[k] = xor_block(ad_offset, adp[k]);
+                remaining = remaining - 16;
+                ++k;
+            }
+            if (remaining) {
+                ad_offset = xor_block(ad_offset, ctx->Lstar);
+                tmp.bl = zero_block();
+                memcpy(tmp.u8, adp + k, remaining);
+                tmp.u8[remaining] = (unsigned char)0x80u;
+                ta[k] = xor_block(ad_offset, tmp.bl);
+                ++k;
+            }
+            AES_ecb_encrypt_blks(ta, k, &ctx->encrypt_key);
+            switch (k) {
+#if (BPI == 8)
+            case 8:
+                ad_checksum = xor_block(ad_checksum, ta[7]);
+            case 7:
+                ad_checksum = xor_block(ad_checksum, ta[6]);
+            case 6:
+                ad_checksum = xor_block(ad_checksum, ta[5]);
+            case 5:
+                ad_checksum = xor_block(ad_checksum, ta[4]);
+#endif
+            case 4:
+                ad_checksum = xor_block(ad_checksum, ta[3]);
+            case 3:
+                ad_checksum = xor_block(ad_checksum, ta[2]);
+            case 2:
+                ad_checksum = xor_block(ad_checksum, ta[1]);
+            case 1:
+                ad_checksum = xor_block(ad_checksum, ta[0]);
+            }
+            ctx->ad_checksum = ad_checksum;
+        }
+    }
+}
+
+/* ----------------------------------------------------------------------- */
+
+int ae_encrypt(ae_ctx* ctx, const void* nonce, const void* pt, int pt_len, const void* ad,
+               int ad_len, void* ct, void* tag, int final) {
+    union {
+        uint32_t u32[4];
+        uint8_t u8[16];
+        block bl;
+    } tmp;
+    block offset, checksum;
+    unsigned i, k;
+    block* ctp = (block*)ct;
+    const block* ptp = (block*)pt;
+
+    /* Non-null nonce means start of new message, init per-message values */
+    if (nonce) {
+        ctx->offset = gen_offset_from_nonce(ctx, nonce);
+        ctx->ad_offset = ctx->checksum = zero_block();
+        ctx->ad_blocks_processed = ctx->blocks_processed = 0;
+        if (ad_len >= 0)
+            ctx->ad_checksum = zero_block();
+    }
+
+    /* Process associated data */
+    if (ad_len > 0)
+        process_ad(ctx, ad, ad_len, final);
+
+    /* Encrypt plaintext data BPI blocks at a time */
+    offset = ctx->offset;
+    checksum = ctx->checksum;
+    i = pt_len / (BPI * 16);
+    if (i) {
+        block oa[BPI];
+        unsigned block_num = ctx->blocks_processed;
+        oa[BPI - 1] = offset;
+        do {
+            block ta[BPI];
+            block_num += BPI;
+            oa[0] = xor_block(oa[BPI - 1], ctx->L[0]);
+            ta[0] = xor_block(oa[0], ptp[0]);
+            checksum = xor_block(checksum, ptp[0]);
+            oa[1] = xor_block(oa[0], ctx->L[1]);
+            ta[1] = xor_block(oa[1], ptp[1]);
+            checksum = xor_block(checksum, ptp[1]);
+            oa[2] = xor_block(oa[1], ctx->L[0]);
+            ta[2] = xor_block(oa[2], ptp[2]);
+            checksum = xor_block(checksum, ptp[2]);
+#if BPI == 4
+            oa[3] = xor_block(oa[2], getL(ctx, ntz(block_num)));
+            ta[3] = xor_block(oa[3], ptp[3]);
+            checksum = xor_block(checksum, ptp[3]);
+#elif BPI == 8
+            oa[3] = xor_block(oa[2], ctx->L[2]);
+            ta[3] = xor_block(oa[3], ptp[3]);
+            checksum = xor_block(checksum, ptp[3]);
+            oa[4] = xor_block(oa[1], ctx->L[2]);
+            ta[4] = xor_block(oa[4], ptp[4]);
+            checksum = xor_block(checksum, ptp[4]);
+            oa[5] = xor_block(oa[0], ctx->L[2]);
+            ta[5] = xor_block(oa[5], ptp[5]);
+            checksum = xor_block(checksum, ptp[5]);
+            oa[6] = xor_block(oa[7], ctx->L[2]);
+            ta[6] = xor_block(oa[6], ptp[6]);
+            checksum = xor_block(checksum, ptp[6]);
+            oa[7] = xor_block(oa[6], getL(ctx, ntz(block_num)));
+            ta[7] = xor_block(oa[7], ptp[7]);
+            checksum = xor_block(checksum, ptp[7]);
+#endif
+            AES_ecb_encrypt_blks(ta, BPI, &ctx->encrypt_key);
+            ctp[0] = xor_block(ta[0], oa[0]);
+            ctp[1] = xor_block(ta[1], oa[1]);
+            ctp[2] = xor_block(ta[2], oa[2]);
+            ctp[3] = xor_block(ta[3], oa[3]);
+#if (BPI == 8)
+            ctp[4] = xor_block(ta[4], oa[4]);
+            ctp[5] = xor_block(ta[5], oa[5]);
+            ctp[6] = xor_block(ta[6], oa[6]);
+            ctp[7] = xor_block(ta[7], oa[7]);
+#endif
+            ptp += BPI;
+            ctp += BPI;
+        } while (--i);
+        ctx->offset = offset = oa[BPI - 1];
+        ctx->blocks_processed = block_num;
+        ctx->checksum = checksum;
+    }
+
+    if (final) {
+        block ta[BPI + 1], oa[BPI];
+
+        /* Process remaining plaintext and compute its tag contribution    */
+        unsigned remaining = ((unsigned)pt_len) % (BPI * 16);
+        k = 0; /* How many blocks in ta[] need ECBing */
+        if (remaining) {
+#if (BPI == 8)
+            if (remaining >= 64) {
+                oa[0] = xor_block(offset, ctx->L[0]);
+                ta[0] = xor_block(oa[0], ptp[0]);
+                checksum = xor_block(checksum, ptp[0]);
+                oa[1] = xor_block(oa[0], ctx->L[1]);
+                ta[1] = xor_block(oa[1], ptp[1]);
+                checksum = xor_block(checksum, ptp[1]);
+                oa[2] = xor_block(oa[1], ctx->L[0]);
+                ta[2] = xor_block(oa[2], ptp[2]);
+                checksum = xor_block(checksum, ptp[2]);
+                offset = oa[3] = xor_block(oa[2], ctx->L[2]);
+                ta[3] = xor_block(offset, ptp[3]);
+                checksum = xor_block(checksum, ptp[3]);
+                remaining -= 64;
+                k = 4;
+            }
+#endif
+            if (remaining >= 32) {
+                oa[k] = xor_block(offset, ctx->L[0]);
+                ta[k] = xor_block(oa[k], ptp[k]);
+                checksum = xor_block(checksum, ptp[k]);
+                offset = oa[k + 1] = xor_block(oa[k], ctx->L[1]);
+                ta[k + 1] = xor_block(offset, ptp[k + 1]);
+                checksum = xor_block(checksum, ptp[k + 1]);
+                remaining -= 32;
+                k += 2;
+            }
+            if (remaining >= 16) {
+                offset = oa[k] = xor_block(offset, ctx->L[0]);
+                ta[k] = xor_block(offset, ptp[k]);
+                checksum = xor_block(checksum, ptp[k]);
+                remaining -= 16;
+                ++k;
+            }
+            if (remaining) {
+                tmp.bl = zero_block();
+                memcpy(tmp.u8, ptp + k, remaining);
+                tmp.u8[remaining] = (unsigned char)0x80u;
+                checksum = xor_block(checksum, tmp.bl);
+                ta[k] = offset = xor_block(offset, ctx->Lstar);
+                ++k;
+            }
+        }
+        offset = xor_block(offset, ctx->Ldollar); /* Part of tag gen */
+        ta[k] = xor_block(offset, checksum);      /* Part of tag gen */
+        AES_ecb_encrypt_blks(ta, k + 1, &ctx->encrypt_key);
+        offset = xor_block(ta[k], ctx->ad_checksum); /* Part of tag gen */
+        if (remaining) {
+            --k;
+            tmp.bl = xor_block(tmp.bl, ta[k]);
+            memcpy(ctp + k, tmp.u8, remaining);
+        }
+        switch (k) {
+#if (BPI == 8)
+        case 7:
+            ctp[6] = xor_block(ta[6], oa[6]);
+        case 6:
+            ctp[5] = xor_block(ta[5], oa[5]);
+        case 5:
+            ctp[4] = xor_block(ta[4], oa[4]);
+        case 4:
+            ctp[3] = xor_block(ta[3], oa[3]);
+#endif
+        case 3:
+            ctp[2] = xor_block(ta[2], oa[2]);
+        case 2:
+            ctp[1] = xor_block(ta[1], oa[1]);
+        case 1:
+            ctp[0] = xor_block(ta[0], oa[0]);
+        }
+
+        /* Tag is placed at the correct location
+         */
+        if (tag) {
+#if (OCB_TAG_LEN == 16)
+            *(block*)tag = offset;
+#elif(OCB_TAG_LEN > 0)
+            memcpy((char*)tag, &offset, OCB_TAG_LEN);
+#else
+            memcpy((char*)tag, &offset, ctx->tag_len);
+#endif
+        } else {
+#if (OCB_TAG_LEN > 0)
+            memcpy((char*)ct + pt_len, &offset, OCB_TAG_LEN);
+            pt_len += OCB_TAG_LEN;
+#else
+            memcpy((char*)ct + pt_len, &offset, ctx->tag_len);
+            pt_len += ctx->tag_len;
+#endif
+        }
+    }
+    return (int)pt_len;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* Compare two regions of memory, taking a constant amount of time for a
+   given buffer size -- under certain assumptions about the compiler
+   and machine, of course.
+
+   Use this to avoid timing side-channel attacks.
+
+   Returns 0 for memory regions with equal contents; non-zero otherwise. */
+static int constant_time_memcmp(const void* av, const void* bv, size_t n) {
+    const uint8_t* a = (const uint8_t*)av;
+    const uint8_t* b = (const uint8_t*)bv;
+    uint8_t result = 0;
+    size_t i;
+
+    for (i = 0; i < n; i++) {
+        result |= *a ^ *b;
+        a++;
+        b++;
+    }
+
+    return (int)result;
+}
+
+int ae_decrypt(ae_ctx* ctx, const void* nonce, const void* ct, int ct_len, const void* ad,
+               int ad_len, void* pt, const void* tag, int final) {
+    union {
+        uint32_t u32[4];
+        uint8_t u8[16];
+        block bl;
+    } tmp;
+    block offset, checksum;
+    unsigned i, k;
+    block* ctp = (block*)ct;
+    block* ptp = (block*)pt;
+
+    /* Reduce ct_len tag bundled in ct */
+    if ((final) && (!tag))
+#if (OCB_TAG_LEN > 0)
+        ct_len -= OCB_TAG_LEN;
+#else
+        ct_len -= ctx->tag_len;
+#endif
+
+    /* Non-null nonce means start of new message, init per-message values */
+    if (nonce) {
+        ctx->offset = gen_offset_from_nonce(ctx, nonce);
+        ctx->ad_offset = ctx->checksum = zero_block();
+        ctx->ad_blocks_processed = ctx->blocks_processed = 0;
+        if (ad_len >= 0)
+            ctx->ad_checksum = zero_block();
+    }
+
+    /* Process associated data */
+    if (ad_len > 0)
+        process_ad(ctx, ad, ad_len, final);
+
+    /* Encrypt plaintext data BPI blocks at a time */
+    offset = ctx->offset;
+    checksum = ctx->checksum;
+    i = ct_len / (BPI * 16);
+    if (i) {
+        block oa[BPI];
+        unsigned block_num = ctx->blocks_processed;
+        oa[BPI - 1] = offset;
+        do {
+            block ta[BPI];
+            block_num += BPI;
+            oa[0] = xor_block(oa[BPI - 1], ctx->L[0]);
+            ta[0] = xor_block(oa[0], ctp[0]);
+            oa[1] = xor_block(oa[0], ctx->L[1]);
+            ta[1] = xor_block(oa[1], ctp[1]);
+            oa[2] = xor_block(oa[1], ctx->L[0]);
+            ta[2] = xor_block(oa[2], ctp[2]);
+#if BPI == 4
+            oa[3] = xor_block(oa[2], getL(ctx, ntz(block_num)));
+            ta[3] = xor_block(oa[3], ctp[3]);
+#elif BPI == 8
+            oa[3] = xor_block(oa[2], ctx->L[2]);
+            ta[3] = xor_block(oa[3], ctp[3]);
+            oa[4] = xor_block(oa[1], ctx->L[2]);
+            ta[4] = xor_block(oa[4], ctp[4]);
+            oa[5] = xor_block(oa[0], ctx->L[2]);
+            ta[5] = xor_block(oa[5], ctp[5]);
+            oa[6] = xor_block(oa[7], ctx->L[2]);
+            ta[6] = xor_block(oa[6], ctp[6]);
+            oa[7] = xor_block(oa[6], getL(ctx, ntz(block_num)));
+            ta[7] = xor_block(oa[7], ctp[7]);
+#endif
+            AES_ecb_decrypt_blks(ta, BPI, &ctx->decrypt_key);
+            ptp[0] = xor_block(ta[0], oa[0]);
+            checksum = xor_block(checksum, ptp[0]);
+            ptp[1] = xor_block(ta[1], oa[1]);
+            checksum = xor_block(checksum, ptp[1]);
+            ptp[2] = xor_block(ta[2], oa[2]);
+            checksum = xor_block(checksum, ptp[2]);
+            ptp[3] = xor_block(ta[3], oa[3]);
+            checksum = xor_block(checksum, ptp[3]);
+#if (BPI == 8)
+            ptp[4] = xor_block(ta[4], oa[4]);
+            checksum = xor_block(checksum, ptp[4]);
+            ptp[5] = xor_block(ta[5], oa[5]);
+            checksum = xor_block(checksum, ptp[5]);
+            ptp[6] = xor_block(ta[6], oa[6]);
+            checksum = xor_block(checksum, ptp[6]);
+            ptp[7] = xor_block(ta[7], oa[7]);
+            checksum = xor_block(checksum, ptp[7]);
+#endif
+            ptp += BPI;
+            ctp += BPI;
+        } while (--i);
+        ctx->offset = offset = oa[BPI - 1];
+        ctx->blocks_processed = block_num;
+        ctx->checksum = checksum;
+    }
+
+    if (final) {
+        block ta[BPI + 1], oa[BPI];
+
+        /* Process remaining plaintext and compute its tag contribution    */
+        unsigned remaining = ((unsigned)ct_len) % (BPI * 16);
+        k = 0; /* How many blocks in ta[] need ECBing */
+        if (remaining) {
+#if (BPI == 8)
+            if (remaining >= 64) {
+                oa[0] = xor_block(offset, ctx->L[0]);
+                ta[0] = xor_block(oa[0], ctp[0]);
+                oa[1] = xor_block(oa[0], ctx->L[1]);
+                ta[1] = xor_block(oa[1], ctp[1]);
+                oa[2] = xor_block(oa[1], ctx->L[0]);
+                ta[2] = xor_block(oa[2], ctp[2]);
+                offset = oa[3] = xor_block(oa[2], ctx->L[2]);
+                ta[3] = xor_block(offset, ctp[3]);
+                remaining -= 64;
+                k = 4;
+            }
+#endif
+            if (remaining >= 32) {
+                oa[k] = xor_block(offset, ctx->L[0]);
+                ta[k] = xor_block(oa[k], ctp[k]);
+                offset = oa[k + 1] = xor_block(oa[k], ctx->L[1]);
+                ta[k + 1] = xor_block(offset, ctp[k + 1]);
+                remaining -= 32;
+                k += 2;
+            }
+            if (remaining >= 16) {
+                offset = oa[k] = xor_block(offset, ctx->L[0]);
+                ta[k] = xor_block(offset, ctp[k]);
+                remaining -= 16;
+                ++k;
+            }
+            if (remaining) {
+                block pad;
+                offset = xor_block(offset, ctx->Lstar);
+                AES_encrypt((unsigned char*)&offset, tmp.u8, &ctx->encrypt_key);
+                pad = tmp.bl;
+                memcpy(tmp.u8, ctp + k, remaining);
+                tmp.bl = xor_block(tmp.bl, pad);
+                tmp.u8[remaining] = (unsigned char)0x80u;
+                memcpy(ptp + k, tmp.u8, remaining);
+                checksum = xor_block(checksum, tmp.bl);
+            }
+        }
+        AES_ecb_decrypt_blks(ta, k, &ctx->decrypt_key);
+        switch (k) {
+#if (BPI == 8)
+        case 7:
+            ptp[6] = xor_block(ta[6], oa[6]);
+            checksum = xor_block(checksum, ptp[6]);
+        case 6:
+            ptp[5] = xor_block(ta[5], oa[5]);
+            checksum = xor_block(checksum, ptp[5]);
+        case 5:
+            ptp[4] = xor_block(ta[4], oa[4]);
+            checksum = xor_block(checksum, ptp[4]);
+        case 4:
+            ptp[3] = xor_block(ta[3], oa[3]);
+            checksum = xor_block(checksum, ptp[3]);
+#endif
+        case 3:
+            ptp[2] = xor_block(ta[2], oa[2]);
+            checksum = xor_block(checksum, ptp[2]);
+        case 2:
+            ptp[1] = xor_block(ta[1], oa[1]);
+            checksum = xor_block(checksum, ptp[1]);
+        case 1:
+            ptp[0] = xor_block(ta[0], oa[0]);
+            checksum = xor_block(checksum, ptp[0]);
+        }
+
+        /* Calculate expected tag */
+        offset = xor_block(offset, ctx->Ldollar);
+        tmp.bl = xor_block(offset, checksum);
+        AES_encrypt(tmp.u8, tmp.u8, &ctx->encrypt_key);
+        tmp.bl = xor_block(tmp.bl, ctx->ad_checksum); /* Full tag */
+
+        /* Compare with proposed tag, change ct_len if invalid */
+        if ((OCB_TAG_LEN == 16) && tag) {
+            if (unequal_blocks(tmp.bl, *(block*)tag))
+                ct_len = AE_INVALID;
+        } else {
+#if (OCB_TAG_LEN > 0)
+            int len = OCB_TAG_LEN;
+#else
+            int len = ctx->tag_len;
+#endif
+            if (tag) {
+                if (constant_time_memcmp(tag, tmp.u8, len) != 0)
+                    ct_len = AE_INVALID;
+            } else {
+                if (constant_time_memcmp((char*)ct + ct_len, tmp.u8, len) != 0)
+                    ct_len = AE_INVALID;
+            }
+        }
+    }
+    return ct_len;
+}
+
+/* ----------------------------------------------------------------------- */
+/* Simple test program                                                     */
+/* ----------------------------------------------------------------------- */
+
+#if 0
+
+#include <stdio.h>
+#include <time.h>
+
+#if __GNUC__
+#define ALIGN(n) __attribute__((aligned(n)))
+#elif _MSC_VER
+#define ALIGN(n) __declspec(align(n))
+#else /* Not GNU/Microsoft: delete alignment uses.     */
+#define ALIGN(n)
+#endif
+
+static void pbuf(void *p, unsigned len, const void *s)
+{
+    unsigned i;
+    if (s)
+        printf("%s", (char *)s);
+    for (i = 0; i < len; i++)
+        printf("%02X", (unsigned)(((unsigned char *)p)[i]));
+    printf("\n");
+}
+
+static void vectors(ae_ctx *ctx, int len)
+{
+    ALIGN(16) char pt[128];
+    ALIGN(16) char ct[144];
+    ALIGN(16) char nonce[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+    int i;
+    for (i=0; i < 128; i++) pt[i] = i;
+    i = ae_encrypt(ctx,nonce,pt,len,pt,len,ct,NULL,AE_FINALIZE);
+    printf("P=%d,A=%d: ",len,len); pbuf(ct, i, NULL);
+    i = ae_encrypt(ctx,nonce,pt,0,pt,len,ct,NULL,AE_FINALIZE);
+    printf("P=%d,A=%d: ",0,len); pbuf(ct, i, NULL);
+    i = ae_encrypt(ctx,nonce,pt,len,pt,0,ct,NULL,AE_FINALIZE);
+    printf("P=%d,A=%d: ",len,0); pbuf(ct, i, NULL);
+}
+
+void validate()
+{
+    ALIGN(16) char pt[1024];
+    ALIGN(16) char ct[1024];
+    ALIGN(16) char tag[16];
+    ALIGN(16) char nonce[12] = {0,};
+    ALIGN(16) char key[32] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
+    ae_ctx ctx;
+    char *val_buf, *next;
+    int i, len;
+
+    val_buf = (char *)malloc(22400 + 16);
+    next = val_buf = (char *)(((size_t)val_buf + 16) & ~((size_t)15));
+
+    if (0) {
+		ae_init(&ctx, key, 16, 12, 16);
+		/* pbuf(&ctx, sizeof(ctx), "CTX: "); */
+		vectors(&ctx,0);
+		vectors(&ctx,8);
+		vectors(&ctx,16);
+		vectors(&ctx,24);
+		vectors(&ctx,32);
+		vectors(&ctx,40);
+    }
+
+    memset(key,0,32);
+    memset(pt,0,128);
+    ae_init(&ctx, key, OCB_KEY_LEN, 12, OCB_TAG_LEN);
+
+    /* RFC Vector test */
+    for (i = 0; i < 128; i++) {
+        int first = ((i/3)/(BPI*16))*(BPI*16);
+        int second = first;
+        int third = i - (first + second);
+
+        nonce[11] = i;
+
+        if (0) {
+            ae_encrypt(&ctx,nonce,pt,i,pt,i,ct,NULL,AE_FINALIZE);
+            memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
+            next = next+i+OCB_TAG_LEN;
+
+            ae_encrypt(&ctx,nonce,pt,i,pt,0,ct,NULL,AE_FINALIZE);
+            memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
+            next = next+i+OCB_TAG_LEN;
+
+            ae_encrypt(&ctx,nonce,pt,0,pt,i,ct,NULL,AE_FINALIZE);
+            memcpy(next,ct,OCB_TAG_LEN);
+            next = next+OCB_TAG_LEN;
+        } else {
+            ae_encrypt(&ctx,nonce,pt,first,pt,first,ct,NULL,AE_PENDING);
+            ae_encrypt(&ctx,NULL,pt+first,second,pt+first,second,ct+first,NULL,AE_PENDING);
+            ae_encrypt(&ctx,NULL,pt+first+second,third,pt+first+second,third,ct+first+second,NULL,AE_FINALIZE);
+            memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
+            next = next+i+OCB_TAG_LEN;
+
+            ae_encrypt(&ctx,nonce,pt,first,pt,0,ct,NULL,AE_PENDING);
+            ae_encrypt(&ctx,NULL,pt+first,second,pt,0,ct+first,NULL,AE_PENDING);
+            ae_encrypt(&ctx,NULL,pt+first+second,third,pt,0,ct+first+second,NULL,AE_FINALIZE);
+            memcpy(next,ct,(size_t)i+OCB_TAG_LEN);
+            next = next+i+OCB_TAG_LEN;
+
+            ae_encrypt(&ctx,nonce,pt,0,pt,first,ct,NULL,AE_PENDING);
+            ae_encrypt(&ctx,NULL,pt,0,pt+first,second,ct,NULL,AE_PENDING);
+            ae_encrypt(&ctx,NULL,pt,0,pt+first+second,third,ct,NULL,AE_FINALIZE);
+            memcpy(next,ct,OCB_TAG_LEN);
+            next = next+OCB_TAG_LEN;
+        }
+
+    }
+    nonce[11] = 0;
+    ae_encrypt(&ctx,nonce,NULL,0,val_buf,next-val_buf,ct,tag,AE_FINALIZE);
+    pbuf(tag,OCB_TAG_LEN,0);
+
+
+    /* Encrypt/Decrypt test */
+    for (i = 0; i < 128; i++) {
+        int first = ((i/3)/(BPI*16))*(BPI*16);
+        int second = first;
+        int third = i - (first + second);
+
+        nonce[11] = i%128;
+
+        if (1) {
+            len = ae_encrypt(&ctx,nonce,val_buf,i,val_buf,i,ct,tag,AE_FINALIZE);
+            len = ae_encrypt(&ctx,nonce,val_buf,i,val_buf,-1,ct,tag,AE_FINALIZE);
+            len = ae_decrypt(&ctx,nonce,ct,len,val_buf,-1,pt,tag,AE_FINALIZE);
+            if (len == -1) { printf("Authentication error: %d\n", i); return; }
+            if (len != i) { printf("Length error: %d\n", i); return; }
+            if (memcmp(val_buf,pt,i)) { printf("Decrypt error: %d\n", i); return; }
+        } else {
+            len = ae_encrypt(&ctx,nonce,val_buf,i,val_buf,i,ct,NULL,AE_FINALIZE);
+            ae_decrypt(&ctx,nonce,ct,first,val_buf,first,pt,NULL,AE_PENDING);
+            ae_decrypt(&ctx,NULL,ct+first,second,val_buf+first,second,pt+first,NULL,AE_PENDING);
+            len = ae_decrypt(&ctx,NULL,ct+first+second,len-(first+second),val_buf+first+second,third,pt+first+second,NULL,AE_FINALIZE);
+            if (len == -1) { printf("Authentication error: %d\n", i); return; }
+            if (memcmp(val_buf,pt,i)) { printf("Decrypt error: %d\n", i); return; }
+        }
+
+    }
+    printf("Decrypt: PASS\n");
+}
+
+int main()
+{
+    validate();
+    return 0;
+}
+#endif
+
+#if USE_AES_NI
+char infoString[] = "OCB3 (AES-NI)";
+#elif USE_REFERENCE_AES
+char infoString[] = "OCB3 (Reference)";
+#elif USE_OPENSSL_AES
+char infoString[] = "OCB3 (OpenSSL)";
+#endif
diff --git a/keymaster/ocb_utils.cpp b/keymaster/ocb_utils.cpp
new file mode 100644
index 0000000..7038da0
--- /dev/null
+++ b/keymaster/ocb_utils.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 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.
+ */
+
+#include "ocb_utils.h"
+
+#include <assert.h>
+
+#include <new>
+
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/android_keymaster_utils.h>
+
+#include "openssl_err.h"
+
+namespace keymaster {
+
+class AeCtx {
+  public:
+    AeCtx() : ctx_(ae_allocate(NULL)) {}
+    ~AeCtx() {
+        ae_clear(ctx_);
+        ae_free(ctx_);
+    }
+
+    ae_ctx* get() { return ctx_; }
+
+  private:
+    ae_ctx* ctx_;
+};
+
+static keymaster_error_t BuildDerivationData(const AuthorizationSet& hw_enforced,
+                                             const AuthorizationSet& sw_enforced,
+                                             const AuthorizationSet& hidden,
+                                             UniquePtr<uint8_t[]>* derivation_data,
+                                             size_t* derivation_data_length) {
+    *derivation_data_length =
+        hidden.SerializedSize() + hw_enforced.SerializedSize() + sw_enforced.SerializedSize();
+    derivation_data->reset(new (std::nothrow) uint8_t[*derivation_data_length]);
+    if (!derivation_data->get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    uint8_t* buf = derivation_data->get();
+    uint8_t* end = derivation_data->get() + *derivation_data_length;
+    buf = hidden.Serialize(buf, end);
+    buf = hw_enforced.Serialize(buf, end);
+    buf = sw_enforced.Serialize(buf, end);
+
+    return KM_ERROR_OK;
+}
+
+static keymaster_error_t InitializeKeyWrappingContext(const AuthorizationSet& hw_enforced,
+                                                      const AuthorizationSet& sw_enforced,
+                                                      const AuthorizationSet& hidden,
+                                                      const KeymasterKeyBlob& master_key,
+                                                      AeCtx* ctx) {
+    size_t derivation_data_length;
+    UniquePtr<uint8_t[]> derivation_data;
+    keymaster_error_t error = BuildDerivationData(hw_enforced, sw_enforced, hidden,
+                                                  &derivation_data, &derivation_data_length);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    SHA256_CTX sha256_ctx;
+    UniquePtr<uint8_t[]> hash_buf(new (std::nothrow) uint8_t[SHA256_DIGEST_LENGTH]);
+    if (!hash_buf.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    Eraser hash_eraser(hash_buf.get(), SHA256_DIGEST_LENGTH);
+    UniquePtr<uint8_t[]> derived_key(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]);
+    if (!derived_key.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    Eraser derived_key_eraser(derived_key.get(), AES_BLOCK_SIZE);
+
+    if (!ctx->get() || !hash_buf.get() || !derived_key.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    // Hash derivation data.
+    Eraser sha256_ctx_eraser(sha256_ctx);
+    SHA256_Init(&sha256_ctx);
+    SHA256_Update(&sha256_ctx, derivation_data.get(), derivation_data_length);
+    SHA256_Final(hash_buf.get(), &sha256_ctx);
+
+    // Encrypt hash with master key to build derived key.
+    AES_KEY aes_key;
+    Eraser aes_key_eraser(AES_KEY);
+    if (0 !=
+        AES_set_encrypt_key(master_key.key_material, master_key.key_material_size * 8, &aes_key))
+        return TranslateLastOpenSslError();
+
+    AES_encrypt(hash_buf.get(), derived_key.get(), &aes_key);
+
+    // Set up AES OCB context using derived key.
+    if (ae_init(ctx->get(), derived_key.get(), AES_BLOCK_SIZE /* key length */, OCB_NONCE_LENGTH,
+                OCB_TAG_LENGTH) != AE_SUCCESS) {
+        memset_s(ctx->get(), 0, ae_ctx_sizeof());
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t OcbEncryptKey(const AuthorizationSet& hw_enforced,
+                                const AuthorizationSet& sw_enforced, const AuthorizationSet& hidden,
+                                const KeymasterKeyBlob& master_key,
+                                const KeymasterKeyBlob& plaintext, const Buffer& nonce,
+                                KeymasterKeyBlob* ciphertext, Buffer* tag) {
+    assert(ciphertext && tag);
+
+    if (nonce.available_read() != OCB_NONCE_LENGTH)
+        return KM_ERROR_INVALID_ARGUMENT;
+
+    AeCtx ctx;
+    if (!ctx.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    keymaster_error_t error =
+        InitializeKeyWrappingContext(hw_enforced, sw_enforced, hidden, master_key, &ctx);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (!ciphertext->Reset(plaintext.key_material_size))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    int ae_err = ae_encrypt(ctx.get(), nonce.peek_read(), plaintext.key_material,
+                            plaintext.key_material_size, NULL /* additional data */,
+                            0 /* additional data length */, ciphertext->writable_data(),
+                            tag->peek_write(), 1 /* final */);
+    if (ae_err < 0) {
+        LOG_E("Error %d while encrypting key", ae_err);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+    if (!tag->advance_write(OCB_TAG_LENGTH))
+        return KM_ERROR_UNKNOWN_ERROR;
+    assert(ae_err == static_cast<int>(plaintext.key_material_size));
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t OcbDecryptKey(const AuthorizationSet& hw_enforced,
+                                const AuthorizationSet& sw_enforced, const AuthorizationSet& hidden,
+                                const KeymasterKeyBlob& master_key,
+                                const KeymasterKeyBlob& ciphertext, const Buffer& nonce,
+                                const Buffer& tag, KeymasterKeyBlob* plaintext) {
+    assert(plaintext);
+
+    if (nonce.available_read() != OCB_NONCE_LENGTH || tag.available_read() != OCB_TAG_LENGTH)
+        return KM_ERROR_INVALID_ARGUMENT;
+
+    AeCtx ctx;
+    if (!ctx.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    keymaster_error_t error =
+        InitializeKeyWrappingContext(hw_enforced, sw_enforced, hidden, master_key, &ctx);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (!plaintext->Reset(ciphertext.key_material_size))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    int ae_err = ae_decrypt(ctx.get(), nonce.peek_read(), ciphertext.key_material,
+                            ciphertext.key_material_size, NULL /* additional data */,
+                            0 /* additional data length */, plaintext->writable_data(),
+                            tag.peek_read(), 1 /* final */);
+    if (ae_err == AE_INVALID) {
+        // Authentication failed!  Decryption probably succeeded(ish), but we don't want to return
+        // any data when the authentication fails, so clear it.
+        plaintext->Clear();
+        LOG_E("Failed to validate authentication tag during key decryption", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    } else if (ae_err < 0) {
+        LOG_E("Failed to decrypt key, error: %d", ae_err);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+    assert(ae_err == static_cast<int>(ciphertext.key_material_size));
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/ocb_utils.h b/keymaster/ocb_utils.h
new file mode 100644
index 0000000..bae1e08
--- /dev/null
+++ b/keymaster/ocb_utils.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_OCB_UTILS_H_
+#define SYSTEM_KEYMASTER_OCB_UTILS_H_
+
+#include "ae.h"
+
+#include <hardware/keymaster_defs.h>
+
+#include <keymaster/serializable.h>
+
+namespace keymaster {
+
+class AuthorizationSet;
+struct KeymasterKeyBlob;
+
+static const int OCB_NONCE_LENGTH = 12;
+static const int OCB_TAG_LENGTH = 16;
+
+keymaster_error_t OcbEncryptKey(const AuthorizationSet& hw_enforced,
+                                const AuthorizationSet& sw_enforced, const AuthorizationSet& hidden,
+                                const KeymasterKeyBlob& master_key,
+                                const KeymasterKeyBlob& plaintext, const Buffer& nonce,
+                                KeymasterKeyBlob* ciphertext, Buffer* tag);
+
+keymaster_error_t OcbDecryptKey(const AuthorizationSet& hw_enforced,
+                                const AuthorizationSet& sw_enforced, const AuthorizationSet& hidden,
+                                const KeymasterKeyBlob& master_key,
+                                const KeymasterKeyBlob& ciphertext, const Buffer& nonce,
+                                const Buffer& tag, KeymasterKeyBlob* plaintext);
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_OCB_UTILS_H_
diff --git a/keymaster/openssl_err.cpp b/keymaster/openssl_err.cpp
new file mode 100644
index 0000000..078b8e3
--- /dev/null
+++ b/keymaster/openssl_err.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "openssl_err.h"
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#if defined(OPENSSL_IS_BORINGSSL)
+#include <openssl/asn1.h>
+#include <openssl/cipher.h>
+#include <openssl/pkcs8.h>
+#include <openssl/x509v3.h>
+#endif
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+static keymaster_error_t TranslateEvpError(int reason);
+#if defined(OPENSSL_IS_BORINGSSL)
+static keymaster_error_t TranslateASN1Error(int reason);
+static keymaster_error_t TranslateCipherError(int reason);
+static keymaster_error_t TranslatePKCS8Error(int reason);
+static keymaster_error_t TranslateX509v3Error(int reason);
+static keymaster_error_t TranslateRsaError(int reason);
+#endif
+
+keymaster_error_t TranslateLastOpenSslError(bool log_message) {
+    unsigned long error = ERR_peek_last_error();
+
+    if (log_message) {
+        LOG_D("%s", ERR_error_string(error, NULL));
+    }
+
+    int reason = ERR_GET_REASON(error);
+
+    /* Handle global error reasons */
+    switch (reason) {
+    case ERR_R_MALLOC_FAILURE:
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
+    case ERR_R_PASSED_NULL_PARAMETER:
+    case ERR_R_INTERNAL_ERROR:
+    case ERR_R_OVERFLOW:
+        return KM_ERROR_UNKNOWN_ERROR;
+    default:
+        break;
+    }
+
+    switch (ERR_GET_LIB(error)) {
+    case ERR_LIB_USER:
+        return static_cast<keymaster_error_t>(reason);
+    case ERR_LIB_EVP:
+        return TranslateEvpError(reason);
+#if defined(OPENSSL_IS_BORINGSSL)
+    case ERR_LIB_ASN1:
+        return TranslateASN1Error(reason);
+    case ERR_LIB_CIPHER:
+        return TranslateCipherError(reason);
+    case ERR_LIB_PKCS8:
+        return TranslatePKCS8Error(reason);
+    case ERR_LIB_X509V3:
+        return TranslateX509v3Error(reason);
+    case ERR_LIB_RSA:
+        return TranslateRsaError(reason);
+#else
+    case ERR_LIB_ASN1:
+        LOG_E("ASN.1 parsing error %d", reason);
+        return KM_ERROR_INVALID_ARGUMENT;
+#endif
+    }
+
+    LOG_E("Openssl error %d, %d", ERR_GET_LIB(error), reason);
+    return KM_ERROR_UNKNOWN_ERROR;
+}
+
+#if defined(OPENSSL_IS_BORINGSSL)
+
+keymaster_error_t TranslatePKCS8Error(int reason) {
+    switch (reason) {
+    case PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:
+    case PKCS8_R_UNKNOWN_CIPHER:
+        return KM_ERROR_UNSUPPORTED_ALGORITHM;
+
+    case PKCS8_R_PRIVATE_KEY_ENCODE_ERROR:
+    case PKCS8_R_PRIVATE_KEY_DECODE_ERROR:
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    case PKCS8_R_ENCODE_ERROR:
+        return KM_ERROR_INVALID_ARGUMENT;
+
+    default:
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+}
+
+keymaster_error_t TranslateCipherError(int reason) {
+    switch (reason) {
+    case CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
+    case CIPHER_R_WRONG_FINAL_BLOCK_LENGTH:
+        return KM_ERROR_INVALID_INPUT_LENGTH;
+
+    case CIPHER_R_UNSUPPORTED_KEY_SIZE:
+    case CIPHER_R_BAD_KEY_LENGTH:
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+
+    case CIPHER_R_BAD_DECRYPT:
+        return KM_ERROR_INVALID_ARGUMENT;
+
+    case CIPHER_R_INVALID_KEY_LENGTH:
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    default:
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+}
+
+keymaster_error_t TranslateASN1Error(int reason) {
+    switch (reason) {
+#if !defined(OPENSSL_IS_BORINGSSL)
+    case ASN1_R_UNSUPPORTED_CIPHER:
+        return KM_ERROR_UNSUPPORTED_ALGORITHM;
+
+    case ASN1_R_ERROR_LOADING_SECTION:
+        return KM_ERROR_INVALID_KEY_BLOB;
+#endif
+
+    case ASN1_R_ENCODE_ERROR:
+        return KM_ERROR_INVALID_ARGUMENT;
+
+    default:
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+}
+
+keymaster_error_t TranslateX509v3Error(int reason) {
+    switch (reason) {
+    case X509V3_R_UNKNOWN_OPTION:
+        return KM_ERROR_UNSUPPORTED_ALGORITHM;
+
+    default:
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+}
+
+keymaster_error_t TranslateRsaError(int reason) {
+    switch (reason) {
+    case RSA_R_KEY_SIZE_TOO_SMALL:
+        LOG_W("RSA key is too small to use with selected padding/digest", 0);
+        return KM_ERROR_INCOMPATIBLE_PADDING_MODE;
+    case RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE:
+    case RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE:
+        return KM_ERROR_INVALID_INPUT_LENGTH;
+    case RSA_R_DATA_TOO_LARGE_FOR_MODULUS:
+        return KM_ERROR_INVALID_ARGUMENT;
+    default:
+        return KM_ERROR_UNKNOWN_ERROR;
+    };
+}
+
+#endif  // OPENSSL_IS_BORINGSSL
+
+keymaster_error_t TranslateEvpError(int reason) {
+    switch (reason) {
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+    case EVP_R_UNKNOWN_DIGEST:
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+
+    case EVP_R_UNSUPPORTED_PRF:
+    case EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM:
+    case EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION:
+    case EVP_R_UNSUPPORTED_SALT_TYPE:
+    case EVP_R_UNKNOWN_PBE_ALGORITHM:
+    case EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS:
+    case EVP_R_UNSUPPORTED_CIPHER:
+    case EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE:
+    case EVP_R_UNKNOWN_CIPHER:
+#endif
+    case EVP_R_UNSUPPORTED_ALGORITHM:
+    case EVP_R_OPERATON_NOT_INITIALIZED:
+    case EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:
+        return KM_ERROR_UNSUPPORTED_ALGORITHM;
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+    case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
+    case EVP_R_WRONG_FINAL_BLOCK_LENGTH:
+        return KM_ERROR_INVALID_INPUT_LENGTH;
+
+    case EVP_R_UNSUPPORTED_KEYLENGTH:
+    case EVP_R_BAD_KEY_LENGTH:
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+#endif
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+    case EVP_R_BAD_BLOCK_LENGTH:
+    case EVP_R_BN_DECODE_ERROR:
+    case EVP_R_BN_PUBKEY_ERROR:
+    case EVP_R_CIPHER_PARAMETER_ERROR:
+    case EVP_R_ERROR_LOADING_SECTION:
+    case EVP_R_EXPECTING_A_DH_KEY:
+    case EVP_R_EXPECTING_A_ECDSA_KEY:
+    case EVP_R_EXPECTING_A_EC_KEY:
+    case EVP_R_INVALID_DIGEST:
+    case EVP_R_INVALID_KEY_LENGTH:
+    case EVP_R_NO_DSA_PARAMETERS:
+    case EVP_R_PRIVATE_KEY_DECODE_ERROR:
+    case EVP_R_PRIVATE_KEY_ENCODE_ERROR:
+    case EVP_R_PUBLIC_KEY_NOT_RSA:
+    case EVP_R_WRONG_PUBLIC_KEY_TYPE:
+#endif
+    case EVP_R_BUFFER_TOO_SMALL:
+    case EVP_R_EXPECTING_AN_RSA_KEY:
+    case EVP_R_EXPECTING_A_DSA_KEY:
+    case EVP_R_MISSING_PARAMETERS:
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+#if !defined(OPENSSL_IS_BORINGSSL)
+    case EVP_R_BAD_DECRYPT:
+    case EVP_R_ENCODE_ERROR:
+#endif
+    case EVP_R_DIFFERENT_PARAMETERS:
+    case EVP_R_DECODE_ERROR:
+        return KM_ERROR_INVALID_ARGUMENT;
+
+    case EVP_R_DIFFERENT_KEY_TYPES:
+        return KM_ERROR_INCOMPATIBLE_ALGORITHM;
+    }
+
+    return KM_ERROR_UNKNOWN_ERROR;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/openssl_err.h b/keymaster/openssl_err.h
new file mode 100644
index 0000000..8f97ef5
--- /dev/null
+++ b/keymaster/openssl_err.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_OPENSSL_ERR_H_
+#define SYSTEM_KEYMASTER_OPENSSL_ERR_H_
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+/**
+ * Translate the last OpenSSL error to a keymaster error.  Does not remove the error from the queue.
+ */
+keymaster_error_t TranslateLastOpenSslError(bool log_message = true);
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_OPENSSL_ERR_H_
diff --git a/keymaster/openssl_utils.cpp b/keymaster/openssl_utils.cpp
new file mode 100644
index 0000000..5d2cb1c
--- /dev/null
+++ b/keymaster/openssl_utils.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 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.
+ */
+
+#include "openssl_utils.h"
+
+#include <keymaster/android_keymaster_utils.h>
+
+#include "openssl_err.h"
+
+namespace keymaster {
+
+keymaster_error_t ec_get_group_size(const EC_GROUP* group, size_t* key_size_bits) {
+    switch (EC_GROUP_get_curve_name(group)) {
+    case NID_secp224r1:
+        *key_size_bits = 224;
+        break;
+    case NID_X9_62_prime256v1:
+        *key_size_bits = 256;
+        break;
+    case NID_secp384r1:
+        *key_size_bits = 384;
+        break;
+    case NID_secp521r1:
+        *key_size_bits = 521;
+        break;
+    default:
+        return KM_ERROR_UNSUPPORTED_EC_FIELD;
+    }
+    return KM_ERROR_OK;
+}
+
+EC_GROUP* ec_get_group(keymaster_ec_curve_t curve) {
+    switch (curve) {
+    case KM_EC_CURVE_P_224:
+        return EC_GROUP_new_by_curve_name(NID_secp224r1);
+        break;
+    case KM_EC_CURVE_P_256:
+        return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+        break;
+    case KM_EC_CURVE_P_384:
+        return EC_GROUP_new_by_curve_name(NID_secp384r1);
+        break;
+    case KM_EC_CURVE_P_521:
+        return EC_GROUP_new_by_curve_name(NID_secp521r1);
+        break;
+    default:
+        return nullptr;
+        break;
+    }
+}
+
+void convert_bn_to_blob(BIGNUM* bn, keymaster_blob_t* blob) {
+    blob->data_length = BN_num_bytes(bn);
+    blob->data = new uint8_t[blob->data_length];
+    BN_bn2bin(bn, const_cast<uint8_t*>(blob->data));
+}
+
+static int convert_to_evp(keymaster_algorithm_t algorithm) {
+    switch (algorithm) {
+    case KM_ALGORITHM_RSA:
+        return EVP_PKEY_RSA;
+    case KM_ALGORITHM_EC:
+        return EVP_PKEY_EC;
+    default:
+        return -1;
+    };
+}
+
+keymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_length,
+                                            keymaster_algorithm_t expected_algorithm,
+                                            UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
+    if (key_data == NULL || key_length <= 0)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8(
+        d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_length));
+    if (pkcs8.get() == NULL)
+        return TranslateLastOpenSslError(true /* log_message */);
+
+    pkey->reset(EVP_PKCS82PKEY(pkcs8.get()));
+    if (!pkey->get())
+        return TranslateLastOpenSslError(true /* log_message */);
+
+    if (EVP_PKEY_type((*pkey)->type) != convert_to_evp(expected_algorithm)) {
+        LOG_E("EVP key algorithm was %d, not the expected %d", EVP_PKEY_type((*pkey)->type),
+              convert_to_evp(expected_algorithm));
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format,
+                                      const KeymasterKeyBlob& key_material,
+                                      keymaster_algorithm_t expected_algorithm,
+                                      UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) {
+    if (key_format != KM_KEY_FORMAT_PKCS8)
+        return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
+
+    return convert_pkcs8_blob_to_evp(key_material.key_material, key_material.key_material_size,
+                                     expected_algorithm, pkey);
+}
+
+keymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* pkey, KeymasterKeyBlob* key_blob) {
+    int key_data_size = i2d_PrivateKey(pkey, NULL /* key_data*/);
+    if (key_data_size <= 0)
+        return TranslateLastOpenSslError();
+
+    if (!key_blob->Reset(key_data_size))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    uint8_t* tmp = key_blob->writable_data();
+    i2d_PrivateKey(pkey, &tmp);
+
+    return KM_ERROR_OK;
+}
+
+size_t ec_group_size_bits(EC_KEY* ec_key) {
+    const EC_GROUP* group = EC_KEY_get0_group(ec_key);
+    UniquePtr<BN_CTX, BN_CTX_Delete> bn_ctx(BN_CTX_new());
+    UniquePtr<BIGNUM, BIGNUM_Delete> order(BN_new());
+    if (!EC_GROUP_get_order(group, order.get(), bn_ctx.get())) {
+        LOG_E("Failed to get EC group order", 0);
+        return 0;
+    }
+    return BN_num_bits(order.get());
+}
+
+}  // namespace keymaster
diff --git a/keymaster/openssl_utils.h b/keymaster/openssl_utils.h
new file mode 100644
index 0000000..034b129
--- /dev/null
+++ b/keymaster/openssl_utils.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_OPENSSL_UTILS_H_
+#define SYSTEM_KEYMASTER_OPENSSL_UTILS_H_
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+#include <UniquePtr.h>
+
+#include <hardware/keymaster_defs.h>
+
+namespace keymaster {
+
+struct KeymasterKeyBlob;
+
+class EvpMdCtxCleaner {
+  public:
+    explicit EvpMdCtxCleaner(EVP_MD_CTX* ctx) : ctx_(ctx) {}
+    ~EvpMdCtxCleaner() { EVP_MD_CTX_cleanup(ctx_); }
+
+  private:
+    EVP_MD_CTX* ctx_;
+};
+
+template <typename T, void (*FreeFunc)(T*)> struct OpenSslObjectDeleter {
+    void operator()(T* p) { FreeFunc(p); }
+};
+
+#define DEFINE_OPENSSL_OBJECT_POINTER(name)                                                        \
+    typedef OpenSslObjectDeleter<name, name##_free> name##_Delete;                                 \
+    typedef UniquePtr<name, name##_Delete> name##_Ptr;
+
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_INTEGER)
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_OBJECT)
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_OCTET_STRING)
+DEFINE_OPENSSL_OBJECT_POINTER(ASN1_TIME)
+DEFINE_OPENSSL_OBJECT_POINTER(BN_CTX);
+DEFINE_OPENSSL_OBJECT_POINTER(EC_GROUP);
+DEFINE_OPENSSL_OBJECT_POINTER(EC_KEY);
+DEFINE_OPENSSL_OBJECT_POINTER(EC_POINT);
+DEFINE_OPENSSL_OBJECT_POINTER(ENGINE);
+DEFINE_OPENSSL_OBJECT_POINTER(EVP_PKEY);
+DEFINE_OPENSSL_OBJECT_POINTER(PKCS8_PRIV_KEY_INFO);
+DEFINE_OPENSSL_OBJECT_POINTER(RSA);
+DEFINE_OPENSSL_OBJECT_POINTER(X509)
+DEFINE_OPENSSL_OBJECT_POINTER(X509_EXTENSION)
+DEFINE_OPENSSL_OBJECT_POINTER(X509_NAME)
+
+typedef OpenSslObjectDeleter<BIGNUM, BN_free> BIGNUM_Delete;
+typedef UniquePtr<BIGNUM, BIGNUM_Delete> BIGNUM_Ptr;
+
+keymaster_error_t ec_get_group_size(const EC_GROUP* group, size_t* key_size_bits);
+EC_GROUP* ec_get_group(keymaster_ec_curve_t curve);
+
+/**
+ * Many OpenSSL APIs take ownership of an argument on success but don't free the argument on
+ * failure. This means we need to tell our scoped pointers when we've transferred ownership, without
+ * triggering a warning by not using the result of release().
+ */
+template <typename T, typename Delete_T>
+inline void release_because_ownership_transferred(UniquePtr<T, Delete_T>& p) {
+    T* val __attribute__((unused)) = p.release();
+}
+
+keymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_length,
+                                            keymaster_algorithm_t expected_algorithm,
+                                            UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey);
+
+keymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format,
+                                      const KeymasterKeyBlob& key_material,
+                                      keymaster_algorithm_t expected_algorithm,
+                                      UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* evp_pkey);
+
+keymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* evp_pkey, KeymasterKeyBlob* key_blob);
+
+size_t ec_group_size_bits(EC_KEY* ec_key);
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_OPENSSL_UTILS_H_
diff --git a/keymaster/operation.cpp b/keymaster/operation.cpp
new file mode 100644
index 0000000..410c9aa
--- /dev/null
+++ b/keymaster/operation.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "operation.h"
+
+#include <keymaster/authorization_set.h>
+
+#include "key.h"
+
+namespace keymaster {
+
+bool OperationFactory::supported(keymaster_padding_t padding) const {
+    size_t padding_count;
+    const keymaster_padding_t* supported_paddings = SupportedPaddingModes(&padding_count);
+    for (size_t i = 0; i < padding_count; ++i)
+        if (padding == supported_paddings[i])
+            return true;
+    return false;
+}
+
+bool OperationFactory::supported(keymaster_block_mode_t block_mode) const {
+    size_t block_mode_count;
+    const keymaster_block_mode_t* supported_block_modes = SupportedBlockModes(&block_mode_count);
+    for (size_t i = 0; i < block_mode_count; ++i)
+        if (block_mode == supported_block_modes[i])
+            return true;
+    return false;
+}
+
+bool OperationFactory::supported(keymaster_digest_t digest) const {
+    size_t digest_count;
+    const keymaster_digest_t* supported_digests = SupportedDigests(&digest_count);
+    for (size_t i = 0; i < digest_count; ++i)
+        if (digest == supported_digests[i])
+            return true;
+    return false;
+}
+
+inline bool is_public_key_algorithm(keymaster_algorithm_t algorithm) {
+    switch (algorithm) {
+    case KM_ALGORITHM_HMAC:
+    case KM_ALGORITHM_AES:
+        return false;
+    case KM_ALGORITHM_RSA:
+    case KM_ALGORITHM_EC:
+        return true;
+    }
+
+    // Unreachable.
+    assert(false);
+    return false;
+}
+
+bool OperationFactory::is_public_key_operation() const {
+    KeyType key_type = registry_key();
+
+    if (!is_public_key_algorithm(key_type.algorithm))
+        return false;
+
+    switch (key_type.purpose) {
+    case KM_PURPOSE_VERIFY:
+    case KM_PURPOSE_ENCRYPT:
+        return true;
+    case KM_PURPOSE_SIGN:
+    case KM_PURPOSE_DECRYPT:
+    case KM_PURPOSE_DERIVE_KEY:
+        return false;
+    };
+
+    // Unreachable.
+    assert(false);
+    return false;
+}
+
+bool OperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
+                                             keymaster_padding_t* padding,
+                                             keymaster_error_t* error) const {
+    *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
+    if (!begin_params.GetTagValue(TAG_PADDING, padding)) {
+        LOG_E("%d padding modes specified in begin params", begin_params.GetTagCount(TAG_PADDING));
+        return false;
+    } else if (!supported(*padding)) {
+        LOG_E("Padding mode %d not supported", *padding);
+        return false;
+    } else if (
+        // If it's a public key operation, all padding modes are authorized.
+        !is_public_key_operation() &&
+        // Otherwise the key needs to authorize the specific mode.
+        !key.authorizations().Contains(TAG_PADDING, *padding) &&
+        !key.authorizations().Contains(TAG_PADDING_OLD, *padding)) {
+        LOG_E("Padding mode %d was specified, but not authorized by key", *padding);
+        *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
+        return false;
+    }
+
+    *error = KM_ERROR_OK;
+    return true;
+}
+
+bool OperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
+                                            keymaster_digest_t* digest,
+                                            keymaster_error_t* error) const {
+    *error = KM_ERROR_UNSUPPORTED_DIGEST;
+    if (!begin_params.GetTagValue(TAG_DIGEST, digest)) {
+        LOG_E("%d digests specified in begin params", begin_params.GetTagCount(TAG_DIGEST));
+        return false;
+    } else if (!supported(*digest)) {
+        LOG_E("Digest %d not supported", *digest);
+        return false;
+    } else if (
+        // If it's a public key operation, all digests are authorized.
+        !is_public_key_operation() &&
+        // Otherwise the key needs to authorize the specific digest.
+        !key.authorizations().Contains(TAG_DIGEST, *digest) &&
+        !key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) {
+        LOG_E("Digest %d was specified, but not authorized by key", *digest);
+        *error = KM_ERROR_INCOMPATIBLE_DIGEST;
+        return false;
+    }
+    *error = KM_ERROR_OK;
+    return true;
+}
+
+keymaster_error_t Operation::UpdateForFinish(const AuthorizationSet& input_params,
+                                             const Buffer& input) {
+    if (!input_params.empty() || input.available_read()) {
+        size_t input_consumed;
+        Buffer output;
+        AuthorizationSet output_params;
+        keymaster_error_t error =
+            Update(input_params, input, &output_params, &output, &input_consumed);
+        if (error != KM_ERROR_OK)
+            return error;
+        assert(input_consumed == input.available_read());
+        assert(output_params.empty());
+        assert(output.available_read() == 0);
+    }
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/operation.h b/keymaster/operation.h
new file mode 100644
index 0000000..aadc406
--- /dev/null
+++ b/keymaster/operation.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_OPERATION_H_
+#define SYSTEM_KEYMASTER_OPERATION_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <hardware/keymaster_defs.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+class AuthorizationSet;
+class Key;
+class Operation;
+
+class OperationFactory {
+  public:
+    virtual ~OperationFactory() {}
+
+    // Required for registry
+    struct KeyType {
+        KeyType(keymaster_algorithm_t alg, keymaster_purpose_t purp)
+            : algorithm(alg), purpose(purp) {}
+
+        keymaster_algorithm_t algorithm;
+        keymaster_purpose_t purpose;
+
+        bool operator==(const KeyType& rhs) const {
+            return algorithm == rhs.algorithm && purpose == rhs.purpose;
+        }
+    };
+    virtual KeyType registry_key() const = 0;
+
+    // Factory methods
+    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                                       keymaster_error_t* error) = 0;
+
+    // Informational methods.  The returned arrays reference static memory and must not be
+    // deallocated or modified.
+    virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const {
+        *padding_count = 0;
+        return NULL;
+    }
+    virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const {
+        *block_mode_count = 0;
+        return NULL;
+    }
+    virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
+        *digest_count = 0;
+        return NULL;
+    }
+
+    // Convenience methods
+    bool supported(keymaster_padding_t padding) const;
+    bool supported(keymaster_block_mode_t padding) const;
+    bool supported(keymaster_digest_t padding) const;
+
+    bool is_public_key_operation() const;
+
+    bool GetAndValidatePadding(const AuthorizationSet& begin_params, const Key& key,
+                               keymaster_padding_t* padding, keymaster_error_t* error) const;
+    bool GetAndValidateDigest(const AuthorizationSet& begin_params, const Key& key,
+                              keymaster_digest_t* digest, keymaster_error_t* error) const;
+};
+
+/**
+ * Abstract base for all cryptographic operations.
+ */
+class Operation {
+  public:
+    explicit Operation(keymaster_purpose_t purpose) : purpose_(purpose) {}
+    virtual ~Operation() {}
+
+    keymaster_purpose_t purpose() const { return purpose_; }
+
+    void set_key_id(uint64_t key_id) { key_id_ = key_id; }
+    uint64_t key_id() const { return key_id_; }
+
+    void SetAuthorizations(const AuthorizationSet& auths) {
+        key_auths_.Reinitialize(auths.data(), auths.size());
+    }
+    const AuthorizationSet authorizations() { return key_auths_; }
+
+    virtual keymaster_error_t Begin(const AuthorizationSet& input_params,
+                                    AuthorizationSet* output_params) = 0;
+    virtual keymaster_error_t Update(const AuthorizationSet& input_params, const Buffer& input,
+                                     AuthorizationSet* output_params, Buffer* output,
+                                     size_t* input_consumed) = 0;
+    virtual keymaster_error_t Finish(const AuthorizationSet& input_params, const Buffer& input,
+                                     const Buffer& signature, AuthorizationSet* output_params,
+                                     Buffer* output) = 0;
+    virtual keymaster_error_t Abort() = 0;
+
+protected:
+    // Helper function for implementing Finish() methods that need to call Update() to process
+    // input, but don't expect any output.
+    keymaster_error_t UpdateForFinish(const AuthorizationSet& input_params, const Buffer& input);
+
+  private:
+    const keymaster_purpose_t purpose_;
+    AuthorizationSet key_auths_;
+    uint64_t key_id_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_OPERATION_H_
diff --git a/keymaster/operation_table.cpp b/keymaster/operation_table.cpp
new file mode 100644
index 0000000..d30885e
--- /dev/null
+++ b/keymaster/operation_table.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#include "operation_table.h"
+
+#include <new>
+
+#include <openssl/rand.h>
+
+#include "openssl_err.h"
+#include "operation.h"
+
+namespace keymaster {
+
+OperationTable::Entry::~Entry() {
+    delete operation;
+    operation = NULL;
+    handle = 0;
+}
+
+keymaster_error_t OperationTable::Add(Operation* operation,
+                                      keymaster_operation_handle_t* op_handle) {
+    if (!table_.get()) {
+        table_.reset(new (std::nothrow) Entry[table_size_]);
+        if (!table_.get())
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+
+    UniquePtr<Operation> op(operation);
+    if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) != 1)
+        return TranslateLastOpenSslError();
+    if (*op_handle == 0) {
+        // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
+        // it indicates a broken RNG.
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+
+    for (size_t i = 0; i < table_size_; ++i) {
+        if (table_[i].operation == NULL) {
+            table_[i].operation = op.release();
+            table_[i].handle = *op_handle;
+            return KM_ERROR_OK;
+        }
+    }
+    return KM_ERROR_TOO_MANY_OPERATIONS;
+}
+
+Operation* OperationTable::Find(keymaster_operation_handle_t op_handle) {
+    if (op_handle == 0)
+        return NULL;
+
+    if (!table_.get())
+        return NULL;
+
+    for (size_t i = 0; i < table_size_; ++i) {
+        if (table_[i].handle == op_handle)
+            return table_[i].operation;
+    }
+    return NULL;
+}
+
+bool OperationTable::Delete(keymaster_operation_handle_t op_handle) {
+    if (!table_.get())
+        return false;
+
+    for (size_t i = 0; i < table_size_; ++i) {
+        if (table_[i].handle == op_handle) {
+            delete table_[i].operation;
+            table_[i].operation = NULL;
+            table_[i].handle = 0;
+            return true;
+        }
+    }
+    return false;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/operation_table.h b/keymaster/operation_table.h
new file mode 100644
index 0000000..c840ad9
--- /dev/null
+++ b/keymaster/operation_table.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_OPERATION_TABLE_H
+#define SYSTEM_KEYMASTER_OPERATION_TABLE_H
+
+#include <UniquePtr.h>
+
+#include <hardware/keymaster_defs.h>
+
+namespace keymaster {
+
+class Operation;
+
+class OperationTable {
+  public:
+    explicit OperationTable(size_t table_size) : table_size_(table_size) {}
+
+    struct Entry {
+        Entry() {
+            handle = 0;
+            operation = NULL;
+        };
+        ~Entry();
+        keymaster_operation_handle_t handle;
+        Operation* operation;
+    };
+
+    keymaster_error_t Add(Operation* operation, keymaster_operation_handle_t* op_handle);
+    Operation* Find(keymaster_operation_handle_t op_handle);
+    bool Delete(keymaster_operation_handle_t);
+
+  private:
+    UniquePtr<Entry[]> table_;
+    size_t table_size_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_OPERATION_TABLE_H
diff --git a/keymaster/rsa_key.cpp b/keymaster/rsa_key.cpp
new file mode 100644
index 0000000..4231953
--- /dev/null
+++ b/keymaster/rsa_key.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "rsa_key.h"
+
+#include <keymaster/keymaster_context.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+#include "rsa_operation.h"
+
+namespace keymaster {
+
+bool RsaKey::EvpToInternal(const EVP_PKEY* pkey) {
+    rsa_key_.reset(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pkey)));
+    return rsa_key_.get() != NULL;
+}
+
+bool RsaKey::InternalToEvp(EVP_PKEY* pkey) const {
+    return EVP_PKEY_set1_RSA(pkey, rsa_key_.get()) == 1;
+}
+
+bool RsaKey::SupportedMode(keymaster_purpose_t purpose, keymaster_padding_t padding) {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+    case KM_PURPOSE_VERIFY:
+        return padding == KM_PAD_NONE || padding == KM_PAD_RSA_PSS ||
+               padding == KM_PAD_RSA_PKCS1_1_5_SIGN;
+
+    case KM_PURPOSE_ENCRYPT:
+    case KM_PURPOSE_DECRYPT:
+        return padding == KM_PAD_RSA_OAEP || padding == KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
+
+    case KM_PURPOSE_DERIVE_KEY:
+        return false;
+    };
+    return false;
+}
+
+bool RsaKey::SupportedMode(keymaster_purpose_t purpose, keymaster_digest_t digest) {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+    case KM_PURPOSE_VERIFY:
+        return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
+
+    case KM_PURPOSE_ENCRYPT:
+    case KM_PURPOSE_DECRYPT:
+        /* Don't care */
+        break;
+
+    case KM_PURPOSE_DERIVE_KEY:
+        return false;
+    };
+    return true;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/rsa_key.h b/keymaster/rsa_key.h
new file mode 100644
index 0000000..502f28a
--- /dev/null
+++ b/keymaster/rsa_key.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_RSA_KEY_H_
+#define SYSTEM_KEYMASTER_RSA_KEY_H_
+
+#include <openssl/rsa.h>
+
+#include "asymmetric_key.h"
+
+namespace keymaster {
+
+class RsaKey : public AsymmetricKey {
+  public:
+    RsaKey(const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+           keymaster_error_t* error)
+        : AsymmetricKey(hw_enforced, sw_enforced, error) {}
+
+    bool InternalToEvp(EVP_PKEY* pkey) const override;
+    bool EvpToInternal(const EVP_PKEY* pkey) override;
+
+    bool SupportedMode(keymaster_purpose_t purpose, keymaster_padding_t padding);
+    bool SupportedMode(keymaster_purpose_t purpose, keymaster_digest_t digest);
+
+    struct RSA_Delete {
+        void operator()(RSA* p) { RSA_free(p); }
+    };
+
+    RSA* key() const { return rsa_key_.get(); }
+
+  protected:
+    RsaKey(RSA* rsa, const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+           keymaster_error_t* error)
+        : AsymmetricKey(hw_enforced, sw_enforced, error), rsa_key_(rsa) {}
+
+  private:
+    UniquePtr<RSA, RSA_Delete> rsa_key_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_RSA_KEY_H_
diff --git a/keymaster/rsa_key_factory.cpp b/keymaster/rsa_key_factory.cpp
new file mode 100644
index 0000000..e6c3f8c
--- /dev/null
+++ b/keymaster/rsa_key_factory.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 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.
+ */
+
+#include <keymaster/rsa_key_factory.h>
+
+#include <new>
+
+#include <keymaster/keymaster_context.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+#include "rsa_key.h"
+#include "rsa_operation.h"
+
+namespace keymaster {
+
+const int kMaximumRsaKeySize = 16 * 1024;  // 16kbits should be enough for anyone.
+
+static RsaSigningOperationFactory sign_factory;
+static RsaVerificationOperationFactory verify_factory;
+static RsaEncryptionOperationFactory encrypt_factory;
+static RsaDecryptionOperationFactory decrypt_factory;
+
+OperationFactory* RsaKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return &sign_factory;
+    case KM_PURPOSE_VERIFY:
+        return &verify_factory;
+    case KM_PURPOSE_ENCRYPT:
+        return &encrypt_factory;
+    case KM_PURPOSE_DECRYPT:
+        return &decrypt_factory;
+    default:
+        return nullptr;
+    }
+}
+
+keymaster_error_t RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                             KeymasterKeyBlob* key_blob,
+                                             AuthorizationSet* hw_enforced,
+                                             AuthorizationSet* sw_enforced) const {
+    if (!key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const AuthorizationSet& authorizations(key_description);
+
+    uint64_t public_exponent;
+    if (!authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
+        LOG_E("%s", "No public exponent specified for RSA key generation");
+        return KM_ERROR_INVALID_ARGUMENT;
+    }
+
+    uint32_t key_size;
+    if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) {
+        LOG_E("No key size specified for RSA key generation", 0);
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+    }
+    if (key_size % 8 != 0 || key_size > kMaximumRsaKeySize) {
+        LOG_E("Invalid key size of %u bits specified for RSA key generation", key_size);
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+    }
+
+    UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new());
+    UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(RSA_new());
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
+    if (exponent.get() == NULL || rsa_key.get() == NULL || pkey.get() == NULL)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (!BN_set_word(exponent.get(), public_exponent) ||
+        !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */))
+        return TranslateLastOpenSslError();
+
+    if (EVP_PKEY_set1_RSA(pkey.get(), rsa_key.get()) != 1)
+        return TranslateLastOpenSslError();
+
+    KeymasterKeyBlob key_material;
+    keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob,
+                                   hw_enforced, sw_enforced);
+}
+
+keymaster_error_t RsaKeyFactory::ImportKey(const AuthorizationSet& key_description,
+                                           keymaster_key_format_t input_key_material_format,
+                                           const KeymasterKeyBlob& input_key_material,
+                                           KeymasterKeyBlob* output_key_blob,
+                                           AuthorizationSet* hw_enforced,
+                                           AuthorizationSet* sw_enforced) const {
+    if (!output_key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    AuthorizationSet authorizations;
+    uint64_t public_exponent;
+    uint32_t key_size;
+    keymaster_error_t error =
+        UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material,
+                                   &authorizations, &public_exponent, &key_size);
+    if (error != KM_ERROR_OK)
+        return error;
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
+                                   output_key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t RsaKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description,
+                                                            keymaster_key_format_t key_format,
+                                                            const KeymasterKeyBlob& key_material,
+                                                            AuthorizationSet* updated_description,
+                                                            uint64_t* public_exponent,
+                                                            uint32_t* key_size) const {
+    if (!updated_description || !public_exponent || !key_size)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey;
+    keymaster_error_t error =
+        KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(EVP_PKEY_get1_RSA(pkey.get()));
+    if (!rsa_key.get())
+        return TranslateLastOpenSslError();
+
+    updated_description->Reinitialize(key_description);
+
+    *public_exponent = BN_get_word(rsa_key->e);
+    if (*public_exponent == 0xffffffffL)
+        return KM_ERROR_INVALID_KEY_BLOB;
+    if (!updated_description->GetTagValue(TAG_RSA_PUBLIC_EXPONENT, public_exponent))
+        updated_description->push_back(TAG_RSA_PUBLIC_EXPONENT, *public_exponent);
+    if (*public_exponent != BN_get_word(rsa_key->e)) {
+        LOG_E("Imported public exponent (%u) does not match specified public exponent (%u)",
+              *public_exponent, BN_get_word(rsa_key->e));
+        return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
+    }
+
+    *key_size = RSA_size(rsa_key.get()) * 8;
+    if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size))
+        updated_description->push_back(TAG_KEY_SIZE, *key_size);
+    if (RSA_size(rsa_key.get()) * 8 != *key_size) {
+        LOG_E("Imported key size (%u bits) does not match specified key size (%u bits)",
+              RSA_size(rsa_key.get()) * 8, *key_size);
+        return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
+    }
+
+    keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
+    if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm))
+        updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+    if (algorithm != KM_ALGORITHM_RSA)
+        return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced,
+                                                const AuthorizationSet& sw_enforced,
+                                                UniquePtr<AsymmetricKey>* key) const {
+    keymaster_error_t error;
+    key->reset(new (std::nothrow) RsaKey(hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return error;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/rsa_keymaster0_key.cpp b/keymaster/rsa_keymaster0_key.cpp
new file mode 100644
index 0000000..6e5c083
--- /dev/null
+++ b/keymaster/rsa_keymaster0_key.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 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.
+ */
+
+#include "rsa_keymaster0_key.h"
+
+#include <memory>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+#include <keymaster/soft_keymaster_context.h>
+
+#include "keymaster0_engine.h"
+#include "openssl_utils.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+RsaKeymaster0KeyFactory::RsaKeymaster0KeyFactory(const SoftKeymasterContext* context,
+                                                 const Keymaster0Engine* engine)
+    : RsaKeyFactory(context), engine_(engine) {}
+
+keymaster_error_t RsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                                       KeymasterKeyBlob* key_blob,
+                                                       AuthorizationSet* hw_enforced,
+                                                       AuthorizationSet* sw_enforced) const {
+    if (!key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    uint64_t public_exponent;
+    if (!key_description.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
+        LOG_E("%s", "No public exponent specified for RSA key generation");
+        return KM_ERROR_INVALID_ARGUMENT;
+    }
+
+    uint32_t key_size;
+    if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) {
+        LOG_E("%s", "No key size specified for RSA key generation");
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+    }
+
+    KeymasterKeyBlob key_material;
+    if (!engine_->GenerateRsaKey(public_exponent, key_size, &key_material))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
+    // context_->CreateKeyBlob doesn't put them in sw_enforced.
+    hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+    hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
+    hw_enforced->push_back(TAG_KEY_SIZE, key_size);
+    hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
+
+    return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob,
+                                   hw_enforced, sw_enforced);
+}
+
+keymaster_error_t RsaKeymaster0KeyFactory::ImportKey(
+    const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
+    const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
+    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
+    if (!output_key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    AuthorizationSet authorizations;
+    uint64_t public_exponent;
+    uint32_t key_size;
+    keymaster_error_t error =
+        UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material,
+                                   &authorizations, &public_exponent, &key_size);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    KeymasterKeyBlob imported_hw_key;
+    if (!engine_->ImportKey(input_key_material_format, input_key_material, &imported_hw_key))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    // These tags are hardware-enforced.  Putting them in the hw_enforced set here will ensure that
+    // context_->CreateKeyBlob doesn't put them in sw_enforced.
+    hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+    hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
+    hw_enforced->push_back(TAG_KEY_SIZE, key_size);
+    hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN);
+
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key,
+                                   output_key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t RsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                                   const AuthorizationSet& additional_params,
+                                                   const AuthorizationSet& hw_enforced,
+                                                   const AuthorizationSet& sw_enforced,
+                                                   UniquePtr<Key>* key) const {
+    if (!key)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1)
+        return super::LoadKey(key_material, additional_params, hw_enforced, sw_enforced, key);
+
+    unique_ptr<RSA, RSA_Delete> rsa(engine_->BlobToRsaKey(key_material));
+    if (!rsa)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    keymaster_error_t error;
+    key->reset(new (std::nothrow)
+                   RsaKeymaster0Key(rsa.release(), hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/rsa_keymaster0_key.h b/keymaster/rsa_keymaster0_key.h
new file mode 100644
index 0000000..261448f
--- /dev/null
+++ b/keymaster/rsa_keymaster0_key.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_RSA_KEYMASTER0_KEY_H_
+#define SYSTEM_KEYMASTER_RSA_KEYMASTER0_KEY_H_
+
+#include <openssl/rsa.h>
+
+#include <keymaster/rsa_key_factory.h>
+
+#include "rsa_key.h"
+
+namespace keymaster {
+
+class Keymaster0Engine;
+class SoftKeymasterContext;
+
+/**
+ * An RsaKeyFactory which can delegate key generation, importing and loading operations to a
+ * keymaster0-backed OpenSSL engine.
+ */
+class RsaKeymaster0KeyFactory : public RsaKeyFactory {
+    typedef RsaKeyFactory super;
+
+  public:
+    RsaKeymaster0KeyFactory(const SoftKeymasterContext* context, const Keymaster0Engine* engine);
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+  private:
+    const Keymaster0Engine* engine_;
+};
+
+class RsaKeymaster0Key : public RsaKey {
+  public:
+    RsaKeymaster0Key(RSA* rsa_key, const AuthorizationSet& hw_enforced,
+                     const AuthorizationSet& sw_enforced, keymaster_error_t* error)
+        : RsaKey(rsa_key, hw_enforced, sw_enforced, error) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_RSA_KEYMASTER0_KEY_H_
diff --git a/keymaster/rsa_keymaster1_key.cpp b/keymaster/rsa_keymaster1_key.cpp
new file mode 100644
index 0000000..7d8a33f
--- /dev/null
+++ b/keymaster/rsa_keymaster1_key.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright 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.
+ */
+
+#include "rsa_keymaster1_key.h"
+
+#include <memory>
+
+#include <keymaster/logger.h>
+#include <keymaster/soft_keymaster_context.h>
+
+#include "rsa_keymaster1_operation.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+RsaKeymaster1KeyFactory::RsaKeymaster1KeyFactory(const SoftKeymasterContext* context,
+                                                 const Keymaster1Engine* engine)
+    : RsaKeyFactory(context), engine_(engine),
+      sign_factory_(new RsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)),
+      decrypt_factory_(new RsaKeymaster1OperationFactory(KM_PURPOSE_DECRYPT, engine)),
+      // For pubkey ops we can use the normal operation factories.
+      verify_factory_(new RsaVerificationOperationFactory),
+      encrypt_factory_(new RsaEncryptionOperationFactory) {}
+
+static bool is_supported(uint32_t digest) {
+    return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256;
+}
+
+static void UpdateToWorkAroundUnsupportedDigests(const AuthorizationSet& key_description,
+                                                 AuthorizationSet* new_description) {
+    bool have_unsupported_digests = false;
+    bool have_digest_none = false;
+    bool have_pad_none = false;
+    bool have_padding_requiring_digest = false;
+    for (const keymaster_key_param_t& entry : key_description) {
+        new_description->push_back(entry);
+
+        if (entry.tag == TAG_DIGEST) {
+            if (entry.enumerated == KM_DIGEST_NONE) {
+                have_digest_none = true;
+            } else if (!is_supported(entry.enumerated)) {
+                LOG_D("Found request for unsupported digest %u", entry.enumerated);
+                have_unsupported_digests = true;
+            }
+        }
+
+        if (entry.tag == TAG_PADDING) {
+            switch (entry.enumerated) {
+            case KM_PAD_RSA_PSS:
+            case KM_PAD_RSA_OAEP:
+                have_padding_requiring_digest = true;
+                break;
+            case KM_PAD_NONE:
+                have_pad_none = true;
+                break;
+            }
+        }
+    }
+
+    if (have_unsupported_digests && !have_digest_none) {
+        LOG_I("Adding KM_DIGEST_NONE to key authorization, to enable software digesting", 0);
+        new_description->push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    }
+
+    if (have_unsupported_digests && have_padding_requiring_digest && !have_pad_none) {
+        LOG_I("Adding KM_PAD_NONE to key authorization, to enable PSS or OAEP software padding", 0);
+        new_description->push_back(TAG_PADDING, KM_PAD_NONE);
+    }
+}
+
+keymaster_error_t RsaKeymaster1KeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                                       KeymasterKeyBlob* key_blob,
+                                                       AuthorizationSet* hw_enforced,
+                                                       AuthorizationSet* sw_enforced) const {
+    AuthorizationSet key_params_copy;
+    UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
+    return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t RsaKeymaster1KeyFactory::ImportKey(
+    const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format,
+    const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob,
+    AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const {
+    AuthorizationSet key_params_copy;
+    UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy);
+    return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material,
+                              output_key_blob, hw_enforced, sw_enforced);
+}
+
+keymaster_error_t RsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material,
+                                                   const AuthorizationSet& additional_params,
+                                                   const AuthorizationSet& hw_enforced,
+                                                   const AuthorizationSet& sw_enforced,
+                                                   UniquePtr<Key>* key) const {
+    if (!key)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    keymaster_error_t error;
+    unique_ptr<RSA, RSA_Delete> rsa(engine_->BuildRsaKey(key_material, additional_params, &error));
+    if (!rsa)
+        return error;
+
+    key->reset(new (std::nothrow)
+                   RsaKeymaster1Key(rsa.release(), hw_enforced, sw_enforced, &error));
+    if (!key->get())
+        error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return KM_ERROR_OK;
+}
+
+OperationFactory* RsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
+    switch (purpose) {
+    case KM_PURPOSE_SIGN:
+        return sign_factory_.get();
+    case KM_PURPOSE_VERIFY:
+        return verify_factory_.get();
+    case KM_PURPOSE_ENCRYPT:
+        return encrypt_factory_.get();
+    case KM_PURPOSE_DECRYPT:
+        return decrypt_factory_.get();
+    case KM_PURPOSE_DERIVE_KEY:
+        break;
+    }
+    return nullptr;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/rsa_keymaster1_key.h b/keymaster/rsa_keymaster1_key.h
new file mode 100644
index 0000000..dd543dd
--- /dev/null
+++ b/keymaster/rsa_keymaster1_key.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_RSA_KEYMASTER1_KEY_H_
+#define SYSTEM_KEYMASTER_RSA_KEYMASTER1_KEY_H_
+
+#include <openssl/rsa.h>
+
+#include <keymaster/rsa_key_factory.h>
+
+#include "keymaster1_engine.h"
+#include "rsa_key.h"
+
+namespace keymaster {
+
+class SoftKeymasterContext;
+
+/**
+ * RsaKeymaster1KeyFactory is a KeyFactory that creates and loads keys which are actually backed by
+ * a hardware keymaster1 module, but which does not support all keymaster1 digests.  If unsupported
+ * digests are found during generation or import, KM_DIGEST_NONE is added to the key description,
+ * then the operations handle the unsupported digests in software.
+ *
+ * If unsupported digests are requested and KM_PAD_RSA_PSS or KM_PAD_RSA_OAEP is also requested, but
+ * KM_PAD_NONE is not present KM_PAD_NONE will be added to the description, to allow for
+ * software padding as well as software digesting.
+ */
+class RsaKeymaster1KeyFactory : public RsaKeyFactory {
+  public:
+    RsaKeymaster1KeyFactory(const SoftKeymasterContext* context, const Keymaster1Engine* engine);
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    keymaster_error_t LoadKey(const KeymasterKeyBlob& key_material,
+                              const AuthorizationSet& additional_params,
+                              const AuthorizationSet& hw_enforced,
+                              const AuthorizationSet& sw_enforced,
+                              UniquePtr<Key>* key) const override;
+
+    OperationFactory* GetOperationFactory(keymaster_purpose_t purpose) const override;
+
+  private:
+    const Keymaster1Engine* engine_;
+
+    std::unique_ptr<OperationFactory> sign_factory_;
+    std::unique_ptr<OperationFactory> decrypt_factory_;
+    std::unique_ptr<OperationFactory> verify_factory_;
+    std::unique_ptr<OperationFactory> encrypt_factory_;
+};
+
+class RsaKeymaster1Key : public RsaKey {
+  public:
+    RsaKeymaster1Key(RSA* rsa_key, const AuthorizationSet& hw_enforced,
+                     const AuthorizationSet& sw_enforced, keymaster_error_t* error)
+        : RsaKey(rsa_key, hw_enforced, sw_enforced, error) {}
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_RSA_KEYMASTER1_KEY_H_
diff --git a/keymaster/rsa_keymaster1_operation.cpp b/keymaster/rsa_keymaster1_operation.cpp
new file mode 100644
index 0000000..002930e
--- /dev/null
+++ b/keymaster/rsa_keymaster1_operation.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 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.
+ */
+
+#include "rsa_keymaster1_operation.h"
+
+#include <memory>
+
+#include <keymaster/android_keymaster_utils.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+#include "rsa_keymaster1_key.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+keymaster_error_t RsaKeymaster1WrappedOperation::Begin(EVP_PKEY* rsa_key,
+                                                       const AuthorizationSet& input_params) {
+    Keymaster1Engine::KeyData* key_data = engine_->GetData(rsa_key);
+    if (!key_data)
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    // Copy the input params and substitute KM_DIGEST_NONE for whatever was specified.  Also change
+    // KM_PAD_RSA_PSS and KM_PAD_OAEP to KM_PAD_NONE, if necessary. These are the params we'll pass
+    // to the hardware module.  The regular Rsa*Operation classes will do software digesting and
+    // padding where we've told the HW not to.
+    //
+    // The reason we don't change KM_PAD_RSA_PKCS1_1_5_SIGN or KM_PAD_RSA_PKCS1_1_5_ENCRYPT to
+    // KM_PAD_NONE is because the hardware can perform those padding modes, since they don't involve
+    // digesting.
+    //
+    // We also cache in the key the padding value that we expect to be passed to the engine crypto
+    // operation.  This just allows us to double-check that the correct padding value is reaching
+    // that layer.
+    AuthorizationSet begin_params(input_params);
+    int pos = begin_params.find(TAG_DIGEST);
+    if (pos == -1)
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    begin_params[pos].enumerated = KM_DIGEST_NONE;
+
+    pos = begin_params.find(TAG_PADDING);
+    if (pos == -1)
+        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
+    switch (begin_params[pos].enumerated) {
+
+    case KM_PAD_RSA_PSS:
+    case KM_PAD_RSA_OAEP:
+        key_data->expected_openssl_padding = RSA_NO_PADDING;
+        begin_params[pos].enumerated = KM_PAD_NONE;
+        break;
+
+    case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
+    case KM_PAD_RSA_PKCS1_1_5_SIGN:
+        key_data->expected_openssl_padding = RSA_PKCS1_PADDING;
+        break;
+    }
+
+    return engine_->device()->begin(engine_->device(), purpose_, &key_data->key_material,
+                                    &begin_params, nullptr /* out_params */, &operation_handle_);
+}
+
+keymaster_error_t
+RsaKeymaster1WrappedOperation::PrepareFinish(EVP_PKEY* rsa_key,
+                                             const AuthorizationSet& input_params) {
+    Keymaster1Engine::KeyData* key_data = engine_->GetData(rsa_key);
+    if (!key_data) {
+        LOG_E("Could not get extended key data... not a Keymaster1Engine key?", 0);
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+    key_data->op_handle = operation_handle_;
+    key_data->finish_params.Reinitialize(input_params);
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaKeymaster1WrappedOperation::Abort() {
+    return engine_->device()->abort(engine_->device(), operation_handle_);
+}
+
+keymaster_error_t RsaKeymaster1WrappedOperation::GetError(EVP_PKEY* rsa_key) {
+    Keymaster1Engine::KeyData* key_data = engine_->GetData(rsa_key);  // key_data is owned by rsa
+    if (!key_data)
+        return KM_ERROR_UNKNOWN_ERROR;
+    return key_data->error;
+}
+
+static EVP_PKEY* GetEvpKey(const RsaKeymaster1Key& key, keymaster_error_t* error) {
+    if (!key.key()) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
+    if (!key.InternalToEvp(pkey.get())) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+    return pkey.release();
+}
+
+Operation* RsaKeymaster1OperationFactory::CreateOperation(const Key& key,
+                                                          const AuthorizationSet& begin_params,
+                                                          keymaster_error_t* error) {
+    keymaster_digest_t digest;
+    if (!GetAndValidateDigest(begin_params, key, &digest, error))
+        return nullptr;
+
+    keymaster_padding_t padding;
+    if (!GetAndValidatePadding(begin_params, key, &padding, error))
+        return nullptr;
+
+    const RsaKeymaster1Key& rsa_km1_key(static_cast<const RsaKeymaster1Key&>(key));
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetEvpKey(rsa_km1_key, error));
+    if (!rsa)
+        return nullptr;
+
+    switch (purpose_) {
+    case KM_PURPOSE_SIGN:
+        return new RsaKeymaster1Operation<RsaSignOperation>(digest, padding, rsa.release(),
+                                                            engine_);
+    case KM_PURPOSE_DECRYPT:
+        return new RsaKeymaster1Operation<RsaDecryptOperation>(digest, padding, rsa.release(),
+                                                               engine_);
+    default:
+        LOG_E("Bug: Pubkey operation requested.  Those should be handled by normal RSA operations.",
+              0);
+        *error = KM_ERROR_UNSUPPORTED_PURPOSE;
+        return nullptr;
+    }
+}
+
+static const keymaster_digest_t supported_digests[] = {
+    KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
+    KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
+
+const keymaster_digest_t*
+RsaKeymaster1OperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = array_length(supported_digests);
+    return supported_digests;
+}
+
+static const keymaster_padding_t supported_sig_padding[] = {
+    KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN, KM_PAD_RSA_PSS,
+};
+static const keymaster_padding_t supported_crypt_padding[] = {
+    KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, KM_PAD_RSA_OAEP,
+};
+
+const keymaster_padding_t*
+RsaKeymaster1OperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    switch (purpose_) {
+    case KM_PURPOSE_SIGN:
+    case KM_PURPOSE_VERIFY:
+        *padding_mode_count = array_length(supported_sig_padding);
+        return supported_sig_padding;
+    case KM_PURPOSE_ENCRYPT:
+    case KM_PURPOSE_DECRYPT:
+        *padding_mode_count = array_length(supported_crypt_padding);
+        return supported_crypt_padding;
+    default:
+        *padding_mode_count = 0;
+        return nullptr;
+    }
+}
+
+}  // namespace keymaster
diff --git a/keymaster/rsa_keymaster1_operation.h b/keymaster/rsa_keymaster1_operation.h
new file mode 100644
index 0000000..30123f0
--- /dev/null
+++ b/keymaster/rsa_keymaster1_operation.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_RSA_KEYMASTER1_OPERATION_H_
+#define SYSTEM_KEYMASTER_RSA_KEYMASTER1_OPERATION_H_
+
+#include <openssl/evp.h>
+
+#include <hardware/keymaster1.h>
+#include <keymaster/android_keymaster_utils.h>
+
+#include "keymaster1_engine.h"
+#include "rsa_operation.h"
+
+namespace keymaster {
+
+class RsaKeymaster1WrappedOperation {
+  public:
+    RsaKeymaster1WrappedOperation(keymaster_purpose_t purpose, const Keymaster1Engine* engine)
+        : purpose_(purpose), operation_handle_(0), engine_(engine) {}
+    ~RsaKeymaster1WrappedOperation() {
+        if (operation_handle_)
+            Abort();
+    }
+
+    keymaster_error_t Begin(EVP_PKEY* rsa_key, const AuthorizationSet& input_params);
+    keymaster_error_t PrepareFinish(EVP_PKEY* rsa_key, const AuthorizationSet& input_params);
+    void Finish() { operation_handle_ = 0; }
+    keymaster_error_t Abort();
+
+    keymaster_error_t GetError(EVP_PKEY* rsa_key);
+
+  protected:
+    keymaster_purpose_t purpose_;
+    keymaster_operation_handle_t operation_handle_;
+    const Keymaster1Engine* engine_;
+};
+
+template <typename BaseOperation> class RsaKeymaster1Operation : public BaseOperation {
+    typedef BaseOperation super;
+
+  public:
+    RsaKeymaster1Operation(keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key,
+                           const Keymaster1Engine* engine)
+        : BaseOperation(digest, padding, key), wrapped_operation_(super::purpose(), engine) {
+        // Shouldn't be instantiated for public key operations.
+        assert(super::purpose() != KM_PURPOSE_VERIFY);
+        assert(super::purpose() != KM_PURPOSE_ENCRYPT);
+    }
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override {
+        keymaster_error_t error = wrapped_operation_.Begin(super::rsa_key_, input_params);
+        if (error != KM_ERROR_OK)
+            return error;
+        return super::Begin(input_params, output_params);
+    }
+
+    keymaster_error_t Finish(const AuthorizationSet& input_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override {
+        keymaster_error_t error = wrapped_operation_.PrepareFinish(super::rsa_key_, input_params);
+        if (error != KM_ERROR_OK)
+            return error;
+        error = super::Finish(input_params, input, signature, output_params, output);
+        if (wrapped_operation_.GetError(super::rsa_key_) != KM_ERROR_OK)
+            error = wrapped_operation_.GetError(super::rsa_key_);
+        if (error == KM_ERROR_OK)
+            wrapped_operation_.Finish();
+        return error;
+    }
+
+    keymaster_error_t Abort() override {
+        keymaster_error_t error = wrapped_operation_.Abort();
+        if (error != KM_ERROR_OK)
+            return error;
+        return super::Abort();
+    }
+
+  private:
+    RsaKeymaster1WrappedOperation wrapped_operation_;
+};
+
+/**
+ * Factory that produces RsaKeymaster1Operations.  This is instantiated and
+ * provided by RsaKeymaster1KeyFactory.
+ */
+class RsaKeymaster1OperationFactory : public OperationFactory {
+  public:
+    RsaKeymaster1OperationFactory(keymaster_purpose_t purpose, const Keymaster1Engine* engine)
+        : purpose_(purpose), engine_(engine) {}
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_RSA, purpose_); }
+
+    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                               keymaster_error_t* error) override;
+
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override;
+
+  private:
+    keymaster_purpose_t purpose_;
+    const Keymaster1Engine* engine_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_RSA_KEYMASTER1_OPERATION_H_
diff --git a/keymaster/rsa_operation.cpp b/keymaster/rsa_operation.cpp
new file mode 100644
index 0000000..2046a64
--- /dev/null
+++ b/keymaster/rsa_operation.cpp
@@ -0,0 +1,619 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "rsa_operation.h"
+
+#include <limits.h>
+
+#include <new>
+
+#include <openssl/err.h>
+
+#include <keymaster/logger.h>
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
+#include "rsa_key.h"
+
+namespace keymaster {
+
+const size_t kPssOverhead = 2;
+const size_t kMinPssSaltSize = 20;
+
+// Overhead for PKCS#1 v1.5 signature padding of undigested messages.  Digested messages have
+// additional overhead, for the digest algorithmIdentifier required by PKCS#1.
+const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11;
+
+/* static */
+EVP_PKEY* RsaOperationFactory::GetRsaKey(const Key& key, keymaster_error_t* error) {
+    const RsaKey* rsa_key = static_cast<const RsaKey*>(&key);
+    assert(rsa_key);
+    if (!rsa_key || !rsa_key->key()) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
+    if (!rsa_key->InternalToEvp(pkey.get())) {
+        *error = KM_ERROR_UNKNOWN_ERROR;
+        return nullptr;
+    }
+    return pkey.release();
+}
+
+static const keymaster_digest_t supported_digests[] = {
+    KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
+    KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
+
+const keymaster_digest_t* RsaOperationFactory::SupportedDigests(size_t* digest_count) const {
+    *digest_count = array_length(supported_digests);
+    return supported_digests;
+}
+
+RsaOperation* RsaOperationFactory::CreateRsaOperation(const Key& key,
+                                                      const AuthorizationSet& begin_params,
+                                                      keymaster_error_t* error) {
+    keymaster_padding_t padding;
+    if (!GetAndValidatePadding(begin_params, key, &padding, error))
+        return nullptr;
+
+    bool require_digest = (purpose() == KM_PURPOSE_SIGN || purpose() == KM_PURPOSE_VERIFY ||
+                           padding == KM_PAD_RSA_OAEP);
+
+    keymaster_digest_t digest = KM_DIGEST_NONE;
+    if (require_digest && !GetAndValidateDigest(begin_params, key, &digest, error))
+        return nullptr;
+
+    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> rsa(GetRsaKey(key, error));
+    if (!rsa.get())
+        return nullptr;
+
+    RsaOperation* op = InstantiateOperation(digest, padding, rsa.release());
+    if (!op)
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return op;
+}
+
+static const keymaster_padding_t supported_sig_padding[] = {KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN,
+                                                            KM_PAD_RSA_PSS};
+const keymaster_padding_t*
+RsaDigestingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    *padding_mode_count = array_length(supported_sig_padding);
+    return supported_sig_padding;
+}
+
+RsaOperation* RsaCryptingOperationFactory::CreateRsaOperation(const Key& key,
+                                                              const AuthorizationSet& begin_params,
+                                                              keymaster_error_t* error) {
+    UniquePtr<RsaOperation> op(RsaOperationFactory::CreateRsaOperation(key, begin_params, error));
+    if (op.get()) {
+        switch (op->padding()) {
+        case KM_PAD_NONE:
+        case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
+            if (op->digest() != KM_DIGEST_NONE) {
+                *error = KM_ERROR_INCOMPATIBLE_DIGEST;
+                return nullptr;
+            }
+            break;
+
+        case KM_PAD_RSA_OAEP:
+            if (op->digest() == KM_DIGEST_NONE) {
+                *error = KM_ERROR_INCOMPATIBLE_DIGEST;
+                return nullptr;
+            }
+            break;
+
+        default:
+            *error = KM_ERROR_UNSUPPORTED_PADDING_MODE;
+            return nullptr;
+        }
+    }
+    return op.release();
+}
+
+static const keymaster_padding_t supported_crypt_padding[] = {KM_PAD_NONE, KM_PAD_RSA_OAEP,
+                                                              KM_PAD_RSA_PKCS1_1_5_ENCRYPT};
+const keymaster_padding_t*
+RsaCryptingOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
+    *padding_mode_count = array_length(supported_crypt_padding);
+    return supported_crypt_padding;
+}
+
+RsaOperation::~RsaOperation() {
+    if (rsa_key_ != NULL)
+        EVP_PKEY_free(rsa_key_);
+}
+
+keymaster_error_t RsaOperation::Begin(const AuthorizationSet& /* input_params */,
+                                      AuthorizationSet* /* output_params */) {
+    return InitDigest();
+}
+
+keymaster_error_t RsaOperation::Update(const AuthorizationSet& /* additional_params */,
+                                       const Buffer& input, AuthorizationSet* /* output_params */,
+                                       Buffer* /* output */, size_t* input_consumed) {
+    assert(input_consumed);
+    switch (purpose()) {
+    default:
+        return KM_ERROR_UNIMPLEMENTED;
+    case KM_PURPOSE_SIGN:
+    case KM_PURPOSE_VERIFY:
+    case KM_PURPOSE_ENCRYPT:
+    case KM_PURPOSE_DECRYPT:
+        return StoreData(input, input_consumed);
+    }
+}
+
+keymaster_error_t RsaOperation::StoreData(const Buffer& input, size_t* input_consumed) {
+    assert(input_consumed);
+
+    if (!data_.reserve(EVP_PKEY_size(rsa_key_)))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    // If the write fails, it's because input length exceeds key size.
+    if (!data_.write(input.peek_read(), input.available_read())) {
+        LOG_E("Input too long: cannot operate on %u bytes of data with %u-byte RSA key",
+              input.available_read() + data_.available_read(), EVP_PKEY_size(rsa_key_));
+        return KM_ERROR_INVALID_INPUT_LENGTH;
+    }
+
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaOperation::SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx) {
+    keymaster_error_t error;
+    int openssl_padding = GetOpensslPadding(&error);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, openssl_padding) <= 0)
+        return TranslateLastOpenSslError();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaOperation::InitDigest() {
+    if (digest_ == KM_DIGEST_NONE) {
+        if (require_digest())
+            return KM_ERROR_INCOMPATIBLE_DIGEST;
+        return KM_ERROR_OK;
+    }
+
+    switch (digest_) {
+    case KM_DIGEST_NONE:
+        return KM_ERROR_OK;
+    case KM_DIGEST_MD5:
+        digest_algorithm_ = EVP_md5();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA1:
+        digest_algorithm_ = EVP_sha1();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_224:
+        digest_algorithm_ = EVP_sha224();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_256:
+        digest_algorithm_ = EVP_sha256();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_384:
+        digest_algorithm_ = EVP_sha384();
+        return KM_ERROR_OK;
+    case KM_DIGEST_SHA_2_512:
+        digest_algorithm_ = EVP_sha512();
+        return KM_ERROR_OK;
+    default:
+        return KM_ERROR_UNSUPPORTED_DIGEST;
+    }
+}
+
+RsaDigestingOperation::RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
+                                             keymaster_padding_t padding, EVP_PKEY* key)
+    : RsaOperation(purpose, digest, padding, key) {
+    EVP_MD_CTX_init(&digest_ctx_);
+}
+RsaDigestingOperation::~RsaDigestingOperation() {
+    EVP_MD_CTX_cleanup(&digest_ctx_);
+}
+
+int RsaDigestingOperation::GetOpensslPadding(keymaster_error_t* error) {
+    *error = KM_ERROR_OK;
+    switch (padding_) {
+    case KM_PAD_NONE:
+        return RSA_NO_PADDING;
+    case KM_PAD_RSA_PKCS1_1_5_SIGN:
+        return RSA_PKCS1_PADDING;
+    case KM_PAD_RSA_PSS:
+        if (digest_ == KM_DIGEST_NONE) {
+            *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
+            return -1;
+        }
+        if (EVP_MD_size(digest_algorithm_) + kPssOverhead + kMinPssSaltSize >
+            (size_t)EVP_PKEY_size(rsa_key_)) {
+            LOG_E("Input too long: %d-byte digest cannot be used with %d-byte RSA key in PSS "
+                  "padding mode",
+                  EVP_MD_size(digest_algorithm_), EVP_PKEY_size(rsa_key_));
+            *error = KM_ERROR_INCOMPATIBLE_DIGEST;
+            return -1;
+        }
+        return RSA_PKCS1_PSS_PADDING;
+    default:
+        return -1;
+    }
+}
+
+keymaster_error_t RsaSignOperation::Begin(const AuthorizationSet& input_params,
+                                          AuthorizationSet* output_params) {
+    keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE)
+        return KM_ERROR_OK;
+
+    EVP_PKEY_CTX* pkey_ctx;
+    if (EVP_DigestSignInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, nullptr /* engine */,
+                           rsa_key_) != 1)
+        return TranslateLastOpenSslError();
+    return SetRsaPaddingInEvpContext(pkey_ctx);
+}
+
+keymaster_error_t RsaSignOperation::Update(const AuthorizationSet& additional_params,
+                                           const Buffer& input, AuthorizationSet* output_params,
+                                           Buffer* output, size_t* input_consumed) {
+    if (digest_ == KM_DIGEST_NONE)
+        // Just buffer the data.
+        return RsaOperation::Update(additional_params, input, output_params, output,
+                                    input_consumed);
+
+    if (EVP_DigestSignUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
+        return TranslateLastOpenSslError();
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaSignOperation::Finish(const AuthorizationSet& additional_params,
+                                           const Buffer& input, const Buffer& /* signature */,
+                                           AuthorizationSet* /* output_params */, Buffer* output) {
+    assert(output);
+
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE)
+        return SignUndigested(output);
+    else
+        return SignDigested(output);
+}
+
+static keymaster_error_t zero_pad_left(UniquePtr<uint8_t[]>* dest, size_t padded_len, Buffer& src) {
+    assert(padded_len > src.available_read());
+
+    dest->reset(new uint8_t[padded_len]);
+    if (!dest->get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    size_t padding_len = padded_len - src.available_read();
+    memset(dest->get(), 0, padding_len);
+    if (!src.read(dest->get() + padding_len, src.available_read()))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaSignOperation::SignUndigested(Buffer* output) {
+    UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
+    if (!rsa.get())
+        return TranslateLastOpenSslError();
+
+    if (!output->Reinitialize(RSA_size(rsa.get())))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    size_t key_len = EVP_PKEY_size(rsa_key_);
+    int bytes_encrypted;
+    switch (padding_) {
+    case KM_PAD_NONE: {
+        const uint8_t* to_encrypt = data_.peek_read();
+        UniquePtr<uint8_t[]> zero_padded;
+        if (data_.available_read() > key_len) {
+            return KM_ERROR_INVALID_INPUT_LENGTH;
+        } else if (data_.available_read() < key_len) {
+            keymaster_error_t error = zero_pad_left(&zero_padded, key_len, data_);
+            if (error != KM_ERROR_OK)
+                return error;
+            to_encrypt = zero_padded.get();
+        }
+        bytes_encrypted = RSA_private_encrypt(key_len, to_encrypt, output->peek_write(), rsa.get(),
+                                              RSA_NO_PADDING);
+        break;
+    }
+    case KM_PAD_RSA_PKCS1_1_5_SIGN:
+        // Does PKCS1 padding without digesting even make sense?  Dunno.  We'll support it.
+        if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
+            LOG_E("Input too long: cannot sign %u-byte message with PKCS1 padding with %u-bit key",
+                  data_.available_read(), EVP_PKEY_size(rsa_key_) * 8);
+            return KM_ERROR_INVALID_INPUT_LENGTH;
+        }
+        bytes_encrypted = RSA_private_encrypt(data_.available_read(), data_.peek_read(),
+                                              output->peek_write(), rsa.get(), RSA_PKCS1_PADDING);
+        break;
+
+    default:
+        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
+    }
+
+    if (bytes_encrypted <= 0)
+        return TranslateLastOpenSslError();
+    if (!output->advance_write(bytes_encrypted))
+        return KM_ERROR_UNKNOWN_ERROR;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaSignOperation::SignDigested(Buffer* output) {
+    size_t siglen;
+    if (EVP_DigestSignFinal(&digest_ctx_, nullptr /* signature */, &siglen) != 1)
+        return TranslateLastOpenSslError();
+
+    if (!output->Reinitialize(siglen))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (EVP_DigestSignFinal(&digest_ctx_, output->peek_write(), &siglen) <= 0)
+        return TranslateLastOpenSslError();
+    if (!output->advance_write(siglen))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaVerifyOperation::Begin(const AuthorizationSet& input_params,
+                                            AuthorizationSet* output_params) {
+    keymaster_error_t error = RsaDigestingOperation::Begin(input_params, output_params);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE)
+        return KM_ERROR_OK;
+
+    EVP_PKEY_CTX* pkey_ctx;
+    if (EVP_DigestVerifyInit(&digest_ctx_, &pkey_ctx, digest_algorithm_, NULL, rsa_key_) != 1)
+        return TranslateLastOpenSslError();
+    return SetRsaPaddingInEvpContext(pkey_ctx);
+}
+
+keymaster_error_t RsaVerifyOperation::Update(const AuthorizationSet& additional_params,
+                                             const Buffer& input, AuthorizationSet* output_params,
+                                             Buffer* output, size_t* input_consumed) {
+    if (digest_ == KM_DIGEST_NONE)
+        // Just buffer the data.
+        return RsaOperation::Update(additional_params, input, output_params, output,
+                                    input_consumed);
+
+    if (EVP_DigestVerifyUpdate(&digest_ctx_, input.peek_read(), input.available_read()) != 1)
+        return TranslateLastOpenSslError();
+    *input_consumed = input.available_read();
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaVerifyOperation::Finish(const AuthorizationSet& additional_params,
+                                             const Buffer& input, const Buffer& signature,
+                                             AuthorizationSet* /* output_params */,
+                                             Buffer* /* output */) {
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (digest_ == KM_DIGEST_NONE)
+        return VerifyUndigested(signature);
+    else
+        return VerifyDigested(signature);
+}
+
+keymaster_error_t RsaVerifyOperation::VerifyUndigested(const Buffer& signature) {
+    UniquePtr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(rsa_key_)));
+    if (!rsa.get())
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    size_t key_len = RSA_size(rsa.get());
+    int openssl_padding;
+    switch (padding_) {
+    case KM_PAD_NONE:
+        if (data_.available_read() > key_len)
+            return KM_ERROR_INVALID_INPUT_LENGTH;
+        if (key_len != signature.available_read())
+            return KM_ERROR_VERIFICATION_FAILED;
+        openssl_padding = RSA_NO_PADDING;
+        break;
+    case KM_PAD_RSA_PKCS1_1_5_SIGN:
+        if (data_.available_read() + kPkcs1UndigestedSignaturePaddingOverhead > key_len) {
+            LOG_E("Input too long: cannot verify %u-byte message with PKCS1 padding && %u-bit key",
+                  data_.available_read(), key_len * 8);
+            return KM_ERROR_INVALID_INPUT_LENGTH;
+        }
+        openssl_padding = RSA_PKCS1_PADDING;
+        break;
+    default:
+        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
+    }
+
+    UniquePtr<uint8_t[]> decrypted_data(new (std::nothrow) uint8_t[key_len]);
+    if (!decrypted_data.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    int bytes_decrypted = RSA_public_decrypt(signature.available_read(), signature.peek_read(),
+                                             decrypted_data.get(), rsa.get(), openssl_padding);
+    if (bytes_decrypted < 0)
+        return KM_ERROR_VERIFICATION_FAILED;
+
+    const uint8_t* compare_pos = decrypted_data.get();
+    size_t bytes_to_compare = bytes_decrypted;
+    uint8_t zero_check_result = 0;
+    if (padding_ == KM_PAD_NONE && data_.available_read() < bytes_to_compare) {
+        // If the data is short, for "unpadded" signing we zero-pad to the left.  So during
+        // verification we should have zeros on the left of the decrypted data.  Do a constant-time
+        // check.
+        const uint8_t* zero_end = compare_pos + bytes_to_compare - data_.available_read();
+        while (compare_pos < zero_end)
+            zero_check_result |= *compare_pos++;
+        bytes_to_compare = data_.available_read();
+    }
+    if (memcmp_s(compare_pos, data_.peek_read(), bytes_to_compare) != 0 || zero_check_result != 0)
+        return KM_ERROR_VERIFICATION_FAILED;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaVerifyOperation::VerifyDigested(const Buffer& signature) {
+    if (!EVP_DigestVerifyFinal(&digest_ctx_, signature.peek_read(), signature.available_read()))
+        return KM_ERROR_VERIFICATION_FAILED;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaCryptOperation::SetOaepDigestIfRequired(EVP_PKEY_CTX* pkey_ctx) {
+    if (padding() != KM_PAD_RSA_OAEP)
+        return KM_ERROR_OK;
+
+    assert(digest_algorithm_ != nullptr);
+    if (!EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, digest_algorithm_))
+        return TranslateLastOpenSslError();
+
+    // MGF1 MD is always SHA1.
+    if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha1()))
+        return TranslateLastOpenSslError();
+
+    return KM_ERROR_OK;
+}
+
+int RsaCryptOperation::GetOpensslPadding(keymaster_error_t* error) {
+    *error = KM_ERROR_OK;
+    switch (padding_) {
+    case KM_PAD_NONE:
+        return RSA_NO_PADDING;
+    case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
+        return RSA_PKCS1_PADDING;
+    case KM_PAD_RSA_OAEP:
+        return RSA_PKCS1_OAEP_PADDING;
+    default:
+        return -1;
+    }
+}
+
+struct EVP_PKEY_CTX_Delete {
+    void operator()(EVP_PKEY_CTX* p) { EVP_PKEY_CTX_free(p); }
+};
+
+keymaster_error_t RsaEncryptOperation::Finish(const AuthorizationSet& additional_params,
+                                              const Buffer& input, const Buffer& /* signature */,
+                                              AuthorizationSet* /* output_params */,
+                                              Buffer* output) {
+    if (!output)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
+        EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
+    if (!ctx.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (EVP_PKEY_encrypt_init(ctx.get()) <= 0)
+        return TranslateLastOpenSslError();
+
+    error = SetRsaPaddingInEvpContext(ctx.get());
+    if (error != KM_ERROR_OK)
+        return error;
+    error = SetOaepDigestIfRequired(ctx.get());
+    if (error != KM_ERROR_OK)
+        return error;
+
+    size_t outlen;
+    if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
+                         data_.available_read()) <= 0)
+        return TranslateLastOpenSslError();
+
+    if (!output->Reinitialize(outlen))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    const uint8_t* to_encrypt = data_.peek_read();
+    size_t to_encrypt_len = data_.available_read();
+    UniquePtr<uint8_t[]> zero_padded;
+    if (padding_ == KM_PAD_NONE && to_encrypt_len < outlen) {
+        keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
+        if (error != KM_ERROR_OK)
+            return error;
+        to_encrypt = zero_padded.get();
+        to_encrypt_len = outlen;
+    }
+
+    if (EVP_PKEY_encrypt(ctx.get(), output->peek_write(), &outlen, to_encrypt, to_encrypt_len) <= 0)
+        return TranslateLastOpenSslError();
+    if (!output->advance_write(outlen))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t RsaDecryptOperation::Finish(const AuthorizationSet& additional_params,
+                                              const Buffer& input, const Buffer& /* signature */,
+                                              AuthorizationSet* /* output_params */,
+                                              Buffer* output) {
+    if (!output)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    keymaster_error_t error = UpdateForFinish(additional_params, input);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    UniquePtr<EVP_PKEY_CTX, EVP_PKEY_CTX_Delete> ctx(
+        EVP_PKEY_CTX_new(rsa_key_, nullptr /* engine */));
+    if (!ctx.get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    if (EVP_PKEY_decrypt_init(ctx.get()) <= 0)
+        return TranslateLastOpenSslError();
+
+    error = SetRsaPaddingInEvpContext(ctx.get());
+    if (error != KM_ERROR_OK)
+        return error;
+    error = SetOaepDigestIfRequired(ctx.get());
+    if (error != KM_ERROR_OK)
+        return error;
+
+    size_t outlen;
+    if (EVP_PKEY_decrypt(ctx.get(), nullptr /* out */, &outlen, data_.peek_read(),
+                         data_.available_read()) <= 0)
+        return TranslateLastOpenSslError();
+
+    if (!output->Reinitialize(outlen))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    const uint8_t* to_decrypt = data_.peek_read();
+    size_t to_decrypt_len = data_.available_read();
+    UniquePtr<uint8_t[]> zero_padded;
+    if (padding_ == KM_PAD_NONE && to_decrypt_len < outlen) {
+        keymaster_error_t error = zero_pad_left(&zero_padded, outlen, data_);
+        if (error != KM_ERROR_OK)
+            return error;
+        to_decrypt = zero_padded.get();
+        to_decrypt_len = outlen;
+    }
+
+    if (EVP_PKEY_decrypt(ctx.get(), output->peek_write(), &outlen, to_decrypt, to_decrypt_len) <= 0)
+        return TranslateLastOpenSslError();
+    if (!output->advance_write(outlen))
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/rsa_operation.h b/keymaster/rsa_operation.h
new file mode 100644
index 0000000..8283f2e
--- /dev/null
+++ b/keymaster/rsa_operation.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_RSA_OPERATION_H_
+#define SYSTEM_KEYMASTER_RSA_OPERATION_H_
+
+#include <UniquePtr.h>
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
+#include "operation.h"
+
+namespace keymaster {
+
+/**
+ * Base class for all RSA operations.
+ *
+ * This class provides RSA key management, plus buffering of data for non-digesting modes.
+ */
+class RsaOperation : public Operation {
+  public:
+    RsaOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
+                 keymaster_padding_t padding, EVP_PKEY* key)
+        : Operation(purpose), rsa_key_(key), padding_(padding), digest_(digest),
+          digest_algorithm_(nullptr) {}
+    ~RsaOperation();
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Abort() override { return KM_ERROR_OK; }
+
+    keymaster_padding_t padding() const { return padding_; }
+    keymaster_digest_t digest() const { return digest_; }
+
+  protected:
+    virtual int GetOpensslPadding(keymaster_error_t* error) = 0;
+    virtual bool require_digest() const = 0;
+
+    keymaster_error_t StoreData(const Buffer& input, size_t* input_consumed);
+    keymaster_error_t SetRsaPaddingInEvpContext(EVP_PKEY_CTX* pkey_ctx);
+    keymaster_error_t InitDigest();
+
+    EVP_PKEY* rsa_key_;
+    const keymaster_padding_t padding_;
+    Buffer data_;
+    const keymaster_digest_t digest_;
+    const EVP_MD* digest_algorithm_;
+};
+
+/**
+ * Base class for all digesting RSA operations.
+ *
+ * This class adds digesting support, for digesting modes.  For non-digesting modes, it falls back
+ * on the RsaOperation input buffering.
+ */
+class RsaDigestingOperation : public RsaOperation {
+  public:
+    RsaDigestingOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
+                          keymaster_padding_t padding, EVP_PKEY* key);
+    ~RsaDigestingOperation();
+
+  protected:
+    int GetOpensslPadding(keymaster_error_t* error) override;
+    bool require_digest() const override { return padding_ == KM_PAD_RSA_PSS; }
+    EVP_MD_CTX digest_ctx_;
+};
+
+/**
+ * RSA private key signing operation.
+ */
+class RsaSignOperation : public RsaDigestingOperation {
+  public:
+    RsaSignOperation(keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
+        : RsaDigestingOperation(KM_PURPOSE_SIGN, digest, padding, key) {}
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+
+  private:
+    keymaster_error_t SignUndigested(Buffer* output);
+    keymaster_error_t SignDigested(Buffer* output);
+};
+
+/**
+ * RSA public key verification operation.
+ */
+class RsaVerifyOperation : public RsaDigestingOperation {
+  public:
+    RsaVerifyOperation(keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
+        : RsaDigestingOperation(KM_PURPOSE_VERIFY, digest, padding, key) {}
+
+    keymaster_error_t Begin(const AuthorizationSet& input_params,
+                            AuthorizationSet* output_params) override;
+    keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
+                             AuthorizationSet* output_params, Buffer* output,
+                             size_t* input_consumed) override;
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+
+  private:
+    keymaster_error_t VerifyUndigested(const Buffer& signature);
+    keymaster_error_t VerifyDigested(const Buffer& signature);
+};
+
+/**
+ * Base class for RSA crypting operations.
+ */
+class RsaCryptOperation : public RsaOperation {
+  public:
+    RsaCryptOperation(keymaster_purpose_t purpose, keymaster_digest_t digest,
+                      keymaster_padding_t padding, EVP_PKEY* key)
+        : RsaOperation(purpose, digest, padding, key) {}
+
+  protected:
+    keymaster_error_t SetOaepDigestIfRequired(EVP_PKEY_CTX* pkey_ctx);
+
+  private:
+    int GetOpensslPadding(keymaster_error_t* error) override;
+    bool require_digest() const override { return padding_ == KM_PAD_RSA_OAEP; }
+};
+
+/**
+ * RSA public key encryption operation.
+ */
+class RsaEncryptOperation : public RsaCryptOperation {
+  public:
+    RsaEncryptOperation(keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
+        : RsaCryptOperation(KM_PURPOSE_ENCRYPT, digest, padding, key) {}
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+};
+
+/**
+ * RSA private key decryption operation.
+ */
+class RsaDecryptOperation : public RsaCryptOperation {
+  public:
+    RsaDecryptOperation(keymaster_digest_t digest, keymaster_padding_t padding, EVP_PKEY* key)
+        : RsaCryptOperation(KM_PURPOSE_DECRYPT, digest, padding, key) {}
+    keymaster_error_t Finish(const AuthorizationSet& additional_params, const Buffer& input,
+                             const Buffer& signature, AuthorizationSet* output_params,
+                             Buffer* output) override;
+};
+
+/**
+ * Abstract base for all RSA operation factories.  This class exists mainly to centralize some code
+ * common to all RSA operation factories.
+ */
+class RsaOperationFactory : public OperationFactory {
+  public:
+    KeyType registry_key() const override { return KeyType(KM_ALGORITHM_RSA, purpose()); }
+    virtual keymaster_purpose_t purpose() const = 0;
+
+    Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
+                               keymaster_error_t* error) override {
+        return CreateRsaOperation(key, begin_params, error);
+    }
+    const keymaster_digest_t* SupportedDigests(size_t* digest_count) const override;
+
+  protected:
+    static EVP_PKEY* GetRsaKey(const Key& key, keymaster_error_t* error);
+    virtual RsaOperation* CreateRsaOperation(const Key& key, const AuthorizationSet& begin_params,
+                                             keymaster_error_t* error);
+
+  private:
+    virtual RsaOperation* InstantiateOperation(keymaster_digest_t digest,
+                                               keymaster_padding_t padding, EVP_PKEY* key) = 0;
+};
+
+/**
+ * Abstract base for RSA operations that digest their input (signing and verification).
+ */
+class RsaDigestingOperationFactory : public RsaOperationFactory {
+  public:
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override;
+};
+
+/**
+ * Abstract base for en/de-crypting RSA operation factories.  This class does most of the work of
+ * creating such operations, delegating only the actual operation instantiation.
+ */
+class RsaCryptingOperationFactory : public RsaOperationFactory {
+  public:
+    RsaOperation* CreateRsaOperation(const Key& key, const AuthorizationSet& begin_params,
+                                     keymaster_error_t* error) override;
+    const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const override;
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
+  public:
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_SIGN; }
+    RsaOperation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                       EVP_PKEY* key) override {
+        return new (std::nothrow) RsaSignOperation(digest, padding, key);
+    }
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_VERIFY; }
+    RsaOperation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                       EVP_PKEY* key) override {
+        return new (std::nothrow) RsaVerifyOperation(digest, padding, key);
+    }
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_ENCRYPT; }
+    RsaOperation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                       EVP_PKEY* key) override {
+        return new (std::nothrow) RsaEncryptOperation(digest, padding, key);
+    }
+};
+
+/**
+ * Concrete factory for RSA signing operations.
+ */
+class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
+    keymaster_purpose_t purpose() const override { return KM_PURPOSE_DECRYPT; }
+    RsaOperation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                       EVP_PKEY* key) override {
+        return new (std::nothrow) RsaDecryptOperation(digest, padding, key);
+    }
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_RSA_OPERATION_H_
diff --git a/keymaster/rsa_privkey_pk8.der b/keymaster/rsa_privkey_pk8.der
new file mode 100644
index 0000000..0336f80
--- /dev/null
+++ b/keymaster/rsa_privkey_pk8.der
Binary files differ
diff --git a/keymaster/serializable.cpp b/keymaster/serializable.cpp
new file mode 100644
index 0000000..5db64f8
--- /dev/null
+++ b/keymaster/serializable.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include <keymaster/serializable.h>
+
+#include <assert.h>
+
+#include <new>
+
+#include <keymaster/android_keymaster_utils.h>
+
+namespace keymaster {
+
+uint8_t* append_to_buf(uint8_t* buf, const uint8_t* end, const void* data, size_t data_len) {
+    if (buf + data_len < buf)  // Pointer wrap check
+        return buf;
+
+    if (buf + data_len <= end) {
+        memcpy(buf, data, data_len);
+        return buf + data_len;
+    }
+    return buf;
+}
+
+bool copy_from_buf(const uint8_t** buf_ptr, const uint8_t* end, void* dest, size_t size) {
+    if (*buf_ptr + size < *buf_ptr)  // Pointer wrap check
+        return false;
+
+    if (end < *buf_ptr + size)
+        return false;
+    memcpy(dest, *buf_ptr, size);
+    *buf_ptr += size;
+    return true;
+}
+
+bool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, size_t* size,
+                                 UniquePtr<uint8_t[]>* dest) {
+    if (!copy_uint32_from_buf(buf_ptr, end, size))
+        return false;
+
+    if (*buf_ptr + *size < *buf_ptr)  // Pointer wrap check
+        return false;
+
+    if (*buf_ptr + *size > end)
+        return false;
+
+    if (*size == 0) {
+        dest->reset();
+        return true;
+    }
+    dest->reset(new (std::nothrow) uint8_t[*size]);
+    if (!dest->get())
+        return false;
+    return copy_from_buf(buf_ptr, end, dest->get(), *size);
+}
+
+bool Buffer::reserve(size_t size) {
+    if (available_write() < size) {
+        size_t new_size = buffer_size_ + size - available_write();
+        uint8_t* new_buffer = new (std::nothrow) uint8_t[new_size];
+        if (!new_buffer)
+            return false;
+        memcpy(new_buffer, buffer_.get() + read_position_, available_read());
+        memset_s(buffer_.get(), 0, buffer_size_);
+        buffer_.reset(new_buffer);
+        buffer_size_ = new_size;
+        write_position_ -= read_position_;
+        read_position_ = 0;
+    }
+    return true;
+}
+
+bool Buffer::Reinitialize(size_t size) {
+    Clear();
+    buffer_.reset(new (std::nothrow) uint8_t[size]);
+    if (!buffer_.get())
+        return false;
+    buffer_size_ = size;
+    read_position_ = 0;
+    write_position_ = 0;
+    return true;
+}
+
+bool Buffer::Reinitialize(const void* data, size_t data_len) {
+    Clear();
+    if (static_cast<const uint8_t*>(data) + data_len < data)  // Pointer wrap check
+        return false;
+    buffer_.reset(new (std::nothrow) uint8_t[data_len]);
+    if (!buffer_.get())
+        return false;
+    buffer_size_ = data_len;
+    memcpy(buffer_.get(), data, data_len);
+    read_position_ = 0;
+    write_position_ = buffer_size_;
+    return true;
+}
+
+size_t Buffer::available_write() const {
+    assert(buffer_size_ >= write_position_);
+    return buffer_size_ - write_position_;
+}
+
+size_t Buffer::available_read() const {
+    assert(buffer_size_ >= write_position_);
+    assert(write_position_ >= read_position_);
+    return write_position_ - read_position_;
+}
+
+bool Buffer::write(const uint8_t* src, size_t write_length) {
+    if (available_write() < write_length)
+        return false;
+    memcpy(buffer_.get() + write_position_, src, write_length);
+    write_position_ += write_length;
+    return true;
+}
+
+bool Buffer::read(uint8_t* dest, size_t read_length) {
+    if (available_read() < read_length)
+        return false;
+    memcpy(dest, buffer_.get() + read_position_, read_length);
+    read_position_ += read_length;
+    return true;
+}
+
+size_t Buffer::SerializedSize() const {
+    return sizeof(uint32_t) + available_read();
+}
+
+uint8_t* Buffer::Serialize(uint8_t* buf, const uint8_t* end) const {
+    return append_size_and_data_to_buf(buf, end, peek_read(), available_read());
+}
+
+bool Buffer::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) {
+    Clear();
+    if (!copy_size_and_data_from_buf(buf_ptr, end, &buffer_size_, &buffer_)) {
+        buffer_.reset();
+        buffer_size_ = 0;
+        return false;
+    }
+    write_position_ = buffer_size_;
+    return true;
+}
+
+void Buffer::Clear() {
+    memset_s(buffer_.get(), 0, buffer_size_);
+    buffer_.reset();
+    read_position_ = 0;
+    write_position_ = 0;
+    buffer_size_ = 0;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/soft_keymaster_context.cpp b/keymaster/soft_keymaster_context.cpp
new file mode 100644
index 0000000..a143245
--- /dev/null
+++ b/keymaster/soft_keymaster_context.cpp
@@ -0,0 +1,883 @@
+/*
+ * Copyright 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.
+ */
+
+#include <keymaster/soft_keymaster_context.h>
+
+#include <memory>
+#include <time.h>
+
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+
+#include "aes_key.h"
+#include "auth_encrypted_key_blob.h"
+#include "ec_keymaster0_key.h"
+#include "ec_keymaster1_key.h"
+#include "hmac_key.h"
+#include "integrity_assured_key_blob.h"
+#include "keymaster0_engine.h"
+#include "ocb_utils.h"
+#include "openssl_err.h"
+#include "rsa_keymaster0_key.h"
+#include "rsa_keymaster1_key.h"
+
+using std::unique_ptr;
+
+namespace keymaster {
+
+namespace {
+static uint8_t master_key_bytes[AES_BLOCK_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const KeymasterKeyBlob MASTER_KEY(master_key_bytes, array_length(master_key_bytes));
+
+static uint8_t kRsaAttestKey[] = {
+    0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc0, 0x83, 0x23, 0xdc, 0x56,
+    0x88, 0x1b, 0xb8, 0x30, 0x20, 0x69, 0xf5, 0xb0, 0x85, 0x61, 0xc6, 0xee, 0xbe, 0x7f, 0x05, 0xe2,
+    0xf5, 0xa8, 0x42, 0x04, 0x8a, 0xbe, 0x8b, 0x47, 0xbe, 0x76, 0xfe, 0xae, 0xf2, 0x5c, 0xf2, 0x9b,
+    0x2a, 0xfa, 0x32, 0x00, 0x14, 0x16, 0x01, 0x42, 0x99, 0x89, 0xa1, 0x5f, 0xcf, 0xc6, 0x81, 0x5e,
+    0xb3, 0x63, 0x58, 0x3c, 0x2f, 0xd2, 0xf2, 0x0b, 0xe4, 0x98, 0x32, 0x83, 0xdd, 0x81, 0x4b, 0x16,
+    0xd7, 0xe1, 0x85, 0x41, 0x7a, 0xe5, 0x4a, 0xbc, 0x29, 0x6a, 0x3a, 0x6d, 0xb5, 0xc0, 0x04, 0x08,
+    0x3b, 0x68, 0xc5, 0x56, 0xc1, 0xf0, 0x23, 0x39, 0x91, 0x64, 0x19, 0x86, 0x4d, 0x50, 0xb7, 0x4d,
+    0x40, 0xae, 0xca, 0x48, 0x4c, 0x77, 0x35, 0x6c, 0x89, 0x5a, 0x0c, 0x27, 0x5a, 0xbf, 0xac, 0x49,
+    0x9d, 0x5d, 0x7d, 0x23, 0x62, 0xf2, 0x9c, 0x5e, 0x02, 0xe8, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01,
+    0x02, 0x81, 0x81, 0x00, 0xbe, 0x86, 0x0b, 0x0b, 0x99, 0xa8, 0x02, 0xa6, 0xfb, 0x1a, 0x59, 0x43,
+    0x8a, 0x7b, 0xb7, 0x15, 0x06, 0x5b, 0x09, 0xa3, 0x6d, 0xc6, 0xe9, 0xca, 0xcc, 0x6b, 0xf3, 0xc0,
+    0x2c, 0x34, 0xd7, 0xd7, 0x9e, 0x94, 0xc6, 0x60, 0x64, 0x28, 0xd8, 0x8c, 0x7b, 0x7f, 0x65, 0x77,
+    0xc1, 0xcd, 0xea, 0x64, 0x07, 0x4a, 0xbe, 0x8e, 0x72, 0x86, 0xdf, 0x1f, 0x08, 0x11, 0xdc, 0x97,
+    0x28, 0x26, 0x08, 0x68, 0xde, 0x95, 0xd3, 0x2e, 0xfc, 0x96, 0xb6, 0xd0, 0x84, 0xff, 0x27, 0x1a,
+    0x5f, 0x60, 0xde, 0xfc, 0xc7, 0x03, 0xe7, 0xa3, 0x8e, 0x6e, 0x29, 0xba, 0x9a, 0x3c, 0x5f, 0xc2,
+    0xc2, 0x80, 0x76, 0xb6, 0xa8, 0x96, 0xaf, 0x1d, 0x34, 0xd7, 0x88, 0x28, 0xce, 0x9b, 0xdd, 0xb1,
+    0xf3, 0x4f, 0x9c, 0x94, 0x04, 0x43, 0x07, 0x81, 0x29, 0x8e, 0x20, 0x13, 0x16, 0x72, 0x5b, 0xbd,
+    0xbc, 0x99, 0x3a, 0x41, 0x02, 0x41, 0x00, 0xe1, 0xc6, 0xd9, 0x27, 0x64, 0x6c, 0x09, 0x16, 0xec,
+    0x36, 0x82, 0x6d, 0x59, 0x49, 0x83, 0x74, 0x0c, 0x21, 0xf1, 0xb0, 0x74, 0xc4, 0xa1, 0xa5, 0x98,
+    0x67, 0xc6, 0x69, 0x79, 0x5c, 0x85, 0xd3, 0xdc, 0x46, 0x4c, 0x5b, 0x92, 0x9e, 0x94, 0xbf, 0xb3,
+    0x4e, 0x0d, 0xcc, 0x50, 0x14, 0xb1, 0x0f, 0x13, 0x34, 0x1a, 0xb7, 0xfd, 0xd5, 0xf6, 0x04, 0x14,
+    0xd2, 0xa3, 0x26, 0xca, 0xd4, 0x1c, 0xc5, 0x02, 0x41, 0x00, 0xda, 0x48, 0x59, 0x97, 0x78, 0x5c,
+    0xd5, 0x63, 0x0f, 0xb0, 0xfd, 0x8c, 0x52, 0x54, 0xf9, 0x8e, 0x53, 0x8e, 0x18, 0x98, 0x3a, 0xae,
+    0x9e, 0x6b, 0x7e, 0x6a, 0x5a, 0x7b, 0x5d, 0x34, 0x37, 0x55, 0xb9, 0x21, 0x8e, 0xbd, 0x40, 0x32,
+    0x0d, 0x28, 0x38, 0x7d, 0x78, 0x9f, 0x76, 0xfa, 0x21, 0x8b, 0xcc, 0x2d, 0x8b, 0x68, 0xa5, 0xf6,
+    0x41, 0x8f, 0xbb, 0xec, 0xa5, 0x17, 0x9a, 0xb3, 0xaf, 0xbd, 0x02, 0x40, 0x50, 0xfe, 0xfc, 0x32,
+    0x64, 0x95, 0x59, 0x61, 0x6e, 0xd6, 0x53, 0x4e, 0x15, 0x45, 0x09, 0x32, 0x9d, 0x93, 0xa3, 0xd8,
+    0x10, 0xdb, 0xe5, 0xbd, 0xb9, 0x82, 0x29, 0x2c, 0xf7, 0x8b, 0xd8, 0xba, 0xdb, 0x80, 0x20, 0xae,
+    0x8d, 0x57, 0xf4, 0xb7, 0x1d, 0x05, 0x38, 0x6f, 0xfe, 0x9e, 0x9d, 0xb2, 0x71, 0xca, 0x34, 0x77,
+    0xa3, 0x49, 0x99, 0xdb, 0x76, 0xf8, 0xe5, 0xec, 0xe9, 0xc0, 0xd4, 0x9d, 0x02, 0x40, 0x15, 0xb7,
+    0x4c, 0xf2, 0x7c, 0xce, 0xff, 0x8b, 0xb3, 0x6b, 0xf0, 0x4d, 0x9d, 0x83, 0x46, 0xb0, 0x9a, 0x2f,
+    0x70, 0xd2, 0xf4, 0x43, 0x9b, 0x0f, 0x26, 0xac, 0x7e, 0x03, 0xf7, 0xe9, 0xd1, 0xf7, 0x7d, 0x4b,
+    0x91, 0x5f, 0xd2, 0x9b, 0x28, 0x23, 0xf0, 0x3a, 0xcb, 0x5d, 0x52, 0x00, 0xe0, 0x85, 0x7f, 0xf2,
+    0xa8, 0x03, 0xe9, 0x3e, 0xee, 0x96, 0xd6, 0x23, 0x5c, 0xe9, 0x54, 0x42, 0xbc, 0x21, 0x02, 0x41,
+    0x00, 0x90, 0xa7, 0x45, 0xda, 0x89, 0x70, 0xb2, 0xcd, 0x64, 0x96, 0x60, 0x32, 0x42, 0x28, 0xc5,
+    0xf8, 0x28, 0x56, 0xff, 0xd6, 0x65, 0xba, 0x9a, 0x85, 0xc8, 0xd6, 0x0f, 0x1b, 0x8b, 0xee, 0x71,
+    0x7e, 0xcd, 0x2c, 0x72, 0xea, 0xe0, 0x1d, 0xad, 0x86, 0xba, 0x76, 0x54, 0xd4, 0xcf, 0x45, 0xad,
+    0xb5, 0xf1, 0xf2, 0xb3, 0x1d, 0x9f, 0x81, 0x22, 0xcf, 0xa5, 0xf1, 0xa5, 0x57, 0x0f, 0x9b, 0x2d,
+    0x25,
+};
+
+static uint8_t kRsaAttestCert[] = {
+    0x30, 0x82, 0x02, 0xb6, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10,
+    0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+    0x30, 0x63, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+    0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f,
+    0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d,
+    0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x15, 0x30, 0x13,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e,
+    0x64, 0x72, 0x6f, 0x69, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x31, 0x30, 0x34, 0x31,
+    0x32, 0x34, 0x30, 0x35, 0x33, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32,
+    0x34, 0x30, 0x35, 0x33, 0x5a, 0x30, 0x76, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+    0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
+    0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
+    0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
+    0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+    0x69, 0x64, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x41, 0x6e, 0x64,
+    0x72, 0x6f, 0x69, 0x64, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74,
+    0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4b, 0x65, 0x79, 0x30, 0x81, 0x9f,
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+    0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xc0, 0x83, 0x23, 0xdc, 0x56, 0x88,
+    0x1b, 0xb8, 0x30, 0x20, 0x69, 0xf5, 0xb0, 0x85, 0x61, 0xc6, 0xee, 0xbe, 0x7f, 0x05, 0xe2, 0xf5,
+    0xa8, 0x42, 0x04, 0x8a, 0xbe, 0x8b, 0x47, 0xbe, 0x76, 0xfe, 0xae, 0xf2, 0x5c, 0xf2, 0x9b, 0x2a,
+    0xfa, 0x32, 0x00, 0x14, 0x16, 0x01, 0x42, 0x99, 0x89, 0xa1, 0x5f, 0xcf, 0xc6, 0x81, 0x5e, 0xb3,
+    0x63, 0x58, 0x3c, 0x2f, 0xd2, 0xf2, 0x0b, 0xe4, 0x98, 0x32, 0x83, 0xdd, 0x81, 0x4b, 0x16, 0xd7,
+    0xe1, 0x85, 0x41, 0x7a, 0xe5, 0x4a, 0xbc, 0x29, 0x6a, 0x3a, 0x6d, 0xb5, 0xc0, 0x04, 0x08, 0x3b,
+    0x68, 0xc5, 0x56, 0xc1, 0xf0, 0x23, 0x39, 0x91, 0x64, 0x19, 0x86, 0x4d, 0x50, 0xb7, 0x4d, 0x40,
+    0xae, 0xca, 0x48, 0x4c, 0x77, 0x35, 0x6c, 0x89, 0x5a, 0x0c, 0x27, 0x5a, 0xbf, 0xac, 0x49, 0x9d,
+    0x5d, 0x7d, 0x23, 0x62, 0xf2, 0x9c, 0x5e, 0x02, 0xe8, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+    0x66, 0x30, 0x64, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd4, 0x0c,
+    0x10, 0x1b, 0xf8, 0xcd, 0x63, 0xb9, 0xf7, 0x39, 0x52, 0xb5, 0x0e, 0x13, 0x5c, 0xa6, 0xd7, 0x99,
+    0x93, 0x86, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x29,
+    0xfa, 0xf1, 0xac, 0xcc, 0x4d, 0xd2, 0x4c, 0x96, 0x40, 0x27, 0x75, 0xb6, 0xb0, 0xe9, 0x32, 0xe5,
+    0x07, 0xfe, 0x2e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
+    0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01,
+    0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+    0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x9e, 0x2d, 0x48, 0x5f, 0x8c, 0x67,
+    0x33, 0xdc, 0x1a, 0x85, 0xad, 0x99, 0xd7, 0x50, 0x23, 0xea, 0x14, 0xec, 0x43, 0xb0, 0xe1, 0x9d,
+    0xea, 0xc2, 0x23, 0x46, 0x1e, 0x72, 0xb5, 0x19, 0xdc, 0x60, 0x22, 0xe4, 0xa5, 0x68, 0x31, 0x6c,
+    0x0b, 0x55, 0xc4, 0xe6, 0x9c, 0xa2, 0x2d, 0x9f, 0x3a, 0x4f, 0x93, 0x6b, 0x31, 0x8b, 0x16, 0x78,
+    0x16, 0x0d, 0x88, 0xcb, 0xd9, 0x8b, 0xcc, 0x80, 0x9d, 0x84, 0xf0, 0xc2, 0x27, 0xe3, 0x6b, 0x38,
+    0xf1, 0xfd, 0xd1, 0xe7, 0x17, 0x72, 0x31, 0x59, 0x35, 0x7d, 0x96, 0xf3, 0xc5, 0x7f, 0xab, 0x9d,
+    0x8f, 0x96, 0x61, 0x26, 0x4f, 0xb2, 0xbe, 0x81, 0xbb, 0x0d, 0x49, 0x04, 0x22, 0x8a, 0xce, 0x9f,
+    0xf7, 0xf5, 0x42, 0x2e, 0x25, 0x44, 0xfa, 0x21, 0x07, 0x12, 0x5a, 0x83, 0xb5, 0x55, 0xad, 0x18,
+    0x82, 0xf8, 0x40, 0x14, 0x9b, 0x9c, 0x20, 0x63, 0x04, 0x7f,
+};
+
+static uint8_t kRsaAttestRootCert[] = {
+    0x30, 0x82, 0x02, 0xa7, 0x30, 0x82, 0x02, 0x10, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
+    0xff, 0x94, 0xd9, 0xdd, 0x9f, 0x07, 0xc8, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x63, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+    0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06,
+    0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56,
+    0x69, 0x65, 0x77, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f,
+    0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x30, 0x1e, 0x17, 0x0d,
+    0x31, 0x36, 0x30, 0x31, 0x30, 0x34, 0x31, 0x32, 0x33, 0x31, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33,
+    0x35, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x38, 0x5a, 0x30, 0x63, 0x31, 0x0b,
+    0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
+    0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61,
+    0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74,
+    0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
+    0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
+    0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+    0x64, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+    0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa2, 0x6b,
+    0xad, 0xeb, 0x6e, 0x2e, 0x44, 0x61, 0xef, 0xd5, 0x0e, 0x82, 0xe6, 0xb7, 0x94, 0xd1, 0x75, 0x23,
+    0x1f, 0x77, 0x9b, 0x63, 0x91, 0x63, 0xff, 0xf7, 0xaa, 0xff, 0x0b, 0x72, 0x47, 0x4e, 0xc0, 0x2c,
+    0x43, 0xec, 0x33, 0x7c, 0xd7, 0xac, 0xed, 0x40, 0x3e, 0x8c, 0x28, 0xa0, 0x66, 0xd5, 0xf7, 0x87,
+    0x0b, 0x33, 0x97, 0xde, 0x0e, 0xb8, 0x4e, 0x13, 0x40, 0xab, 0xaf, 0xa5, 0x27, 0xbf, 0x95, 0x69,
+    0xa0, 0x31, 0xdb, 0x06, 0x52, 0x65, 0xf8, 0x44, 0x59, 0x57, 0x61, 0xf0, 0xbb, 0xf2, 0x17, 0x4b,
+    0xb7, 0x41, 0x80, 0x64, 0xc0, 0x28, 0x0e, 0x8f, 0x52, 0x77, 0x8e, 0xdb, 0xd2, 0x47, 0xb6, 0x45,
+    0xe9, 0x19, 0xc8, 0xe9, 0x8b, 0xc3, 0xdb, 0xc2, 0x91, 0x3f, 0xd7, 0xd7, 0x50, 0xc4, 0x1d, 0x35,
+    0x66, 0xf9, 0x57, 0xe4, 0x97, 0x96, 0x0b, 0x09, 0xac, 0xce, 0x92, 0x35, 0x85, 0x9b, 0x02, 0x03,
+    0x01, 0x00, 0x01, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
+    0x04, 0x14, 0x29, 0xfa, 0xf1, 0xac, 0xcc, 0x4d, 0xd2, 0x4c, 0x96, 0x40, 0x27, 0x75, 0xb6, 0xb0,
+    0xe9, 0x32, 0xe5, 0x07, 0xfe, 0x2e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+    0x16, 0x80, 0x14, 0x29, 0xfa, 0xf1, 0xac, 0xcc, 0x4d, 0xd2, 0x4c, 0x96, 0x40, 0x27, 0x75, 0xb6,
+    0xb0, 0xe9, 0x32, 0xe5, 0x07, 0xfe, 0x2e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+    0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
+    0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+    0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x4f, 0x72, 0xf3, 0x36, 0x59,
+    0x8d, 0x0e, 0xc1, 0xb9, 0x74, 0x5b, 0x31, 0x59, 0xf6, 0xf0, 0x8d, 0x25, 0x49, 0x30, 0x9e, 0xa3,
+    0x1c, 0x1c, 0x29, 0xd2, 0x45, 0x2d, 0x20, 0xb9, 0x4d, 0x5f, 0x64, 0xb4, 0xe8, 0x80, 0xc7, 0x78,
+    0x7a, 0x9c, 0x39, 0xde, 0xa8, 0xb3, 0xf5, 0xbf, 0x2f, 0x70, 0x5f, 0x47, 0x10, 0x5c, 0xc5, 0xe6,
+    0xeb, 0x4d, 0x06, 0x99, 0x61, 0xd2, 0xae, 0x9a, 0x07, 0xff, 0xf7, 0x7c, 0xb8, 0xab, 0xeb, 0x9c,
+    0x0f, 0x24, 0x07, 0x5e, 0xb1, 0x7f, 0xba, 0x79, 0x71, 0xfd, 0x4d, 0x5b, 0x9e, 0xdf, 0x14, 0xa9,
+    0xfe, 0xdf, 0xed, 0x7c, 0xc0, 0x88, 0x5d, 0xf8, 0xdd, 0x9b, 0x64, 0x32, 0x56, 0xd5, 0x35, 0x9a,
+    0xe2, 0x13, 0xf9, 0x8f, 0xce, 0xc1, 0x7c, 0xdc, 0xef, 0xa4, 0xaa, 0xb2, 0x55, 0xc3, 0x83, 0xa9,
+    0x2e, 0xfb, 0x5c, 0xf6, 0x62, 0xf5, 0x27, 0x52, 0x17, 0xbe, 0x63,
+};
+
+static uint8_t kEcAttestKey[] = {
+    0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x21, 0xe0, 0x86, 0x43, 0x2a, 0x15, 0x19, 0x84, 0x59,
+    0xcf, 0x36, 0x3a, 0x50, 0xfc, 0x14, 0xc9, 0xda, 0xad, 0xf9, 0x35, 0xf5, 0x27, 0xc2, 0xdf, 0xd7,
+    0x1e, 0x4d, 0x6d, 0xbc, 0x42, 0xe5, 0x44, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xeb, 0x9e, 0x79, 0xf8, 0x42, 0x63, 0x59,
+    0xac, 0xcb, 0x2a, 0x91, 0x4c, 0x89, 0x86, 0xcc, 0x70, 0xad, 0x90, 0x66, 0x93, 0x82, 0xa9, 0x73,
+    0x26, 0x13, 0xfe, 0xac, 0xcb, 0xf8, 0x21, 0x27, 0x4c, 0x21, 0x74, 0x97, 0x4a, 0x2a, 0xfe, 0xa5,
+    0xb9, 0x4d, 0x7f, 0x66, 0xd4, 0xe0, 0x65, 0x10, 0x66, 0x35, 0xbc, 0x53, 0xb7, 0xa0, 0xa3, 0xa6,
+    0x71, 0x58, 0x3e, 0xdb, 0x3e, 0x11, 0xae, 0x10, 0x14,
+};
+
+static uint8_t kEcAttestCert[] = {
+    0x30, 0x82, 0x02, 0x78, 0x30, 0x82, 0x02, 0x1e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10,
+    0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0x98,
+    0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30,
+    0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e,
+    0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75,
+    0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63,
+    0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72,
+    0x6f, 0x69, 0x64, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x41, 0x6e,
+    0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x53,
+    0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74,
+    0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x31,
+    0x31, 0x31, 0x30, 0x30, 0x34, 0x36, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x31, 0x30,
+    0x38, 0x30, 0x30, 0x34, 0x36, 0x30, 0x39, 0x5a, 0x30, 0x81, 0x88, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+    0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x15, 0x30,
+    0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41,
+    0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
+    0x32, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72,
+    0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73,
+    0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69,
+    0x61, 0x74, 0x65, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+    0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xeb, 0x9e,
+    0x79, 0xf8, 0x42, 0x63, 0x59, 0xac, 0xcb, 0x2a, 0x91, 0x4c, 0x89, 0x86, 0xcc, 0x70, 0xad, 0x90,
+    0x66, 0x93, 0x82, 0xa9, 0x73, 0x26, 0x13, 0xfe, 0xac, 0xcb, 0xf8, 0x21, 0x27, 0x4c, 0x21, 0x74,
+    0x97, 0x4a, 0x2a, 0xfe, 0xa5, 0xb9, 0x4d, 0x7f, 0x66, 0xd4, 0xe0, 0x65, 0x10, 0x66, 0x35, 0xbc,
+    0x53, 0xb7, 0xa0, 0xa3, 0xa6, 0x71, 0x58, 0x3e, 0xdb, 0x3e, 0x11, 0xae, 0x10, 0x14, 0xa3, 0x66,
+    0x30, 0x64, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3f, 0xfc, 0xac,
+    0xd6, 0x1a, 0xb1, 0x3a, 0x9e, 0x81, 0x20, 0xb8, 0xd5, 0x25, 0x1c, 0xc5, 0x65, 0xbb, 0x1e, 0x91,
+    0xa9, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc8, 0xad,
+    0xe9, 0x77, 0x4c, 0x45, 0xc3, 0xa3, 0xcf, 0x0d, 0x16, 0x10, 0xe4, 0x79, 0x43, 0x3a, 0x21, 0x5a,
+    0x30, 0xcf, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
+    0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04,
+    0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x4b, 0x8a, 0x9b, 0x7b, 0xee, 0x82, 0xbc,
+    0xc0, 0x33, 0x87, 0xae, 0x2f, 0xc0, 0x89, 0x98, 0xb4, 0xdd, 0xc3, 0x8d, 0xab, 0x27, 0x2a, 0x45,
+    0x9f, 0x69, 0x0c, 0xc7, 0xc3, 0x92, 0xd4, 0x0f, 0x8e, 0x02, 0x21, 0x00, 0xee, 0xda, 0x01, 0x5d,
+    0xb6, 0xf4, 0x32, 0xe9, 0xd4, 0x84, 0x3b, 0x62, 0x4c, 0x94, 0x04, 0xef, 0x3a, 0x7c, 0xcc, 0xbd,
+    0x5e, 0xfb, 0x22, 0xbb, 0xe7, 0xfe, 0xb9, 0x77, 0x3f, 0x59, 0x3f, 0xfb,
+};
+
+static uint8_t kEcAttestRootCert[] = {
+    0x30, 0x82, 0x02, 0x8b, 0x30, 0x82, 0x02, 0x32, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
+    0xa2, 0x05, 0x9e, 0xd1, 0x0e, 0x43, 0x5b, 0x57, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
+    0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+    0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
+    0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55,
+    0x04, 0x07, 0x0c, 0x0d, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65,
+    0x77, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67,
+    0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x0c, 0x07, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03,
+    0x55, 0x04, 0x03, 0x0c, 0x2a, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79,
+    0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41,
+    0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30,
+    0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x31, 0x31, 0x31, 0x30, 0x30, 0x34, 0x33, 0x35, 0x30, 0x5a,
+    0x17, 0x0d, 0x33, 0x36, 0x30, 0x31, 0x30, 0x36, 0x30, 0x30, 0x34, 0x33, 0x35, 0x30, 0x5a, 0x30,
+    0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
+    0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f,
+    0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x0d, 0x4d,
+    0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, 0x31, 0x15, 0x30, 0x13,
+    0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x41, 0x6e,
+    0x64, 0x72, 0x6f, 0x69, 0x64, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a,
+    0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65,
+    0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74,
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01,
+    0x07, 0x03, 0x42, 0x00, 0x04, 0xee, 0x5d, 0x5e, 0xc7, 0xe1, 0xc0, 0xdb, 0x6d, 0x03, 0xa6, 0x7e,
+    0xe6, 0xb6, 0x1b, 0xec, 0x4d, 0x6a, 0x5d, 0x6a, 0x68, 0x2e, 0x0f, 0xff, 0x7f, 0x49, 0x0e, 0x7d,
+    0x77, 0x1f, 0x44, 0x22, 0x6d, 0xbd, 0xb1, 0xaf, 0xfa, 0x16, 0xcb, 0xc7, 0xad, 0xc5, 0x77, 0xd2,
+    0x56, 0x9c, 0xaa, 0xb7, 0xb0, 0x2d, 0x54, 0x01, 0x5d, 0x3e, 0x43, 0x2b, 0x2a, 0x8e, 0xd7, 0x4e,
+    0xec, 0x48, 0x75, 0x41, 0xa4, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
+    0x04, 0x16, 0x04, 0x14, 0xc8, 0xad, 0xe9, 0x77, 0x4c, 0x45, 0xc3, 0xa3, 0xcf, 0x0d, 0x16, 0x10,
+    0xe4, 0x79, 0x43, 0x3a, 0x21, 0x5a, 0x30, 0xcf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+    0x18, 0x30, 0x16, 0x80, 0x14, 0xc8, 0xad, 0xe9, 0x77, 0x4c, 0x45, 0xc3, 0xa3, 0xcf, 0x0d, 0x16,
+    0x10, 0xe4, 0x79, 0x43, 0x3a, 0x21, 0x5a, 0x30, 0xcf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13,
+    0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86,
+    0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x35, 0x21, 0xa3,
+    0xef, 0x8b, 0x34, 0x46, 0x1e, 0x9c, 0xd5, 0x60, 0xf3, 0x1d, 0x58, 0x89, 0x20, 0x6a, 0xdc, 0xa3,
+    0x65, 0x41, 0xf6, 0x0d, 0x9e, 0xce, 0x8a, 0x19, 0x8c, 0x66, 0x48, 0x60, 0x7b, 0x02, 0x20, 0x4d,
+    0x0b, 0xf3, 0x51, 0xd9, 0x30, 0x7c, 0x7d, 0x5b, 0xda, 0x35, 0x34, 0x1d, 0xa8, 0x47, 0x1b, 0x63,
+    0xa5, 0x85, 0x65, 0x3c, 0xad, 0x4f, 0x24, 0xa7, 0xe7, 0x4d, 0xaf, 0x41, 0x7d, 0xf1, 0xbf,
+};
+
+size_t kCertificateChainLength = 2;
+
+}  // anonymous namespace
+
+SoftKeymasterContext::SoftKeymasterContext(const std::string& root_of_trust)
+    : rsa_factory_(new RsaKeyFactory(this)), ec_factory_(new EcKeyFactory(this)),
+      aes_factory_(new AesKeyFactory(this)), hmac_factory_(new HmacKeyFactory(this)),
+      km1_dev_(nullptr), root_of_trust_(root_of_trust) {}
+
+SoftKeymasterContext::~SoftKeymasterContext() {}
+
+keymaster_error_t SoftKeymasterContext::SetHardwareDevice(keymaster0_device_t* keymaster0_device) {
+    if (!keymaster0_device)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if ((keymaster0_device->flags & KEYMASTER_SOFTWARE_ONLY) != 0) {
+        LOG_E("SoftKeymasterContext only wraps hardware keymaster0 devices", 0);
+        return KM_ERROR_INVALID_ARGUMENT;
+    }
+
+    km0_engine_.reset(new Keymaster0Engine(keymaster0_device));
+    rsa_factory_.reset(new RsaKeymaster0KeyFactory(this, km0_engine_.get()));
+    ec_factory_.reset(new EcdsaKeymaster0KeyFactory(this, km0_engine_.get()));
+    // Keep AES and HMAC factories.
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::SetHardwareDevice(keymaster1_device_t* keymaster1_device) {
+    if (!keymaster1_device)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    km1_dev_ = keymaster1_device;
+
+    km1_engine_.reset(new Keymaster1Engine(keymaster1_device));
+    rsa_factory_.reset(new RsaKeymaster1KeyFactory(this, km1_engine_.get()));
+    ec_factory_.reset(new EcdsaKeymaster1KeyFactory(this, km1_engine_.get()));
+
+    // All AES and HMAC operations should be passed directly to the keymaster1 device.  Explicitly
+    // do not handle them, to provoke errors in case the higher layers fail to send them to the
+    // device.
+    aes_factory_.reset(nullptr);
+    hmac_factory_.reset(nullptr);
+
+    return KM_ERROR_OK;
+}
+
+KeyFactory* SoftKeymasterContext::GetKeyFactory(keymaster_algorithm_t algorithm) const {
+    switch (algorithm) {
+    case KM_ALGORITHM_RSA:
+        return rsa_factory_.get();
+    case KM_ALGORITHM_EC:
+        return ec_factory_.get();
+    case KM_ALGORITHM_AES:
+        return aes_factory_.get();
+    case KM_ALGORITHM_HMAC:
+        return hmac_factory_.get();
+    default:
+        return nullptr;
+    }
+}
+
+static keymaster_algorithm_t supported_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC,
+                                                       KM_ALGORITHM_AES, KM_ALGORITHM_HMAC};
+
+keymaster_algorithm_t*
+SoftKeymasterContext::GetSupportedAlgorithms(size_t* algorithms_count) const {
+    *algorithms_count = array_length(supported_algorithms);
+    return supported_algorithms;
+}
+
+OperationFactory* SoftKeymasterContext::GetOperationFactory(keymaster_algorithm_t algorithm,
+                                                            keymaster_purpose_t purpose) const {
+    KeyFactory* key_factory = GetKeyFactory(algorithm);
+    if (!key_factory)
+        return nullptr;
+    return key_factory->GetOperationFactory(purpose);
+}
+
+static keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
+    switch (err) {
+    case AuthorizationSet::OK:
+        return KM_ERROR_OK;
+    case AuthorizationSet::ALLOCATION_FAILURE:
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    case AuthorizationSet::MALFORMED_DATA:
+        return KM_ERROR_UNKNOWN_ERROR;
+    }
+    return KM_ERROR_OK;
+}
+
+static keymaster_error_t SetAuthorizations(const AuthorizationSet& key_description,
+                                           keymaster_key_origin_t origin,
+                                           AuthorizationSet* hw_enforced,
+                                           AuthorizationSet* sw_enforced) {
+    sw_enforced->Clear();
+
+    for (auto& entry : key_description) {
+        switch (entry.tag) {
+        // These cannot be specified by the client.
+        case KM_TAG_ROOT_OF_TRUST:
+        case KM_TAG_ORIGIN:
+            LOG_E("Root of trust and origin tags may not be specified", 0);
+            return KM_ERROR_INVALID_TAG;
+
+        // These don't work.
+        case KM_TAG_ROLLBACK_RESISTANT:
+            LOG_E("KM_TAG_ROLLBACK_RESISTANT not supported", 0);
+            return KM_ERROR_UNSUPPORTED_TAG;
+
+        // These are hidden.
+        case KM_TAG_APPLICATION_ID:
+        case KM_TAG_APPLICATION_DATA:
+            break;
+
+        // Everything else we just copy into sw_enforced, unless the KeyFactory has placed it in
+        // hw_enforced, in which case we defer to its decision.
+        default:
+            if (hw_enforced->GetTagCount(entry.tag) == 0)
+                sw_enforced->push_back(entry);
+            break;
+        }
+    }
+
+    sw_enforced->push_back(TAG_CREATION_DATETIME, java_time(time(NULL)));
+    sw_enforced->push_back(TAG_ORIGIN, origin);
+    return TranslateAuthorizationSetError(sw_enforced->is_valid());
+}
+
+keymaster_error_t SoftKeymasterContext::CreateKeyBlob(const AuthorizationSet& key_description,
+                                                      const keymaster_key_origin_t origin,
+                                                      const KeymasterKeyBlob& key_material,
+                                                      KeymasterKeyBlob* blob,
+                                                      AuthorizationSet* hw_enforced,
+                                                      AuthorizationSet* sw_enforced) const {
+    keymaster_error_t error = SetAuthorizations(key_description, origin, hw_enforced, sw_enforced);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    AuthorizationSet hidden;
+    error = BuildHiddenAuthorizations(key_description, &hidden);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    return SerializeIntegrityAssuredBlob(key_material, hidden, *hw_enforced, *sw_enforced, blob);
+}
+
+static keymaster_error_t ParseOcbAuthEncryptedBlob(const KeymasterKeyBlob& blob,
+                                                   const AuthorizationSet& hidden,
+                                                   KeymasterKeyBlob* key_material,
+                                                   AuthorizationSet* hw_enforced,
+                                                   AuthorizationSet* sw_enforced) {
+    Buffer nonce, tag;
+    KeymasterKeyBlob encrypted_key_material;
+    keymaster_error_t error = DeserializeAuthEncryptedBlob(blob, &encrypted_key_material,
+                                                           hw_enforced, sw_enforced, &nonce, &tag);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (nonce.available_read() != OCB_NONCE_LENGTH || tag.available_read() != OCB_TAG_LENGTH)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    return OcbDecryptKey(*hw_enforced, *sw_enforced, hidden, MASTER_KEY, encrypted_key_material,
+                         nonce, tag, key_material);
+}
+
+// Note: This parsing code in below is from system/security/softkeymaster/keymaster_openssl.cpp's
+// unwrap_key function, modified for the preferred function signature and formatting.  It does some
+// odd things, but they have been left unchanged to avoid breaking compatibility.
+static const uint8_t SOFT_KEY_MAGIC[] = {'P', 'K', '#', '8'};
+keymaster_error_t SoftKeymasterContext::ParseOldSoftkeymasterBlob(
+    const KeymasterKeyBlob& blob, KeymasterKeyBlob* key_material, AuthorizationSet* hw_enforced,
+    AuthorizationSet* sw_enforced) const {
+    long publicLen = 0;
+    long privateLen = 0;
+    const uint8_t* p = blob.key_material;
+    const uint8_t* end = blob.key_material + blob.key_material_size;
+
+    int type = 0;
+    ptrdiff_t min_size =
+        sizeof(SOFT_KEY_MAGIC) + sizeof(type) + sizeof(publicLen) + 1 + sizeof(privateLen) + 1;
+    if (end - p < min_size) {
+        LOG_W("key blob appears to be truncated (if an old SW key)", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    if (memcmp(p, SOFT_KEY_MAGIC, sizeof(SOFT_KEY_MAGIC)) != 0)
+        return KM_ERROR_INVALID_KEY_BLOB;
+    p += sizeof(SOFT_KEY_MAGIC);
+
+    for (size_t i = 0; i < sizeof(type); i++)
+        type = (type << 8) | *p++;
+
+    for (size_t i = 0; i < sizeof(type); i++)
+        publicLen = (publicLen << 8) | *p++;
+
+    if (p + publicLen > end) {
+        LOG_W("public key length encoding error: size=%ld, end=%td", publicLen, end - p);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+    p += publicLen;
+
+    if (end - p < 2) {
+        LOG_W("key blob appears to be truncated (if an old SW key)", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    for (size_t i = 0; i < sizeof(type); i++)
+        privateLen = (privateLen << 8) | *p++;
+
+    if (p + privateLen > end) {
+        LOG_W("private key length encoding error: size=%ld, end=%td", privateLen, end - p);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    // Just to be sure, make sure that the ASN.1 structure parses correctly.  We don't actually use
+    // the EVP_PKEY here.
+    const uint8_t* key_start = p;
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> pkey(d2i_PrivateKey(type, nullptr, &p, privateLen));
+    if (pkey.get() == nullptr) {
+        LOG_W("Failed to parse PKCS#8 key material (if old SW key)", 0);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    // All auths go into sw_enforced, including those that would be HW-enforced if we were faking
+    // auths for a HW-backed key.
+    hw_enforced->Clear();
+    keymaster_error_t error = FakeKeyAuthorizations(pkey.get(), sw_enforced, sw_enforced);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (!key_material->Reset(privateLen))
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    memcpy(key_material->writable_data(), key_start, privateLen);
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::ParseKeyBlob(const KeymasterKeyBlob& blob,
+                                                     const AuthorizationSet& additional_params,
+                                                     KeymasterKeyBlob* key_material,
+                                                     AuthorizationSet* hw_enforced,
+                                                     AuthorizationSet* sw_enforced) const {
+    // This is a little bit complicated.
+    //
+    // The SoftKeymasterContext has to handle a lot of different kinds of key blobs.
+    //
+    // 1.  New keymaster1 software key blobs.  These are integrity-assured but not encrypted.  The
+    //     raw key material and auth sets should be extracted and returned.  This is the kind
+    //     produced by this context when the KeyFactory doesn't use keymaster0 to back the keys.
+    //
+    // 2.  Old keymaster1 software key blobs.  These are OCB-encrypted with an all-zero master key.
+    //     They should be decrypted and the key material and auth sets extracted and returned.
+    //
+    // 3.  Old keymaster0 software key blobs.  These are raw key material with a small header tacked
+    //     on the front.  They don't have auth sets, so reasonable defaults are generated and
+    //     returned along with the raw key material.
+    //
+    // 4.  New keymaster0 hardware key blobs.  These are integrity-assured but not encrypted (though
+    //     they're protected by the keymaster0 hardware implementation).  The keymaster0 key blob
+    //     and auth sets should be extracted and returned.
+    //
+    // 5.  Keymaster1 hardware key blobs.  These are raw hardware key blobs.  They contain auth
+    //     sets, which we retrieve from the hardware module.
+    //
+    // 6.  Old keymaster0 hardware key blobs.  These are raw hardware key blobs.  They don't have
+    //     auth sets so reasonable defaults are generated and returned along with the key blob.
+    //
+    // Determining what kind of blob has arrived is somewhat tricky.  What helps is that
+    // integrity-assured and OCB-encrypted blobs are self-consistent and effectively impossible to
+    // parse as anything else.  Old keymaster0 software key blobs have a header.  It's reasonably
+    // unlikely that hardware keys would have the same header.  So anything that is neither
+    // integrity-assured nor OCB-encrypted and lacks the old software key header is assumed to be
+    // keymaster0 hardware.
+
+    AuthorizationSet hidden;
+    keymaster_error_t error = BuildHiddenAuthorizations(additional_params, &hidden);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    // Assume it's an integrity-assured blob (new software-only blob, or new keymaster0-backed
+    // blob).
+    error = DeserializeIntegrityAssuredBlob(blob, hidden, key_material, hw_enforced, sw_enforced);
+    if (error != KM_ERROR_INVALID_KEY_BLOB)
+        return error;
+
+    // Wasn't an integrity-assured blob.  Maybe it's an OCB-encrypted blob.
+    error = ParseOcbAuthEncryptedBlob(blob, hidden, key_material, hw_enforced, sw_enforced);
+    if (error == KM_ERROR_OK)
+        LOG_D("Parsed an old keymaster1 software key", 0);
+    if (error != KM_ERROR_INVALID_KEY_BLOB)
+        return error;
+
+    // Wasn't an OCB-encrypted blob.  Maybe it's an old softkeymaster blob.
+    error = ParseOldSoftkeymasterBlob(blob, key_material, hw_enforced, sw_enforced);
+    if (error == KM_ERROR_OK)
+        LOG_D("Parsed an old sofkeymaster key", 0);
+    if (error != KM_ERROR_INVALID_KEY_BLOB)
+        return error;
+
+    if (km1_dev_)
+        return ParseKeymaster1HwBlob(blob, additional_params, key_material, hw_enforced,
+                                     sw_enforced);
+    else if (km0_engine_)
+        return ParseKeymaster0HwBlob(blob, key_material, hw_enforced, sw_enforced);
+
+    LOG_E("Failed to parse key; not a valid software blob, no hardware module configured", 0);
+    return KM_ERROR_INVALID_KEY_BLOB;
+}
+
+keymaster_error_t SoftKeymasterContext::DeleteKey(const KeymasterKeyBlob& blob) const {
+    if (km1_engine_) {
+        keymaster_error_t error = km1_engine_->DeleteKey(blob);
+        if (error == KM_ERROR_INVALID_KEY_BLOB) {
+            // Note that we succeed on invalid blob, because it probably just indicates that the
+            // blob is a software blob, not a hardware blob.
+            error = KM_ERROR_OK;
+        }
+        return error;
+    }
+
+    if (km0_engine_) {
+        // This could be a keymaster0 hardware key, and it could be either raw or encapsulated in an
+        // integrity-assured blob.  If it's integrity-assured, we can't validate it strongly,
+        // because we don't have the necessary additional_params data.  However, the probability
+        // that anything other than an integrity-assured blob would have all of the structure
+        // required to decode as a valid blob is low -- unless it's maliciously-constructed, but the
+        // deserializer should be proof against bad data, as should the keymaster0 hardware.
+        //
+        // Thus, we first try to parse it as integrity-assured.  If that works, we pass the result
+        // to the underlying hardware.  If not, we pass blob unmodified to the underlying hardware.
+        KeymasterKeyBlob key_material;
+        AuthorizationSet hw_enforced, sw_enforced;
+        keymaster_error_t error = DeserializeIntegrityAssuredBlob_NoHmacCheck(
+            blob, &key_material, &hw_enforced, &sw_enforced);
+        if (error == KM_ERROR_OK && km0_engine_->DeleteKey(key_material))
+            return KM_ERROR_OK;
+
+        km0_engine_->DeleteKey(blob);
+
+        // We succeed unconditionally at this point, even if delete failed.  Failure indicates that
+        // either the blob is a software blob (which we can't distinguish with certainty without
+        // additional_params) or because it is a hardware blob and the hardware failed.  In the
+        // first case, there is no error.  In the second case, the client can't do anything to fix
+        // it anyway, so it's not too harmful to simply swallow the error.  This is not ideal, but
+        // it's the least-bad alternative.
+        return KM_ERROR_OK;
+    }
+
+    // Nothing to do for software-only contexts.
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::DeleteAllKeys() const {
+    if (km1_engine_)
+        return km1_engine_->DeleteAllKeys();
+
+    if (km0_engine_ && !km0_engine_->DeleteAllKeys())
+        return KM_ERROR_UNKNOWN_ERROR;
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::AddRngEntropy(const uint8_t* buf, size_t length) const {
+    RAND_add(buf, length, 0 /* Don't assume any entropy is added to the pool. */);
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::GenerateRandom(uint8_t* buf, size_t length) const {
+    if (RAND_bytes(buf, length) != 1)
+        return KM_ERROR_UNKNOWN_ERROR;
+    return KM_ERROR_OK;
+}
+
+EVP_PKEY* SoftKeymasterContext::AttestationKey(keymaster_algorithm_t algorithm,
+                                               keymaster_error_t* error) const {
+
+    const uint8_t* key;
+    size_t key_length;
+    int evp_key_type;
+
+    switch (algorithm) {
+    case KM_ALGORITHM_RSA:
+        key = kRsaAttestKey;
+        key_length = array_length(kRsaAttestKey);
+        evp_key_type = EVP_PKEY_RSA;
+        break;
+
+    case KM_ALGORITHM_EC:
+        key = kEcAttestKey;
+        key_length = array_length(kEcAttestKey);
+        evp_key_type = EVP_PKEY_EC;
+        break;
+
+    default:
+        *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+        return nullptr;
+    }
+
+    EVP_PKEY* pkey = d2i_PrivateKey(evp_key_type, nullptr /* pkey */, &key, key_length);
+    if (!pkey)
+        *error = TranslateLastOpenSslError();
+
+    return pkey;
+}
+
+keymaster_cert_chain_t* SoftKeymasterContext::AttestationChain(keymaster_algorithm_t algorithm,
+                                                               keymaster_error_t* error) const {
+    // If we have to bail it will be because of an allocation failure.
+    *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    UniquePtr<keymaster_cert_chain_t, CertificateChainDelete> chain(new keymaster_cert_chain_t);
+    if (!chain.get())
+        return nullptr;
+    memset(chain.get(), 0, sizeof(keymaster_cert_chain_t));
+
+    chain->entries = new keymaster_blob_t[kCertificateChainLength];
+    if (!chain->entries)
+        return nullptr;
+
+    memset(chain->entries, 0, sizeof(chain->entries[0]) * kCertificateChainLength);
+    chain->entry_count = kCertificateChainLength;
+
+    size_t entry = 0;
+
+    switch (algorithm) {
+    case KM_ALGORITHM_RSA:
+        chain->entries[entry].data = dup_array(kRsaAttestCert);
+        if (!chain->entries[entry].data)
+            return nullptr;
+        chain->entries[entry].data_length = array_length(kRsaAttestCert);
+        entry++;
+        chain->entries[entry].data = dup_array(kRsaAttestRootCert);
+        if (!chain->entries[entry].data)
+            return nullptr;
+        chain->entries[entry].data_length = array_length(kRsaAttestRootCert);
+        entry++;
+        break;
+
+    case KM_ALGORITHM_EC:
+        chain->entries[entry].data = dup_array(kEcAttestCert);
+        if (!chain->entries[entry].data)
+            return nullptr;
+        chain->entries[entry].data_length = array_length(kEcAttestCert);
+        entry++;
+        chain->entries[entry].data = dup_array(kEcAttestRootCert);
+        if (!chain->entries[entry].data)
+            return nullptr;
+        chain->entries[entry].data_length = array_length(kEcAttestRootCert);
+        entry++;
+        break;
+
+    default:
+        *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
+        return nullptr;
+    };
+
+    assert(entry == kCertificateChainLength);
+
+    *error = KM_ERROR_OK;
+    return chain.release();
+}
+
+keymaster_error_t SoftKeymasterContext::ParseKeymaster1HwBlob(
+    const KeymasterKeyBlob& blob, const AuthorizationSet& additional_params,
+    KeymasterKeyBlob* key_material, AuthorizationSet* hw_enforced,
+    AuthorizationSet* sw_enforced) const {
+    assert(km1_dev_);
+
+    keymaster_blob_t client_id = {nullptr, 0};
+    keymaster_blob_t app_data = {nullptr, 0};
+    keymaster_blob_t* client_id_ptr = nullptr;
+    keymaster_blob_t* app_data_ptr = nullptr;
+    if (additional_params.GetTagValue(TAG_APPLICATION_ID, &client_id))
+        client_id_ptr = &client_id;
+    if (additional_params.GetTagValue(TAG_APPLICATION_DATA, &app_data))
+        app_data_ptr = &app_data;
+
+    // Get key characteristics, which incidentally verifies that the HW recognizes the key.
+    keymaster_key_characteristics_t* characteristics;
+    keymaster_error_t error = km1_dev_->get_key_characteristics(km1_dev_, &blob, client_id_ptr,
+                                                                app_data_ptr, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    unique_ptr<keymaster_key_characteristics_t, Characteristics_Delete> characteristics_deleter(
+        characteristics);
+
+    LOG_D("Module \"%s\" accepted key", km1_dev_->common.module->name);
+
+    hw_enforced->Reinitialize(characteristics->hw_enforced);
+    sw_enforced->Reinitialize(characteristics->sw_enforced);
+    *key_material = blob;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::ParseKeymaster0HwBlob(const KeymasterKeyBlob& blob,
+                                                              KeymasterKeyBlob* key_material,
+                                                              AuthorizationSet* hw_enforced,
+                                                              AuthorizationSet* sw_enforced) const {
+    assert(km0_engine_);
+
+    unique_ptr<EVP_PKEY, EVP_PKEY_Delete> tmp_key(km0_engine_->GetKeymaster0PublicKey(blob));
+
+    if (!tmp_key)
+        return KM_ERROR_INVALID_KEY_BLOB;
+
+    LOG_D("Module \"%s\" accepted key", km0_engine_->device()->common.module->name);
+    keymaster_error_t error = FakeKeyAuthorizations(tmp_key.get(), hw_enforced, sw_enforced);
+    if (error == KM_ERROR_OK)
+        *key_material = blob;
+
+    return error;
+}
+
+keymaster_error_t SoftKeymasterContext::FakeKeyAuthorizations(EVP_PKEY* pubkey,
+                                                              AuthorizationSet* hw_enforced,
+                                                              AuthorizationSet* sw_enforced) const {
+    hw_enforced->Clear();
+    sw_enforced->Clear();
+
+    switch (EVP_PKEY_type(pubkey->type)) {
+    case EVP_PKEY_RSA: {
+        hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_MD5);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
+        hw_enforced->push_back(TAG_PADDING, KM_PAD_NONE);
+        hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+        hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+        hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PSS);
+        hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+
+        sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
+        sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
+        sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
+        sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
+
+        unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(pubkey));
+        if (!rsa)
+            return TranslateLastOpenSslError();
+        hw_enforced->push_back(TAG_KEY_SIZE, RSA_size(rsa.get()) * 8);
+        uint64_t public_exponent = BN_get_word(rsa->e);
+        if (public_exponent == 0xffffffffL)
+            return KM_ERROR_INVALID_KEY_BLOB;
+        hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
+        break;
+    }
+
+    case EVP_PKEY_EC: {
+        hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_MD5);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
+        hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
+
+        sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
+        sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
+
+        UniquePtr<EC_KEY, EC_KEY_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pubkey));
+        if (!ec_key.get())
+            return TranslateLastOpenSslError();
+        size_t key_size_bits;
+        keymaster_error_t error =
+            ec_get_group_size(EC_KEY_get0_group(ec_key.get()), &key_size_bits);
+        if (error != KM_ERROR_OK)
+            return error;
+        hw_enforced->push_back(TAG_KEY_SIZE, key_size_bits);
+        break;
+    }
+
+    default:
+        return KM_ERROR_UNSUPPORTED_ALGORITHM;
+    }
+
+    sw_enforced->push_back(TAG_ALL_USERS);
+    sw_enforced->push_back(TAG_NO_AUTH_REQUIRED);
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterContext::BuildHiddenAuthorizations(const AuthorizationSet& input_set,
+                                                                  AuthorizationSet* hidden) const {
+    keymaster_blob_t entry;
+    if (input_set.GetTagValue(TAG_APPLICATION_ID, &entry))
+        hidden->push_back(TAG_APPLICATION_ID, entry.data, entry.data_length);
+    if (input_set.GetTagValue(TAG_APPLICATION_DATA, &entry))
+        hidden->push_back(TAG_APPLICATION_DATA, entry.data, entry.data_length);
+
+    hidden->push_back(TAG_ROOT_OF_TRUST, reinterpret_cast<const uint8_t*>(root_of_trust_.data()),
+                      root_of_trust_.size());
+
+    return TranslateAuthorizationSetError(hidden->is_valid());
+}
+
+}  // namespace keymaster
diff --git a/keymaster/soft_keymaster_device.cpp b/keymaster/soft_keymaster_device.cpp
new file mode 100644
index 0000000..cbeaec7
--- /dev/null
+++ b/keymaster/soft_keymaster_device.cpp
@@ -0,0 +1,1341 @@
+/*
+ * Copyright 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.
+ */
+
+#include <keymaster/soft_keymaster_device.h>
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <algorithm>
+
+#include <type_traits>
+
+#include <openssl/x509.h>
+
+#include <hardware/keymaster1.h>
+#define LOG_TAG "SoftKeymasterDevice"
+#include <cutils/log.h>
+
+#include <keymaster/android_keymaster.h>
+#include <keymaster/android_keymaster_messages.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/soft_keymaster_context.h>
+#include <keymaster/soft_keymaster_logger.h>
+
+#include "openssl_utils.h"
+
+struct keystore_module soft_keymaster1_device_module = {
+    .common =
+        {
+            .tag = HARDWARE_MODULE_TAG,
+            .module_api_version = KEYMASTER_MODULE_API_VERSION_1_0,
+            .hal_api_version = HARDWARE_HAL_API_VERSION,
+            .id = KEYSTORE_HARDWARE_MODULE_ID,
+            .name = "OpenSSL-based SoftKeymaster HAL",
+            .author = "The Android Open Source Project",
+            .methods = nullptr,
+            .dso = 0,
+            .reserved = {},
+        },
+};
+
+struct keystore_module soft_keymaster2_device_module = {
+    .common =
+        {
+            .tag = HARDWARE_MODULE_TAG,
+            .module_api_version = KEYMASTER_MODULE_API_VERSION_2_0,
+            .hal_api_version = HARDWARE_HAL_API_VERSION,
+            .id = KEYSTORE_HARDWARE_MODULE_ID,
+            .name = "OpenSSL-based SoftKeymaster HAL",
+            .author = "The Android Open Source Project",
+            .methods = nullptr,
+            .dso = 0,
+            .reserved = {},
+        },
+};
+
+namespace keymaster {
+
+const size_t kOperationTableSize = 16;
+
+template <typename T> std::vector<T> make_vector(const T* array, size_t len) {
+    return std::vector<T>(array, array + len);
+}
+
+static keymaster_error_t add_digests(keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
+                                     keymaster_purpose_t purpose,
+                                     SoftKeymasterDevice::DigestMap* map) {
+    auto key = std::make_pair(algorithm, purpose);
+
+    keymaster_digest_t* digests;
+    size_t digests_length;
+    keymaster_error_t error =
+        dev->get_supported_digests(dev, algorithm, purpose, &digests, &digests_length);
+    if (error != KM_ERROR_OK) {
+        LOG_E("Error %d getting supported digests from keymaster1 device", error);
+        return error;
+    }
+    std::unique_ptr<keymaster_digest_t, Malloc_Delete> digests_deleter(digests);
+
+    (*map)[key] = make_vector(digests, digests_length);
+    return KM_ERROR_OK;
+}
+
+static keymaster_error_t map_digests(keymaster1_device_t* dev,
+                                     SoftKeymasterDevice::DigestMap* map) {
+    map->clear();
+
+    keymaster_algorithm_t sig_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC};
+    keymaster_purpose_t sig_purposes[] = {KM_PURPOSE_SIGN, KM_PURPOSE_VERIFY};
+    for (auto algorithm : sig_algorithms)
+        for (auto purpose : sig_purposes) {
+            keymaster_error_t error = add_digests(dev, algorithm, purpose, map);
+            if (error != KM_ERROR_OK)
+                return error;
+        }
+
+    keymaster_algorithm_t crypt_algorithms[] = {KM_ALGORITHM_RSA};
+    keymaster_purpose_t crypt_purposes[] = {KM_PURPOSE_ENCRYPT, KM_PURPOSE_DECRYPT};
+    for (auto algorithm : crypt_algorithms)
+        for (auto purpose : crypt_purposes) {
+            keymaster_error_t error = add_digests(dev, algorithm, purpose, map);
+            if (error != KM_ERROR_OK)
+                return error;
+        }
+
+    return KM_ERROR_OK;
+}
+
+SoftKeymasterDevice::SoftKeymasterDevice()
+    : wrapped_km0_device_(nullptr), wrapped_km1_device_(nullptr),
+      context_(new SoftKeymasterContext),
+      impl_(new AndroidKeymaster(context_, kOperationTableSize)) {
+    LOG_I("Creating device", 0);
+    LOG_D("Device address: %p", this);
+
+    initialize_device_struct(KEYMASTER_SOFTWARE_ONLY | KEYMASTER_BLOBS_ARE_STANDALONE |
+                             KEYMASTER_SUPPORTS_EC);
+}
+
+SoftKeymasterDevice::SoftKeymasterDevice(SoftKeymasterContext* context)
+    : wrapped_km0_device_(nullptr), wrapped_km1_device_(nullptr), context_(context),
+      impl_(new AndroidKeymaster(context_, kOperationTableSize)) {
+    LOG_I("Creating test device", 0);
+    LOG_D("Device address: %p", this);
+
+    initialize_device_struct(KEYMASTER_SOFTWARE_ONLY | KEYMASTER_BLOBS_ARE_STANDALONE |
+                             KEYMASTER_SUPPORTS_EC);
+}
+
+keymaster_error_t SoftKeymasterDevice::SetHardwareDevice(keymaster0_device_t* keymaster0_device) {
+    assert(keymaster0_device);
+    LOG_D("Reinitializing SoftKeymasterDevice to use HW keymaster0", 0);
+
+    if (!context_)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    keymaster_error_t error = context_->SetHardwareDevice(keymaster0_device);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    initialize_device_struct(keymaster0_device->flags);
+
+    module_name_ = km1_device_.common.module->name;
+    module_name_.append("(Wrapping ");
+    module_name_.append(keymaster0_device->common.module->name);
+    module_name_.append(")");
+
+    updated_module_ = *km1_device_.common.module;
+    updated_module_.name = module_name_.c_str();
+
+    km1_device_.common.module = &updated_module_;
+
+    wrapped_km0_device_ = keymaster0_device;
+    wrapped_km1_device_ = nullptr;
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t SoftKeymasterDevice::SetHardwareDevice(keymaster1_device_t* keymaster1_device) {
+    assert(keymaster1_device);
+    LOG_D("Reinitializing SoftKeymasterDevice to use HW keymaster1", 0);
+
+    if (!context_)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    keymaster_error_t error = map_digests(keymaster1_device, &km1_device_digests_);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    error = context_->SetHardwareDevice(keymaster1_device);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    initialize_device_struct(keymaster1_device->flags);
+
+    module_name_ = km1_device_.common.module->name;
+    module_name_.append(" (Wrapping ");
+    module_name_.append(keymaster1_device->common.module->name);
+    module_name_.append(")");
+
+    updated_module_ = *km1_device_.common.module;
+    updated_module_.name = module_name_.c_str();
+
+    km1_device_.common.module = &updated_module_;
+
+    wrapped_km0_device_ = nullptr;
+    wrapped_km1_device_ = keymaster1_device;
+    return KM_ERROR_OK;
+}
+
+bool SoftKeymasterDevice::Keymaster1DeviceIsGood() {
+    std::vector<keymaster_digest_t> expected_rsa_digests = {
+        KM_DIGEST_NONE,      KM_DIGEST_MD5,       KM_DIGEST_SHA1,     KM_DIGEST_SHA_2_224,
+        KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
+    std::vector<keymaster_digest_t> expected_ec_digests = {
+        KM_DIGEST_NONE,      KM_DIGEST_SHA1,      KM_DIGEST_SHA_2_224,
+        KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
+
+    for (auto& entry : km1_device_digests_) {
+        if (entry.first.first == KM_ALGORITHM_RSA)
+            if (!std::is_permutation(entry.second.begin(), entry.second.end(),
+                                     expected_rsa_digests.begin()))
+                return false;
+        if (entry.first.first == KM_ALGORITHM_EC)
+            if (!std::is_permutation(entry.second.begin(), entry.second.end(),
+                                     expected_ec_digests.begin()))
+                return false;
+    }
+    return true;
+}
+
+void SoftKeymasterDevice::initialize_device_struct(uint32_t flags) {
+    memset(&km1_device_, 0, sizeof(km1_device_));
+
+    km1_device_.common.tag = HARDWARE_DEVICE_TAG;
+    km1_device_.common.version = 1;
+    km1_device_.common.module = reinterpret_cast<hw_module_t*>(&soft_keymaster1_device_module);
+    km1_device_.common.close = &close_device;
+
+    km1_device_.flags = flags;
+
+    km1_device_.context = this;
+
+    // keymaster0 APIs
+    km1_device_.generate_keypair = nullptr;
+    km1_device_.import_keypair = nullptr;
+    km1_device_.get_keypair_public = nullptr;
+    km1_device_.delete_keypair = nullptr;
+    km1_device_.delete_all = nullptr;
+    km1_device_.sign_data = nullptr;
+    km1_device_.verify_data = nullptr;
+
+    // keymaster1 APIs
+    km1_device_.get_supported_algorithms = get_supported_algorithms;
+    km1_device_.get_supported_block_modes = get_supported_block_modes;
+    km1_device_.get_supported_padding_modes = get_supported_padding_modes;
+    km1_device_.get_supported_digests = get_supported_digests;
+    km1_device_.get_supported_import_formats = get_supported_import_formats;
+    km1_device_.get_supported_export_formats = get_supported_export_formats;
+    km1_device_.add_rng_entropy = add_rng_entropy;
+    km1_device_.generate_key = generate_key;
+    km1_device_.get_key_characteristics = get_key_characteristics;
+    km1_device_.import_key = import_key;
+    km1_device_.export_key = export_key;
+    km1_device_.delete_key = delete_key;
+    km1_device_.delete_all_keys = delete_all_keys;
+    km1_device_.begin = begin;
+    km1_device_.update = update;
+    km1_device_.finish = finish;
+    km1_device_.abort = abort;
+
+    // keymaster2 APIs
+    memset(&km2_device_, 0, sizeof(km2_device_));
+
+    km2_device_.context = this;
+
+    km2_device_.common.tag = HARDWARE_DEVICE_TAG;
+    km2_device_.common.version = 1;
+    km2_device_.common.module = reinterpret_cast<hw_module_t*>(&soft_keymaster2_device_module);
+    km2_device_.common.close = &close_device;
+
+    km2_device_.add_rng_entropy = add_rng_entropy;
+    km2_device_.generate_key = generate_key;
+    km2_device_.get_key_characteristics = get_key_characteristics;
+    km2_device_.import_key = import_key;
+    km2_device_.export_key = export_key;
+    km2_device_.agree_key = nullptr;  // TODO(swillden) Implement ECDH
+    km2_device_.attest_key = attest_key;
+    km2_device_.upgrade_key = nullptr;  // TODO(swillden) Implement upgrade
+    km2_device_.delete_key = delete_key;
+    km2_device_.delete_all_keys = delete_all_keys;
+    km2_device_.begin = begin;
+    km2_device_.update = update;
+    km2_device_.finish = finish;
+    km2_device_.abort = abort;
+}
+
+hw_device_t* SoftKeymasterDevice::hw_device() {
+    return &km1_device_.common;
+}
+
+keymaster1_device_t* SoftKeymasterDevice::keymaster_device() {
+    return &km1_device_;
+}
+
+keymaster2_device_t* SoftKeymasterDevice::keymaster2_device() {
+    return &km2_device_;
+}
+
+namespace {
+
+keymaster_key_characteristics_t* BuildCharacteristics(const AuthorizationSet& hw_enforced,
+                                                      const AuthorizationSet& sw_enforced) {
+    keymaster_key_characteristics_t* characteristics =
+        reinterpret_cast<keymaster_key_characteristics_t*>(
+            malloc(sizeof(keymaster_key_characteristics_t)));
+    if (characteristics) {
+        hw_enforced.CopyToParamSet(&characteristics->hw_enforced);
+        sw_enforced.CopyToParamSet(&characteristics->sw_enforced);
+    }
+    return characteristics;
+}
+
+template <typename RequestType>
+void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
+                         RequestType* request) {
+    request->additional_params.Clear();
+    if (client_id)
+        request->additional_params.push_back(TAG_APPLICATION_ID, *client_id);
+    if (app_data)
+        request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data);
+}
+
+template <typename T> SoftKeymasterDevice* convert_device(const T* dev) {
+    static_assert((std::is_same<T, keymaster0_device_t>::value ||
+                   std::is_same<T, keymaster1_device_t>::value ||
+                   std::is_same<T, keymaster2_device_t>::value),
+                  "convert_device should only be applied to keymaster devices");
+    return reinterpret_cast<SoftKeymasterDevice*>(dev->context);
+}
+
+bool FindAlgorithm(const keymaster_key_param_set_t& params, keymaster_algorithm_t* algorithm) {
+    for (size_t i = 0; i < params.length; ++i)
+        if (params.params[i].tag == KM_TAG_ALGORITHM) {
+            *algorithm = static_cast<keymaster_algorithm_t>(params.params[i].enumerated);
+            return true;
+        }
+    return false;
+}
+
+keymaster_error_t GetAlgorithm(const keymaster1_device_t* dev, const keymaster_key_blob_t& key,
+                               const AuthorizationSet& in_params,
+                               keymaster_algorithm_t* algorithm) {
+    keymaster_blob_t client_id = {nullptr, 0};
+    keymaster_blob_t app_data = {nullptr, 0};
+    keymaster_blob_t* client_id_ptr = nullptr;
+    keymaster_blob_t* app_data_ptr = nullptr;
+    if (in_params.GetTagValue(TAG_APPLICATION_ID, &client_id))
+        client_id_ptr = &client_id;
+    if (in_params.GetTagValue(TAG_APPLICATION_DATA, &app_data))
+        app_data_ptr = &app_data;
+
+    keymaster_key_characteristics_t* characteristics;
+    keymaster_error_t error =
+        dev->get_key_characteristics(dev, &key, client_id_ptr, app_data_ptr, &characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    std::unique_ptr<keymaster_key_characteristics_t, Characteristics_Delete>
+        characteristics_deleter(characteristics);
+
+    if (FindAlgorithm(characteristics->hw_enforced, algorithm))
+        return KM_ERROR_OK;
+
+    if (FindAlgorithm(characteristics->sw_enforced, algorithm))
+        return KM_ERROR_OK;
+
+    return KM_ERROR_INVALID_KEY_BLOB;
+}
+
+}  // unnamed namespaced
+
+/* static */
+int SoftKeymasterDevice::close_device(hw_device_t* dev) {
+    switch (dev->module->module_api_version) {
+    case KEYMASTER_MODULE_API_VERSION_2_0: {
+        delete convert_device(reinterpret_cast<keymaster2_device_t*>(dev));
+        break;
+    }
+
+    case KEYMASTER_MODULE_API_VERSION_1_0: {
+        delete convert_device(reinterpret_cast<keymaster1_device_t*>(dev));
+        break;
+    }
+
+    default:
+        return -1;
+    }
+
+    return 0;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_supported_algorithms(const keymaster1_device_t* dev,
+                                                                keymaster_algorithm_t** algorithms,
+                                                                size_t* algorithms_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!algorithms || !algorithms_length)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_supported_algorithms(km1_dev, algorithms, algorithms_length);
+
+    SupportedAlgorithmsRequest request;
+    SupportedAlgorithmsResponse response;
+    convert_device(dev)->impl_->SupportedAlgorithms(request, &response);
+    if (response.error != KM_ERROR_OK) {
+        LOG_E("get_supported_algorithms failed with %d", response.error);
+
+        return response.error;
+    }
+
+    *algorithms_length = response.results_length;
+    *algorithms =
+        reinterpret_cast<keymaster_algorithm_t*>(malloc(*algorithms_length * sizeof(**algorithms)));
+    if (!*algorithms)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    std::copy(response.results, response.results + response.results_length, *algorithms);
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_supported_block_modes(const keymaster1_device_t* dev,
+                                                                 keymaster_algorithm_t algorithm,
+                                                                 keymaster_purpose_t purpose,
+                                                                 keymaster_block_mode_t** modes,
+                                                                 size_t* modes_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!modes || !modes_length)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_supported_block_modes(km1_dev, algorithm, purpose, modes, modes_length);
+
+    SupportedBlockModesRequest request;
+    request.algorithm = algorithm;
+    request.purpose = purpose;
+    SupportedBlockModesResponse response;
+    convert_device(dev)->impl_->SupportedBlockModes(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        LOG_E("get_supported_block_modes failed with %d", response.error);
+
+        return response.error;
+    }
+
+    *modes_length = response.results_length;
+    *modes = reinterpret_cast<keymaster_block_mode_t*>(malloc(*modes_length * sizeof(**modes)));
+    if (!*modes)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    std::copy(response.results, response.results + response.results_length, *modes);
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_supported_padding_modes(const keymaster1_device_t* dev,
+                                                                   keymaster_algorithm_t algorithm,
+                                                                   keymaster_purpose_t purpose,
+                                                                   keymaster_padding_t** modes,
+                                                                   size_t* modes_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!modes || !modes_length)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_supported_padding_modes(km1_dev, algorithm, purpose, modes,
+                                                    modes_length);
+
+    SupportedPaddingModesRequest request;
+    request.algorithm = algorithm;
+    request.purpose = purpose;
+    SupportedPaddingModesResponse response;
+    convert_device(dev)->impl_->SupportedPaddingModes(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        LOG_E("get_supported_padding_modes failed with %d", response.error);
+        return response.error;
+    }
+
+    *modes_length = response.results_length;
+    *modes = reinterpret_cast<keymaster_padding_t*>(malloc(*modes_length * sizeof(**modes)));
+    if (!*modes)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    std::copy(response.results, response.results + response.results_length, *modes);
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_supported_digests(const keymaster1_device_t* dev,
+                                                             keymaster_algorithm_t algorithm,
+                                                             keymaster_purpose_t purpose,
+                                                             keymaster_digest_t** digests,
+                                                             size_t* digests_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!digests || !digests_length)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_supported_digests(km1_dev, algorithm, purpose, digests, digests_length);
+
+    SupportedDigestsRequest request;
+    request.algorithm = algorithm;
+    request.purpose = purpose;
+    SupportedDigestsResponse response;
+    convert_device(dev)->impl_->SupportedDigests(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        LOG_E("get_supported_digests failed with %d", response.error);
+        return response.error;
+    }
+
+    *digests_length = response.results_length;
+    *digests = reinterpret_cast<keymaster_digest_t*>(malloc(*digests_length * sizeof(**digests)));
+    if (!*digests)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    std::copy(response.results, response.results + response.results_length, *digests);
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_supported_import_formats(
+    const keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
+    keymaster_key_format_t** formats, size_t* formats_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!formats || !formats_length)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_supported_import_formats(km1_dev, algorithm, formats, formats_length);
+
+    SupportedImportFormatsRequest request;
+    request.algorithm = algorithm;
+    SupportedImportFormatsResponse response;
+    convert_device(dev)->impl_->SupportedImportFormats(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        LOG_E("get_supported_import_formats failed with %d", response.error);
+        return response.error;
+    }
+
+    *formats_length = response.results_length;
+    *formats =
+        reinterpret_cast<keymaster_key_format_t*>(malloc(*formats_length * sizeof(**formats)));
+    if (!*formats)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    std::copy(response.results, response.results + response.results_length, *formats);
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_supported_export_formats(
+    const keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
+    keymaster_key_format_t** formats, size_t* formats_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!formats || !formats_length)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_supported_export_formats(km1_dev, algorithm, formats, formats_length);
+
+    SupportedExportFormatsRequest request;
+    request.algorithm = algorithm;
+    SupportedExportFormatsResponse response;
+    convert_device(dev)->impl_->SupportedExportFormats(request, &response);
+
+    if (response.error != KM_ERROR_OK) {
+        LOG_E("get_supported_export_formats failed with %d", response.error);
+        return response.error;
+    }
+
+    *formats_length = response.results_length;
+    *formats =
+        reinterpret_cast<keymaster_key_format_t*>(malloc(*formats_length * sizeof(**formats)));
+    if (!*formats)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    std::copy(response.results, response.results + *formats_length, *formats);
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::add_rng_entropy(const keymaster1_device_t* dev,
+                                                       const uint8_t* data, size_t data_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->add_rng_entropy(km1_dev, data, data_length);
+
+    AddEntropyRequest request;
+    request.random_data.Reinitialize(data, data_length);
+    AddEntropyResponse response;
+    convert_device(dev)->impl_->AddRngEntropy(request, &response);
+    if (response.error != KM_ERROR_OK)
+        LOG_E("add_rng_entropy failed with %d", response.error);
+    return response.error;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::add_rng_entropy(const keymaster2_device_t* dev,
+                                                       const uint8_t* data, size_t data_length) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+    return add_rng_entropy(&sk_dev->km1_device_, data, data_length);
+}
+
+template <typename Collection, typename Value> bool contains(const Collection& c, const Value& v) {
+    return std::find(c.begin(), c.end(), v) != c.end();
+}
+
+bool SoftKeymasterDevice::FindUnsupportedDigest(keymaster_algorithm_t algorithm,
+                                                keymaster_purpose_t purpose,
+                                                const AuthorizationSet& params,
+                                                keymaster_digest_t* unsupported) const {
+    assert(wrapped_km1_device_);
+
+    auto supported_digests = km1_device_digests_.find(std::make_pair(algorithm, purpose));
+    if (supported_digests == km1_device_digests_.end())
+        // Invalid algorith/purpose pair (e.g. EC encrypt).  Let the error be handled by HW module.
+        return false;
+
+    for (auto& entry : params)
+        if (entry.tag == TAG_DIGEST)
+            if (!contains(supported_digests->second, entry.enumerated)) {
+                LOG_I("Digest %d requested but not supported by module %s", entry.enumerated,
+                      wrapped_km1_device_->common.module->name);
+                *unsupported = static_cast<keymaster_digest_t>(entry.enumerated);
+                return true;
+            }
+    return false;
+}
+
+bool SoftKeymasterDevice::RequiresSoftwareDigesting(keymaster_algorithm_t algorithm,
+                                                    keymaster_purpose_t purpose,
+                                                    const AuthorizationSet& params) const {
+    assert(wrapped_km1_device_);
+    if (!wrapped_km1_device_)
+        return true;
+
+    switch (algorithm) {
+    case KM_ALGORITHM_AES:
+    case KM_ALGORITHM_HMAC:
+        LOG_D("Not performing software digesting for algorithm %d", algorithm);
+        return false;
+    case KM_ALGORITHM_RSA:
+    case KM_ALGORITHM_EC:
+        break;
+    }
+
+    keymaster_digest_t unsupported;
+    if (!FindUnsupportedDigest(algorithm, purpose, params, &unsupported)) {
+        LOG_D("Requested digest(s) supported for algorithm %d and purpose %d", algorithm, purpose);
+        return false;
+    }
+
+    return true;
+}
+
+bool SoftKeymasterDevice::KeyRequiresSoftwareDigesting(
+    const AuthorizationSet& key_description) const {
+    assert(wrapped_km1_device_);
+    if (!wrapped_km1_device_)
+        return true;
+
+    keymaster_algorithm_t algorithm;
+    if (!key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) {
+        // The hardware module will return an error during keygen.
+        return false;
+    }
+
+    for (auto& entry : key_description)
+        if (entry.tag == TAG_PURPOSE) {
+            keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(entry.enumerated);
+            if (RequiresSoftwareDigesting(algorithm, purpose, key_description))
+                return true;
+        }
+
+    return false;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::generate_key(
+    const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
+    keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
+    if (!dev || !params)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!key_blob)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+
+    GenerateKeyRequest request;
+    request.key_description.Reinitialize(*params);
+
+    keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
+    if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description))
+        return km1_dev->generate_key(km1_dev, params, key_blob, characteristics);
+
+    GenerateKeyResponse response;
+    sk_dev->impl_->GenerateKey(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    key_blob->key_material_size = response.key_blob.key_material_size;
+    uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
+    if (!tmp)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    memcpy(tmp, response.key_blob.key_material, response.key_blob.key_material_size);
+    key_blob->key_material = tmp;
+
+    if (characteristics) {
+        *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
+        if (!*characteristics)
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+
+    return KM_ERROR_OK;
+}
+
+keymaster_error_t
+SoftKeymasterDevice::generate_key(const keymaster2_device_t* dev,  //
+                                  const keymaster_key_param_set_t* params,
+                                  keymaster_key_blob_t* key_blob,
+                                  keymaster_key_characteristics_t* characteristics) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!key_blob)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+
+    GenerateKeyRequest request;
+    request.key_description.Reinitialize(*params);
+
+    keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
+    if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description)) {
+        keymaster_key_characteristics_t* chars_ptr;
+        keymaster_error_t error = km1_dev->generate_key(km1_dev, params, key_blob,
+                                                        characteristics ? &chars_ptr : nullptr);
+        if (error != KM_ERROR_OK)
+            return error;
+
+        if (characteristics) {
+            *characteristics = *chars_ptr;
+            free(chars_ptr);
+        }
+        return KM_ERROR_OK;
+    }
+
+    GenerateKeyResponse response;
+    sk_dev->impl_->GenerateKey(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    key_blob->key_material_size = response.key_blob.key_material_size;
+    uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
+    if (!tmp)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    memcpy(tmp, response.key_blob.key_material, response.key_blob.key_material_size);
+    key_blob->key_material = tmp;
+
+    if (characteristics) {
+        response.enforced.CopyToParamSet(&characteristics->hw_enforced);
+        response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
+    }
+
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_key_characteristics(
+    const keymaster1_device_t* dev, const keymaster_key_blob_t* key_blob,
+    const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
+    keymaster_key_characteristics_t** characteristics) {
+    if (!dev || !key_blob || !key_blob->key_material)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!characteristics)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->get_key_characteristics(km1_dev, key_blob, client_id, app_data,
+                                                characteristics);
+
+    GetKeyCharacteristicsRequest request;
+    request.SetKeyMaterial(*key_blob);
+    AddClientAndAppData(client_id, app_data, &request);
+
+    GetKeyCharacteristicsResponse response;
+    convert_device(dev)->impl_->GetKeyCharacteristics(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
+    if (!*characteristics)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::get_key_characteristics(
+    const keymaster2_device_t* dev, const keymaster_key_blob_t* key_blob,
+    const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
+    keymaster_key_characteristics_t* characteristics) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!characteristics)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+
+    keymaster_error_t error;
+    keymaster_key_characteristics_t* key_characteristics;
+    error = get_key_characteristics(&sk_dev->km1_device_, key_blob, client_id, app_data,
+                                    &key_characteristics);
+    if (error != KM_ERROR_OK)
+        return error;
+    *characteristics = *key_characteristics;
+    free(key_characteristics);
+
+    return error;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::import_key(
+    const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
+    keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
+    keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
+    if (!params || !key_data)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!key_blob)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+
+    ImportKeyRequest request;
+    request.key_description.Reinitialize(*params);
+
+    keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
+    if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description))
+        return km1_dev->import_key(km1_dev, params, key_format, key_data, key_blob,
+                                   characteristics);
+
+    *characteristics = nullptr;
+
+    request.key_format = key_format;
+    request.SetKeyMaterial(key_data->data, key_data->data_length);
+
+    ImportKeyResponse response;
+    convert_device(dev)->impl_->ImportKey(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    key_blob->key_material_size = response.key_blob.key_material_size;
+    key_blob->key_material = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
+    if (!key_blob->key_material)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    memcpy(const_cast<uint8_t*>(key_blob->key_material), response.key_blob.key_material,
+           response.key_blob.key_material_size);
+
+    if (characteristics) {
+        *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
+        if (!*characteristics)
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::import_key(
+    const keymaster2_device_t* dev, const keymaster_key_param_set_t* params,
+    keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
+    keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+
+    keymaster_error_t error;
+    if (characteristics) {
+        keymaster_key_characteristics_t* characteristics_ptr;
+        error = import_key(&sk_dev->km1_device_, params, key_format, key_data, key_blob,
+                           &characteristics_ptr);
+        if (error == KM_ERROR_OK) {
+            *characteristics = *characteristics_ptr;
+            free(characteristics_ptr);
+        }
+    } else {
+        error = import_key(&sk_dev->km1_device_, params, key_format, key_data, key_blob, nullptr);
+    }
+
+    return error;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::export_key(const keymaster1_device_t* dev,
+                                                  keymaster_key_format_t export_format,
+                                                  const keymaster_key_blob_t* key_to_export,
+                                                  const keymaster_blob_t* client_id,
+                                                  const keymaster_blob_t* app_data,
+                                                  keymaster_blob_t* export_data) {
+    if (!key_to_export || !key_to_export->key_material)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!export_data)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev)
+        return km1_dev->export_key(km1_dev, export_format, key_to_export, client_id, app_data,
+                                   export_data);
+
+    export_data->data = nullptr;
+    export_data->data_length = 0;
+
+    ExportKeyRequest request;
+    request.key_format = export_format;
+    request.SetKeyMaterial(*key_to_export);
+    AddClientAndAppData(client_id, app_data, &request);
+
+    ExportKeyResponse response;
+    convert_device(dev)->impl_->ExportKey(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    export_data->data_length = response.key_data_length;
+    uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(export_data->data_length));
+    if (!tmp)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    memcpy(tmp, response.key_data, export_data->data_length);
+    export_data->data = tmp;
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::export_key(const keymaster2_device_t* dev,
+                                                  keymaster_key_format_t export_format,
+                                                  const keymaster_key_blob_t* key_to_export,
+                                                  const keymaster_blob_t* client_id,
+                                                  const keymaster_blob_t* app_data,
+                                                  keymaster_blob_t* export_data) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+    return export_key(&sk_dev->km1_device_, export_format, key_to_export, client_id, app_data,
+                      export_data);
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::attest_key(const keymaster2_device_t* dev,
+                                                  const keymaster_key_blob_t* key_to_attest,
+                                                  const keymaster_key_param_set_t* attest_params,
+                                                  keymaster_cert_chain_t* cert_chain) {
+    if (!dev || !key_to_attest || !attest_params || !cert_chain)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    cert_chain->entry_count = 0;
+    cert_chain->entries = nullptr;
+
+    AttestKeyRequest request;
+    request.SetKeyMaterial(*key_to_attest);
+    request.attest_params.Reinitialize(*attest_params);
+
+    AttestKeyResponse response;
+    convert_device(dev)->impl_->AttestKey(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    // Allocate and clear storage for cert_chain.
+    keymaster_cert_chain_t& rsp_chain = response.certificate_chain;
+    cert_chain->entries = reinterpret_cast<keymaster_blob_t*>(
+        malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries)));
+    if (!cert_chain->entries)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    cert_chain->entry_count = rsp_chain.entry_count;
+    for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count))
+        entry = {};
+
+    // Copy cert_chain contents
+    size_t i = 0;
+    for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) {
+        cert_chain->entries[i].data = reinterpret_cast<uint8_t*>(malloc(entry.data_length));
+        if (!cert_chain->entries[i].data) {
+            keymaster_free_cert_chain(cert_chain);
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        }
+        cert_chain->entries[i].data_length = entry.data_length;
+        memcpy(const_cast<uint8_t*>(cert_chain->entries[i].data), entry.data, entry.data_length);
+        ++i;
+    }
+
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::delete_key(const keymaster1_device_t* dev,
+                                                  const keymaster_key_blob_t* key) {
+    if (!dev || !key || !key->key_material)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    KeymasterKeyBlob blob(*key);
+    return convert_device(dev)->context_->DeleteKey(blob);
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::delete_key(const keymaster2_device_t* dev,
+                                                  const keymaster_key_blob_t* key) {
+    if (!dev || !key || !key->key_material)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    KeymasterKeyBlob blob(*key);
+    return convert_device(dev)->context_->DeleteKey(blob);
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::delete_all_keys(const keymaster1_device_t* dev) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    return convert_device(dev)->context_->DeleteAllKeys();
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::delete_all_keys(const keymaster2_device_t* dev) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    return convert_device(dev)->context_->DeleteAllKeys();
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::begin(const keymaster1_device_t* dev,
+                                             keymaster_purpose_t purpose,
+                                             const keymaster_key_blob_t* key,
+                                             const keymaster_key_param_set_t* in_params,
+                                             keymaster_key_param_set_t* out_params,
+                                             keymaster_operation_handle_t* operation_handle) {
+    if (!key || !key->key_material)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!operation_handle)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev) {
+        AuthorizationSet in_params_set(*in_params);
+
+        keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
+        keymaster_error_t error = GetAlgorithm(km1_dev, *key, in_params_set, &algorithm);
+        if (error != KM_ERROR_OK)
+            return error;
+
+        if (!convert_device(dev)->RequiresSoftwareDigesting(algorithm, purpose, in_params_set)) {
+            LOG_D("Operation supported by %s, passing through to keymaster1 module",
+                  km1_dev->common.module->name);
+            return km1_dev->begin(km1_dev, purpose, key, in_params, out_params, operation_handle);
+        }
+        LOG_I("Doing software digesting for keymaster1 module %s", km1_dev->common.module->name);
+    }
+
+    if (out_params) {
+        out_params->params = nullptr;
+        out_params->length = 0;
+    }
+
+    BeginOperationRequest request;
+    request.purpose = purpose;
+    request.SetKeyMaterial(*key);
+    request.additional_params.Reinitialize(*in_params);
+
+    BeginOperationResponse response;
+    convert_device(dev)->impl_->BeginOperation(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    if (response.output_params.size() > 0) {
+        if (out_params)
+            response.output_params.CopyToParamSet(out_params);
+        else
+            return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    }
+
+    *operation_handle = response.op_handle;
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::begin(const keymaster2_device_t* dev,
+                                             keymaster_purpose_t purpose,
+                                             const keymaster_key_blob_t* key,
+                                             const keymaster_key_param_set_t* in_params,
+                                             keymaster_key_param_set_t* out_params,
+                                             keymaster_operation_handle_t* operation_handle) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+    return begin(&sk_dev->km1_device_, purpose, key, in_params, out_params, operation_handle);
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::update(const keymaster1_device_t* dev,
+                                              keymaster_operation_handle_t operation_handle,
+                                              const keymaster_key_param_set_t* in_params,
+                                              const keymaster_blob_t* input, size_t* input_consumed,
+                                              keymaster_key_param_set_t* out_params,
+                                              keymaster_blob_t* output) {
+    if (!input)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (!input_consumed)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
+        // This operation is being handled by km1_dev (or doesn't exist).  Pass it through to
+        // km1_dev.  Otherwise, we'll use the software AndroidKeymaster, which may delegate to
+        // km1_dev after doing necessary digesting.
+        return km1_dev->update(km1_dev, operation_handle, in_params, input, input_consumed,
+                               out_params, output);
+    }
+
+    if (out_params) {
+        out_params->params = nullptr;
+        out_params->length = 0;
+    }
+    if (output) {
+        output->data = nullptr;
+        output->data_length = 0;
+    }
+
+    UpdateOperationRequest request;
+    request.op_handle = operation_handle;
+    if (input)
+        request.input.Reinitialize(input->data, input->data_length);
+    if (in_params)
+        request.additional_params.Reinitialize(*in_params);
+
+    UpdateOperationResponse response;
+    convert_device(dev)->impl_->UpdateOperation(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    if (response.output_params.size() > 0) {
+        if (out_params)
+            response.output_params.CopyToParamSet(out_params);
+        else
+            return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    }
+
+    *input_consumed = response.input_consumed;
+    if (output) {
+        output->data_length = response.output.available_read();
+        uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
+        if (!tmp)
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        memcpy(tmp, response.output.peek_read(), output->data_length);
+        output->data = tmp;
+    } else if (response.output.available_read() > 0) {
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    }
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::update(const keymaster2_device_t* dev,
+                                              keymaster_operation_handle_t operation_handle,
+                                              const keymaster_key_param_set_t* in_params,
+                                              const keymaster_blob_t* input, size_t* input_consumed,
+                                              keymaster_key_param_set_t* out_params,
+                                              keymaster_blob_t* output) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+    return update(&sk_dev->km1_device_, operation_handle, in_params, input, input_consumed,
+                  out_params, output);
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::finish(const keymaster1_device_t* dev,
+                                              keymaster_operation_handle_t operation_handle,
+                                              const keymaster_key_param_set_t* params,
+                                              const keymaster_blob_t* signature,
+                                              keymaster_key_param_set_t* out_params,
+                                              keymaster_blob_t* output) {
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
+        // This operation is being handled by km1_dev (or doesn't exist).  Pass it through to
+        // km1_dev.  Otherwise, we'll use the software AndroidKeymaster, which may delegate to
+        // km1_dev after doing necessary digesting.
+        return km1_dev->finish(km1_dev, operation_handle, params, signature, out_params, output);
+    }
+
+    if (out_params) {
+        out_params->params = nullptr;
+        out_params->length = 0;
+    }
+
+    if (output) {
+        output->data = nullptr;
+        output->data_length = 0;
+    }
+
+    FinishOperationRequest request;
+    request.op_handle = operation_handle;
+    if (signature && signature->data_length > 0)
+        request.signature.Reinitialize(signature->data, signature->data_length);
+    request.additional_params.Reinitialize(*params);
+
+    FinishOperationResponse response;
+    convert_device(dev)->impl_->FinishOperation(request, &response);
+    if (response.error != KM_ERROR_OK)
+        return response.error;
+
+    if (response.output_params.size() > 0) {
+        if (out_params)
+            response.output_params.CopyToParamSet(out_params);
+        else
+            return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    }
+    if (output) {
+        output->data_length = response.output.available_read();
+        uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
+        if (!tmp)
+            return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+        memcpy(tmp, response.output.peek_read(), output->data_length);
+        output->data = tmp;
+    } else if (response.output.available_read() > 0) {
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    }
+
+    return KM_ERROR_OK;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::finish(const keymaster2_device_t* dev,
+                                              keymaster_operation_handle_t operation_handle,
+                                              const keymaster_key_param_set_t* params,
+                                              const keymaster_blob_t* input,
+                                              const keymaster_blob_t* signature,
+                                              keymaster_key_param_set_t* out_params,
+                                              keymaster_blob_t* output) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    if (input && input->data)
+        return KM_ERROR_UNIMPLEMENTED;  // TODO(swillden): Implement this
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+    return finish(&sk_dev->km1_device_, operation_handle, params, signature, out_params, output);
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::abort(const keymaster1_device_t* dev,
+                                             keymaster_operation_handle_t operation_handle) {
+    const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
+    if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
+        // This operation is being handled by km1_dev (or doesn't exist).  Pass it through to
+        // km1_dev.  Otherwise, we'll use the software AndroidKeymaster, which may delegate to
+        // km1_dev.
+        return km1_dev->abort(km1_dev, operation_handle);
+    }
+
+    AbortOperationRequest request;
+    request.op_handle = operation_handle;
+    AbortOperationResponse response;
+    convert_device(dev)->impl_->AbortOperation(request, &response);
+    return response.error;
+}
+
+/* static */
+keymaster_error_t SoftKeymasterDevice::abort(const keymaster2_device_t* dev,
+                                             keymaster_operation_handle_t operation_handle) {
+    if (!dev)
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+
+    SoftKeymasterDevice* sk_dev = convert_device(dev);
+    return abort(&sk_dev->km1_device_, operation_handle);
+}
+
+/* static */
+void SoftKeymasterDevice::StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm,
+                                                   AuthorizationSet* auth_set) {
+    auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
+    auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
+    auth_set->push_back(TAG_ALL_USERS);
+    auth_set->push_back(TAG_NO_AUTH_REQUIRED);
+
+    // All digests.
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE);
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_MD5);
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
+    auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
+
+    if (algorithm == KM_ALGORITHM_RSA) {
+        auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
+        auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
+        auth_set->push_back(TAG_PADDING, KM_PAD_NONE);
+        auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
+        auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+        auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PSS);
+        auth_set->push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
+    }
+}
+
+}  // namespace keymaster
diff --git a/keymaster/soft_keymaster_logger.cpp b/keymaster/soft_keymaster_logger.cpp
new file mode 100644
index 0000000..3c55a64
--- /dev/null
+++ b/keymaster/soft_keymaster_logger.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.
+ */
+
+#include <keymaster/soft_keymaster_logger.h>
+
+#include <stdarg.h>
+#include <syslog.h>
+
+#define LOG_TAG "SoftKeymaster"
+#include <cutils/log.h>
+
+namespace keymaster {
+
+int SoftKeymasterLogger::log_msg(LogLevel level, const char* fmt, va_list args) const {
+
+    int android_log_level = ANDROID_LOG_ERROR;
+    switch (level) {
+    case DEBUG_LVL:
+        android_log_level = ANDROID_LOG_DEBUG;
+        break;
+    case INFO_LVL:
+        android_log_level = ANDROID_LOG_INFO;
+        break;
+    case WARNING_LVL:
+        android_log_level = ANDROID_LOG_WARN;
+        break;
+    case ERROR_LVL:
+        android_log_level = ANDROID_LOG_ERROR;
+        break;
+    case SEVERE_LVL:
+        android_log_level = ANDROID_LOG_ERROR;
+        break;
+    }
+
+    return LOG_PRI_VA(android_log_level, LOG_TAG, fmt, args);
+}
+
+}  // namespace keymaster
diff --git a/keymaster/sw_rsa_attest_root.key.pem b/keymaster/sw_rsa_attest_root.key.pem
new file mode 100644
index 0000000..387a852
--- /dev/null
+++ b/keymaster/sw_rsa_attest_root.key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCia63rbi5EYe/VDoLmt5TRdSMfd5tjkWP/96r/C3JHTsAsQ+wz
+fNes7UA+jCigZtX3hwszl94OuE4TQKuvpSe/lWmgMdsGUmX4RFlXYfC78hdLt0GA
+ZMAoDo9Sd47b0ke2RekZyOmLw9vCkT/X11DEHTVm+Vfkl5YLCazOkjWFmwIDAQAB
+AoGAU8dxXchmqzVNbbvff7zgUa63YErk51Yem/EXzhkMaIXRkMO0edaCtZtnkRvg
+9OQ2qEiLWaCTlUoyU7H/HUn2lwTQsOXyZI7dHijVDRMIv1mmrHCrGW/JC8FXfPLS
+r3L3KoHXQVYL2mslbR8Rpogxq4WwnwK6XqSTH9mynFwQwEkCQQDMX3EZk3ricWVH
+ruXD0BpXOMMpZuLu4rg5+1L51WEJvItIMeSjLuNa+g3AI8AYTYYi/aSLk6XEv82L
+iXFGmJ2XAkEAy3M8k8Z0QzHae4olduqoHVWEarBtDE+fqFQBWgdm8fZhdHWrvlAc
+qwJIXMUVc+dWm/FAQarCjbqWqhCRdaYgnQJBAJ7z7GdUCVNtlrQ2F4ZAqPwFreTZ
+nM7njxmpm1Os3hhQiJPSGl3A7huoOGGkbJd6VEWKuRvF7jwkYZ2RfITH1mkCQAvh
+X9E1Toa5+4spRwTJsSV9X+0m/kcwwx7+QNH0CrPockptsKi9Xt8xk+4u6BDLmogi
+r2DmStQh6DhoHUZkfBUCQQCOgBkqH/15drpdR+BQH3VaP4/ALFfxR9E3G+lS+M5a
+IqJEk9kh8vjuGzTaAZyU5keUmpWNc1gI7OvDMaH4+8vQ
+-----END RSA PRIVATE KEY-----
diff --git a/keymaster/symmetric_key.cpp b/keymaster/symmetric_key.cpp
new file mode 100644
index 0000000..1d51e3a
--- /dev/null
+++ b/keymaster/symmetric_key.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#include "symmetric_key.h"
+
+#include <assert.h>
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+#include <keymaster/keymaster_context.h>
+
+#include "aes_key.h"
+#include "hmac_key.h"
+#include "openssl_err.h"
+
+namespace keymaster {
+
+keymaster_error_t SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                                   KeymasterKeyBlob* key_blob,
+                                                   AuthorizationSet* hw_enforced,
+                                                   AuthorizationSet* sw_enforced) const {
+    if (!key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    uint32_t key_size_bits;
+    if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size_bits) ||
+        !key_size_supported(key_size_bits))
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+
+    keymaster_error_t error = validate_algorithm_specific_new_key_params(key_description);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    size_t key_data_size = key_size_bits / 8;
+    KeymasterKeyBlob key_material(key_data_size);
+    if (!key_material.key_material)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    error = context_->GenerateRandom(key_material.writable_data(), key_data_size);
+    if (error != KM_ERROR_OK) {
+        LOG_E("Error generating %d bit symmetric key", key_size_bits);
+        return error;
+    }
+
+    return context_->CreateKeyBlob(key_description, KM_ORIGIN_GENERATED, key_material, key_blob,
+                                   hw_enforced, sw_enforced);
+}
+
+keymaster_error_t SymmetricKeyFactory::ImportKey(const AuthorizationSet& key_description,
+                                                 keymaster_key_format_t input_key_material_format,
+                                                 const KeymasterKeyBlob& input_key_material,
+                                                 KeymasterKeyBlob* output_key_blob,
+                                                 AuthorizationSet* hw_enforced,
+                                                 AuthorizationSet* sw_enforced) const {
+    if (!output_key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+
+    AuthorizationSet authorizations(key_description);
+
+    uint32_t key_size_bits;
+    if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) {
+        // Default key size if not specified.
+        key_size_bits = input_key_material.key_material_size * 8;
+        authorizations.push_back(TAG_KEY_SIZE, key_size_bits);
+    }
+
+    keymaster_error_t error = validate_algorithm_specific_new_key_params(key_description);
+    if (error != KM_ERROR_OK)
+        return error;
+
+    if (!key_size_supported(key_size_bits))
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+
+    if (input_key_material_format != KM_KEY_FORMAT_RAW)
+        return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
+
+    if (key_size_bits != input_key_material.key_material_size * 8) {
+        LOG_E("Expected %d-bit key data but got %d bits", key_size_bits,
+              input_key_material.key_material_size * 8);
+        return KM_ERROR_INVALID_KEY_BLOB;
+    }
+
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
+                                   output_key_blob, hw_enforced, sw_enforced);
+}
+
+static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_RAW};
+const keymaster_key_format_t*
+SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) const {
+    *format_count = array_length(supported_import_formats);
+    return supported_import_formats;
+}
+
+SymmetricKey::SymmetricKey(const KeymasterKeyBlob& key_material,
+                           const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+                           keymaster_error_t* error)
+    : Key(hw_enforced, sw_enforced, error) {
+    if (*error != KM_ERROR_OK)
+        return;
+
+    uint8_t* tmp = dup_buffer(key_material.key_material, key_material.key_material_size);
+    if (tmp) {
+        key_data_.reset(tmp);
+        key_data_size_ = key_material.key_material_size;
+        *error = KM_ERROR_OK;
+    } else {
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+}
+
+SymmetricKey::~SymmetricKey() {
+    memset_s(key_data_.get(), 0, key_data_size_);
+}
+
+keymaster_error_t SymmetricKey::key_material(UniquePtr<uint8_t[]>* key_material,
+                                             size_t* size) const {
+    *size = key_data_size_;
+    key_material->reset(new (std::nothrow) uint8_t[*size]);
+    if (!key_material->get())
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    memcpy(key_material->get(), key_data_.get(), *size);
+    return KM_ERROR_OK;
+}
+
+}  // namespace keymaster
diff --git a/keymaster/symmetric_key.h b/keymaster/symmetric_key.h
new file mode 100644
index 0000000..979df62
--- /dev/null
+++ b/keymaster/symmetric_key.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef SYSTEM_KEYMASTER_SYMMETRIC_KEY_H_
+#define SYSTEM_KEYMASTER_SYMMETRIC_KEY_H_
+
+#include <keymaster/key_factory.h>
+
+#include "key.h"
+
+namespace keymaster {
+
+class SymmetricKey;
+
+class SymmetricKeyFactory : public KeyFactory {
+  public:
+    explicit SymmetricKeyFactory(const KeymasterContext* context) : KeyFactory(context) {}
+
+    keymaster_error_t GenerateKey(const AuthorizationSet& key_description,
+                                  KeymasterKeyBlob* key_blob, AuthorizationSet* hw_enforced,
+                                  AuthorizationSet* sw_enforced) const override;
+    keymaster_error_t ImportKey(const AuthorizationSet& key_description,
+                                keymaster_key_format_t input_key_material_format,
+                                const KeymasterKeyBlob& input_key_material,
+                                KeymasterKeyBlob* output_key_blob, AuthorizationSet* hw_enforced,
+                                AuthorizationSet* sw_enforced) const override;
+
+    virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) const;
+    virtual const keymaster_key_format_t* SupportedExportFormats(size_t* format_count) const {
+        return NoFormats(format_count);
+    };
+
+  private:
+    virtual bool key_size_supported(size_t key_size_bits) const = 0;
+    virtual keymaster_error_t
+    validate_algorithm_specific_new_key_params(const AuthorizationSet& key_description) const = 0;
+
+    const keymaster_key_format_t* NoFormats(size_t* format_count) const {
+        *format_count = 0;
+        return NULL;
+    }
+};
+
+class SymmetricKey : public Key {
+  public:
+    ~SymmetricKey();
+
+    virtual keymaster_error_t key_material(UniquePtr<uint8_t[]>* key_material, size_t* size) const;
+    virtual keymaster_error_t formatted_key_material(keymaster_key_format_t, UniquePtr<uint8_t[]>*,
+                                                     size_t*) const {
+        return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
+    }
+
+    const uint8_t* key_data() const { return key_data_.get(); }
+    size_t key_data_size() const { return key_data_size_; }
+
+  protected:
+    SymmetricKey(const KeymasterKeyBlob& key_material, const AuthorizationSet& hw_enforced,
+                 const AuthorizationSet& sw_enforced, keymaster_error_t* error);
+
+  private:
+    size_t key_data_size_;
+    UniquePtr<uint8_t[]> key_data_;
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_AES_KEY_H_
diff --git a/keymaster/valgrind.supp b/keymaster/valgrind.supp
new file mode 100644
index 0000000..2838278
--- /dev/null
+++ b/keymaster/valgrind.supp
@@ -0,0 +1,40 @@
+{
+   BoringSSLErrorLeak
+   Memcheck:Leak
+   fun:malloc
+   ...
+   fun:err_get_state
+   ...
+}
+{
+   EcKeyErrorLeak
+   Memcheck:Leak
+   fun:malloc
+   fun:err_add_error_vdata
+   fun:ERR_add_error_data
+   fun:ASN1_item_ex_d2i
+   fun:ASN1_item_d2i
+   fun:d2i_EC_PRIVATEKEY
+   fun:d2i_ECPrivateKey
+   fun:old_ec_priv_decode
+   fun:d2i_PrivateKey
+   ...
+}
+{
+   BoringSSLGetNewIndexLeak1
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:malloc
+   ...
+   fun:CRYPTO_get_ex_new_index
+   ...
+}
+{
+   BoringSSLGetNewIndexLeak2
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:realloc
+   ...
+   fun:CRYPTO_get_ex_new_index
+   ...
+}
\ No newline at end of file
