Switch to using global logger

Change-Id: I7af02342320a9a431cd9845baaf5dbcf61d460c2
diff --git a/Android.mk b/Android.mk
index f24bebc..407db46 100644
--- a/Android.mk
+++ b/Android.mk
@@ -59,8 +59,8 @@
 		key_blob.cpp \
 		logger.cpp \
 		ocb.c \
-		operation.cpp \
 		openssl_err.cpp \
+		operation.cpp \
 		rsa_key.cpp \
 		rsa_operation.cpp \
 		serializable.cpp \
diff --git a/Makefile b/Makefile
index 4c3c809..ad11e1b 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,11 @@
 CXXFLAGS=-Wall -Werror -Wno-unused -Winit-self -Wpointer-arith	-Wunused-parameter \
 	-Wmissing-declarations -ftest-coverage \
 	-Wno-deprecated-declarations -fno-exceptions -DKEYMASTER_NAME_TAGS \
-	$(COMPILER_SPECIFIC_ARGS) -DDEBUG
+	$(COMPILER_SPECIFIC_ARGS)
+
+# Uncomment to enable debug logging.
+# CXXFLAGS += -DDEBUG
+
 LDLIBS=-lcrypto -lpthread -lstdc++
 
 CPPSRCS=\
@@ -123,6 +127,7 @@
 	key_blob.o \
 	logger.o \
 	ocb.o \
+	openssl_err.o \
 	serializable.o \
 	unencrypted_key_blob.o \
 	$(GTEST)/src/gtest-all.o
diff --git a/aead_mode_operation.cpp b/aead_mode_operation.cpp
index 8aa5535..05ed6e9 100644
--- a/aead_mode_operation.cpp
+++ b/aead_mode_operation.cpp
@@ -19,7 +19,10 @@
 #include <openssl/aes.h>
 #include <openssl/rand.h>
 
+#include <keymaster/logger.h>
+
 #include "aead_mode_operation.h"
+#include "openssl_err.h"
 
 namespace keymaster {
 
@@ -90,7 +93,7 @@
         if (buffered_data_length() < tag_length_)
             return KM_ERROR_INVALID_INPUT_LENGTH;
         ExtractTagFromBuffer();
-        logger().info("AeadMode decrypting %d", buffered_data_length());
+        LOG_D("AeadMode decrypting %d", buffered_data_length());
         if (!output->reserve(output->available_read() + buffered_data_length()))
             error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
         else
@@ -121,7 +124,7 @@
         return output->available_read() + chunk_length * chunk_count;
     }
     default:
-        logger().error("Encountered invalid purpose %d", purpose());
+        LOG_E("Encountered invalid purpose %d", purpose());
         return 0;
     }
 }
@@ -130,8 +133,8 @@
     switch (purpose()) {
     case KM_PURPOSE_ENCRYPT:
         if (!RAND_bytes(nonce_, nonce_length_)) {
-            logger().error("Failed to generate nonce");
-            return KM_ERROR_UNKNOWN_ERROR;
+            LOG_S("Failed to generate %d-byte nonce", nonce_length_);
+            return TranslateLastOpenSslError();
         }
         if (!output->reserve(nonce_length_))
             return KM_ERROR_MEMORY_ALLOCATION_FAILED;
diff --git a/aead_mode_operation.h b/aead_mode_operation.h
index cb976a2..e89da20 100644
--- a/aead_mode_operation.h
+++ b/aead_mode_operation.h
@@ -28,10 +28,10 @@
     static const size_t MAX_TAG_LENGTH = 16;
     static const size_t MAX_KEY_LENGTH = 32;
 
-    AeadModeOperation(keymaster_purpose_t purpose, const Logger& logger, const uint8_t* key,
-                      size_t key_size, size_t chunk_length, size_t tag_length, size_t nonce_length,
+    AeadModeOperation(keymaster_purpose_t purpose, const uint8_t* key, size_t key_size,
+                      size_t chunk_length, size_t tag_length, size_t nonce_length,
                       keymaster_blob_t additional_data)
-        : Operation(purpose, logger), key_size_(key_size), tag_length_(tag_length),
+        : Operation(purpose), key_size_(key_size), tag_length_(tag_length),
           nonce_length_(nonce_length),
           processing_unit_(purpose == KM_PURPOSE_DECRYPT ? chunk_length + tag_length
                                                          : chunk_length),
diff --git a/aes_key.cpp b/aes_key.cpp
index 87a63a7..2519f61 100644
--- a/aes_key.cpp
+++ b/aes_key.cpp
@@ -30,14 +30,11 @@
   public:
     keymaster_algorithm_t registry_key() const { return KM_ALGORITHM_AES; }
 
-    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, const Logger& logger,
-                         keymaster_error_t* error) {
-        return new AesKey(blob, logger, error);
+    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) {
+        return new AesKey(blob, error);
     }
 
-    virtual SymmetricKey* CreateKey(const AuthorizationSet& auths, const Logger& logger) {
-        return new AesKey(auths, logger);
-    }
+    virtual SymmetricKey* CreateKey(const AuthorizationSet& auths) { return new AesKey(auths); }
 };
 static KeyFactoryRegistry::Registration<AesKeyFactory> registration;
 
diff --git a/aes_key.h b/aes_key.h
index bd6d905..f79d5a2 100644
--- a/aes_key.h
+++ b/aes_key.h
@@ -25,9 +25,8 @@
 
 class AesKey : public SymmetricKey {
   public:
-    AesKey(const AuthorizationSet& auths, const Logger& logger) : SymmetricKey(auths, logger) {}
-    AesKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error)
-        : SymmetricKey(blob, logger, error) {}
+    AesKey(const AuthorizationSet& auths) : SymmetricKey(auths) {}
+    AesKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) : SymmetricKey(blob, error) {}
 };
 
 }  // namespace keymaster
diff --git a/aes_operation.cpp b/aes_operation.cpp
index 0b17249..e605d2a 100644
--- a/aes_operation.cpp
+++ b/aes_operation.cpp
@@ -19,6 +19,8 @@
 #include <openssl/aes.h>
 #include <openssl/rand.h>
 
+#include <keymaster/logger.h>
+
 #include "aes_key.h"
 #include "aes_operation.h"
 
@@ -32,15 +34,13 @@
   public:
     virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_AES, purpose()); }
 
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error);
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
     virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const;
 
     virtual keymaster_purpose_t purpose() const = 0;
 };
 
-Operation* AesOcbOperationFactory::CreateOperation(const Key& key, const Logger& logger,
-                                                   keymaster_error_t* error) {
+Operation* AesOcbOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
     *error = KM_ERROR_OK;
 
     keymaster_block_mode_t block_mode;
@@ -87,9 +87,9 @@
     keymaster_blob_t additional_data = {0, 0};
     symmetric_key->authorizations().GetTagValue(TAG_ASSOCIATED_DATA, &additional_data);
 
-    Operation* op = new AesOcbOperation(purpose(), logger, symmetric_key->key_data(),
-                                        symmetric_key->key_data_size(), chunk_length, tag_length,
-                                        additional_data);
+    Operation* op =
+        new AesOcbOperation(purpose(), symmetric_key->key_data(), symmetric_key->key_data_size(),
+                            chunk_length, tag_length, additional_data);
     if (!op)
         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return op;
diff --git a/aes_operation.h b/aes_operation.h
index 6a9d69f..0ceb631 100644
--- a/aes_operation.h
+++ b/aes_operation.h
@@ -29,10 +29,9 @@
     static const size_t MAX_TAG_LENGTH = 16;
     static const size_t MAX_KEY_LENGTH = 32;
 
-    AesOcbOperation(keymaster_purpose_t purpose, const Logger& logger, const uint8_t* key,
-                    size_t key_size, size_t chunk_length, size_t tag_length,
-                    keymaster_blob_t additional_data)
-        : AeadModeOperation(purpose, logger, key, key_size, chunk_length, tag_length, NONCE_LENGTH,
+    AesOcbOperation(keymaster_purpose_t purpose, const uint8_t* key, size_t key_size,
+                    size_t chunk_length, size_t tag_length, keymaster_blob_t additional_data)
+        : AeadModeOperation(purpose, key, key_size, chunk_length, tag_length, NONCE_LENGTH,
                             additional_data) {}
 
     virtual keymaster_error_t Abort() {
diff --git a/asymmetric_key.cpp b/asymmetric_key.cpp
index 65249fe..57d4d1c 100644
--- a/asymmetric_key.cpp
+++ b/asymmetric_key.cpp
@@ -21,6 +21,7 @@
 #include <hardware/keymaster_defs.h>
 
 #include "ecdsa_key.h"
+#include "openssl_err.h"
 #include "openssl_utils.h"
 #include "rsa_key.h"
 #include "unencrypted_key_blob.h"
@@ -99,7 +100,7 @@
         return KM_ERROR_INVALID_KEY_BLOB;
     }
     if (!EvpToInternal(evp_key.get()))
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
 
     return KM_ERROR_OK;
 }
@@ -113,11 +114,11 @@
         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
 
     if (!InternalToEvp(pkey.get()))
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
 
     *size = i2d_PrivateKey(pkey.get(), NULL /* key_data*/);
     if (*size <= 0)
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
 
     material->reset(new uint8_t[*size]);
     uint8_t* tmp = material->get();
@@ -137,11 +138,11 @@
 
     UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new());
     if (!InternalToEvp(pkey.get()))
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
 
     int key_data_length = i2d_PUBKEY(pkey.get(), NULL);
     if (key_data_length <= 0)
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
 
     material->reset(new uint8_t[key_data_length]);
     if (material->get() == NULL)
@@ -150,7 +151,7 @@
     uint8_t* tmp = material->get();
     if (i2d_PUBKEY(pkey.get(), &tmp) != key_data_length) {
         material->reset();
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
     }
 
     *size = key_data_length;
diff --git a/asymmetric_key.h b/asymmetric_key.h
index b715077..a55c9b5 100644
--- a/asymmetric_key.h
+++ b/asymmetric_key.h
@@ -39,7 +39,7 @@
 class AsymmetricKey : public Key {
   public:
   protected:
-    AsymmetricKey(const KeyBlob& blob, const Logger& logger) : Key(blob, logger) {}
+    AsymmetricKey(const KeyBlob& blob) : Key(blob) {}
     keymaster_error_t LoadKey(const UnencryptedKeyBlob& blob);
 
     /**
@@ -55,7 +55,7 @@
                                                      size_t* size) const;
 
   protected:
-    AsymmetricKey(const AuthorizationSet& auths, const Logger& logger) : Key(auths, logger) {}
+    AsymmetricKey(const AuthorizationSet& auths) : Key(auths) {}
 
   private:
     virtual int evp_key_type() = 0;
diff --git a/ecdsa_key.cpp b/ecdsa_key.cpp
index 448374f..f90cf80 100644
--- a/ecdsa_key.cpp
+++ b/ecdsa_key.cpp
@@ -16,6 +16,7 @@
 
 #include "ecdsa_key.h"
 #include "ecdsa_operation.h"
+#include "openssl_err.h"
 #include "openssl_utils.h"
 #include "unencrypted_key_blob.h"
 
@@ -27,14 +28,12 @@
   public:
     virtual keymaster_algorithm_t registry_key() const { return KM_ALGORITHM_ECDSA; }
 
-    virtual Key* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
-                             keymaster_error_t* error);
+    virtual Key* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
     virtual Key* ImportKey(const AuthorizationSet& key_description,
                            keymaster_key_format_t key_format, const uint8_t* key_data,
-                           size_t key_data_length, const Logger& logger, keymaster_error_t* error);
-    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, const Logger& logger,
-                         keymaster_error_t* error) {
-        return new EcdsaKey(blob, logger, error);
+                           size_t key_data_length, keymaster_error_t* error);
+    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) {
+        return new EcdsaKey(blob, error);
     }
 
   private:
@@ -47,7 +46,7 @@
 };
 static KeyFactoryRegistry::Registration<EcdsaKeyFactory> registration;
 
-Key* EcdsaKeyFactory::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+Key* EcdsaKeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                   keymaster_error_t* error) {
     if (!error)
         return NULL;
@@ -79,19 +78,18 @@
 
     if (EC_KEY_set_group(ecdsa_key.get(), group.get()) != 1 ||
         EC_KEY_generate_key(ecdsa_key.get()) != 1 || EC_KEY_check_key(ecdsa_key.get()) < 0) {
-        *error = KM_ERROR_UNKNOWN_ERROR;
+        *error = TranslateLastOpenSslError();
         return NULL;
     }
 
-    EcdsaKey* new_key = new EcdsaKey(ecdsa_key.release(), authorizations, logger);
+    EcdsaKey* new_key = new EcdsaKey(ecdsa_key.release(), authorizations);
     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return new_key;
 }
 
 Key* EcdsaKeyFactory::ImportKey(const AuthorizationSet& key_description,
                                 keymaster_key_format_t key_format, const uint8_t* key_data,
-                                size_t key_data_length, const Logger& logger,
-                                keymaster_error_t* error) {
+                                size_t key_data_length, keymaster_error_t* error) {
     if (!error)
         return NULL;
 
@@ -103,7 +101,7 @@
 
     UniquePtr<EC_KEY, EcdsaKey::ECDSA_Delete> ecdsa_key(EVP_PKEY_get1_EC_KEY(pkey.get()));
     if (!ecdsa_key.get()) {
-        *error = KM_ERROR_UNKNOWN_ERROR;
+        *error = TranslateLastOpenSslError();
         return NULL;
     }
 
@@ -140,7 +138,7 @@
     // missing, the error will be diagnosed when the key is used (when auth checking is
     // implemented).
     *error = KM_ERROR_OK;
-    return new EcdsaKey(ecdsa_key.release(), authorizations, logger);
+    return new EcdsaKey(ecdsa_key.release(), authorizations);
 }
 
 /* static */
@@ -185,8 +183,7 @@
     return KM_ERROR_OK;
 }
 
-EcdsaKey::EcdsaKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error)
-    : AsymmetricKey(blob, logger) {
+EcdsaKey::EcdsaKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) : AsymmetricKey(blob) {
     if (error)
         *error = LoadKey(blob);
 }
diff --git a/ecdsa_key.h b/ecdsa_key.h
index 3b7b563..a0a78e2 100644
--- a/ecdsa_key.h
+++ b/ecdsa_key.h
@@ -33,9 +33,9 @@
     friend EcdsaSignOperationFactory;
     friend EcdsaVerifyOperationFactory;
 
-    EcdsaKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error);
-    EcdsaKey(EC_KEY* ecdsa_key, const AuthorizationSet auths, const Logger& logger)
-        : AsymmetricKey(auths, logger), ecdsa_key_(ecdsa_key) {}
+    EcdsaKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error);
+    EcdsaKey(EC_KEY* ecdsa_key, const AuthorizationSet auths)
+        : AsymmetricKey(auths), ecdsa_key_(ecdsa_key) {}
 
     virtual int evp_key_type() { return EVP_PKEY_EC; }
     virtual bool InternalToEvp(EVP_PKEY* pkey) const;
diff --git a/ecdsa_operation.cpp b/ecdsa_operation.cpp
index 3bc0d88..3a07537 100644
--- a/ecdsa_operation.cpp
+++ b/ecdsa_operation.cpp
@@ -18,6 +18,7 @@
 
 #include "ecdsa_key.h"
 #include "ecdsa_operation.h"
+#include "openssl_err.h"
 #include "openssl_utils.h"
 
 namespace keymaster {
@@ -26,15 +27,14 @@
   public:
     virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN); }
 
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error){
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error) {
         const EcdsaKey* ecdsa_key = static_cast<const EcdsaKey*>(&key);
         if (!ecdsa_key) {
             *error = KM_ERROR_UNKNOWN_ERROR;
             return NULL;
         }
 
-        Operation* op = new EcdsaSignOperation(KM_PURPOSE_SIGN, logger, ecdsa_key->key());
+        Operation* op = new EcdsaSignOperation(KM_PURPOSE_SIGN, ecdsa_key->key());
         if (!op)
             *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
         return op;
@@ -46,15 +46,14 @@
   public:
     virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_ECDSA, KM_PURPOSE_VERIFY); }
 
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error){
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error) {
         const EcdsaKey* ecdsa_key = static_cast<const EcdsaKey*>(&key);
         if (!ecdsa_key) {
             *error = KM_ERROR_UNKNOWN_ERROR;
             return NULL;
         }
 
-        Operation* op = new EcdsaVerifyOperation(KM_PURPOSE_VERIFY, logger, ecdsa_key->key());
+        Operation* op = new EcdsaVerifyOperation(KM_PURPOSE_VERIFY, ecdsa_key->key());
         if (!op)
             *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
         return op;
@@ -111,7 +110,7 @@
     unsigned int siglen;
     if (!ECDSA_sign(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
                     output->peek_write(), &siglen, ecdsa_key_))
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
     output->advance_write(siglen);
     return KM_ERROR_OK;
 }
@@ -121,7 +120,7 @@
     int result = ECDSA_verify(0 /* type -- ignored */, data_.peek_read(), data_.available_read(),
                               signature.peek_read(), signature.available_read(), ecdsa_key_);
     if (result < 0)
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
     else if (result == 0)
         return KM_ERROR_VERIFICATION_FAILED;
     else
diff --git a/ecdsa_operation.h b/ecdsa_operation.h
index fdfe526..4ec8a4b 100644
--- a/ecdsa_operation.h
+++ b/ecdsa_operation.h
@@ -29,8 +29,8 @@
 
 class EcdsaOperation : public Operation {
   public:
-    EcdsaOperation(keymaster_purpose_t purpose, const Logger& logger, EC_KEY* key)
-        : Operation(purpose, logger), ecdsa_key_(key) {}
+    EcdsaOperation(keymaster_purpose_t purpose, EC_KEY* key)
+        : Operation(purpose), ecdsa_key_(key) {}
     ~EcdsaOperation();
 
     virtual keymaster_error_t Begin(const AuthorizationSet& /* input_params */,
@@ -50,16 +50,14 @@
 
 class EcdsaSignOperation : public EcdsaOperation {
   public:
-    EcdsaSignOperation(keymaster_purpose_t purpose, const Logger& logger, EC_KEY* key)
-        : EcdsaOperation(purpose, logger, key) {}
+    EcdsaSignOperation(keymaster_purpose_t purpose, EC_KEY* key) : EcdsaOperation(purpose, key) {}
     virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
                                      const Buffer& signature, Buffer* output);
 };
 
 class EcdsaVerifyOperation : public EcdsaOperation {
   public:
-    EcdsaVerifyOperation(keymaster_purpose_t purpose, const Logger& logger, EC_KEY* key)
-        : EcdsaOperation(purpose, logger, key) {}
+    EcdsaVerifyOperation(keymaster_purpose_t purpose, EC_KEY* key) : EcdsaOperation(purpose, key) {}
     virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
                                      const Buffer& signature, Buffer* output);
 };
diff --git a/google_keymaster.cpp b/google_keymaster.cpp
index cda181d..f4aafbe 100644
--- a/google_keymaster.cpp
+++ b/google_keymaster.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <keymaster/google_keymaster.h>
+
 #include <assert.h>
 #include <string.h>
 
@@ -24,11 +26,11 @@
 
 #include <UniquePtr.h>
 
-#include <keymaster/google_keymaster.h>
 #include <keymaster/google_keymaster_utils.h>
 
 #include "ae.h"
 #include "key.h"
+#include "openssl_err.h"
 #include "operation.h"
 #include "unencrypted_key_blob.h"
 
@@ -38,9 +40,9 @@
 const uint8_t MINOR_VER = 0;
 const uint8_t SUBMINOR_VER = 0;
 
-GoogleKeymaster::GoogleKeymaster(size_t operation_table_size, Logger* logger)
+GoogleKeymaster::GoogleKeymaster(size_t operation_table_size)
     : operation_table_(new OpTableEntry[operation_table_size]),
-      operation_table_size_(operation_table_size), logger_(logger) {
+      operation_table_size_(operation_table_size) {
     if (operation_table_.get() == NULL)
         operation_table_size_ = 0;
 }
@@ -192,7 +194,7 @@
         !(factory = KeyFactoryRegistry::Get(algorithm)))
         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
     else
-        key.reset(factory->GenerateKey(request.key_description, logger(), &response->error));
+        key.reset(factory->GenerateKey(request.key_description, &response->error));
 
     if (response->error != KM_ERROR_OK)
         return;
@@ -236,7 +238,7 @@
         return;
     }
 
-    UniquePtr<Operation> operation(factory->CreateOperation(*key, logger(), &response->error));
+    UniquePtr<Operation> operation(factory->CreateOperation(*key, &response->error));
     if (operation.get() == NULL)
         return;
 
@@ -325,7 +327,7 @@
         response->error = KM_ERROR_UNSUPPORTED_ALGORITHM;
     else
         key.reset(factory->ImportKey(request.key_description, request.key_format, request.key_data,
-                                     request.key_data_length, logger(), &response->error));
+                                     request.key_data_length, &response->error));
 
     if (response->error != KM_ERROR_OK)
         return;
@@ -390,7 +392,7 @@
 
     KeyFactory* factory = 0;
     if ((factory = KeyFactoryRegistry::Get(*algorithm)))
-        return factory->LoadKey(*blob, logger(), error);
+        return factory->LoadKey(*blob, error);
     *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
     return NULL;
 }
@@ -489,7 +491,7 @@
                                                 keymaster_operation_handle_t* op_handle) {
     UniquePtr<Operation> op(operation);
     if (RAND_bytes(reinterpret_cast<uint8_t*>(op_handle), sizeof(*op_handle)) == 0)
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
     if (*op_handle == 0) {
         // Statistically this is vanishingly unlikely, which means if it ever happens in practice,
         // it indicates a broken RNG.
diff --git a/google_keymaster_test.cpp b/google_keymaster_test.cpp
index 04b50e8..c832235 100644
--- a/google_keymaster_test.cpp
+++ b/google_keymaster_test.cpp
@@ -163,12 +163,12 @@
     AuthorizationSet set;
 };
 
+StdoutLogger logger;
+
 const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
 class KeymasterTest : public testing::Test {
   protected:
-    KeymasterTest()
-        : device_(new StdoutLogger), out_params_(NULL), op_handle_(OP_HANDLE_SENTINEL),
-          characteristics_(NULL) {
+    KeymasterTest() : out_params_(NULL), op_handle_(OP_HANDLE_SENTINEL), characteristics_(NULL) {
         blob_.key_material = NULL;
         RAND_seed("foobar", 6);
         blob_.key_material = 0;
@@ -672,7 +672,7 @@
 }
 
 TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
-    GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256, KM_PAD_NONE));
+    GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_MD5, KM_PAD_NONE));
     ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
 }
 
diff --git a/google_softkeymaster.h b/google_softkeymaster.h
index fa96d14..e8b958e 100644
--- a/google_softkeymaster.h
+++ b/google_softkeymaster.h
@@ -23,8 +23,7 @@
 
 class GoogleSoftKeymaster : public GoogleKeymaster {
   public:
-    GoogleSoftKeymaster(size_t operation_table_size, Logger* logger)
-        : GoogleKeymaster(operation_table_size, logger) {
+    GoogleSoftKeymaster(size_t operation_table_size) : GoogleKeymaster(operation_table_size) {
         root_of_trust.tag = KM_TAG_ROOT_OF_TRUST;
         root_of_trust.blob.data = reinterpret_cast<const uint8_t*>("SW");
         root_of_trust.blob.data_length = 2;
diff --git a/hmac_key.cpp b/hmac_key.cpp
index 278fa6d..0f43640 100644
--- a/hmac_key.cpp
+++ b/hmac_key.cpp
@@ -27,14 +27,11 @@
   public:
     keymaster_algorithm_t registry_key() const { return KM_ALGORITHM_HMAC; }
 
-    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, const Logger& logger,
-                         keymaster_error_t* error) {
-        return new HmacKey(blob, logger, error);
+    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) {
+        return new HmacKey(blob, error);
     }
 
-    virtual SymmetricKey* CreateKey(const AuthorizationSet& auths, const Logger& logger) {
-        return new HmacKey(auths, logger);
-    }
+    virtual SymmetricKey* CreateKey(const AuthorizationSet& auths) { return new HmacKey(auths); }
 };
 
 static KeyFactoryRegistry::Registration<HmacKeyFactory> registration;
diff --git a/hmac_key.h b/hmac_key.h
index afb877c..f94dea8 100644
--- a/hmac_key.h
+++ b/hmac_key.h
@@ -23,9 +23,8 @@
 
 class HmacKey : public SymmetricKey {
   public:
-    HmacKey(const AuthorizationSet& auths, const Logger& logger) : SymmetricKey(auths, logger) {}
-    HmacKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error)
-        : SymmetricKey(blob, logger, error) {}
+    HmacKey(const AuthorizationSet& auths) : SymmetricKey(auths) {}
+    HmacKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) : SymmetricKey(blob, error) {}
 };
 
 }  // namespace keymaster
diff --git a/hmac_operation.cpp b/hmac_operation.cpp
index 8e67624..fa243d5 100644
--- a/hmac_operation.cpp
+++ b/hmac_operation.cpp
@@ -19,6 +19,7 @@
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 
+#include "openssl_err.h"
 #include "symmetric_key.h"
 
 #if defined(OPENSSL_IS_BORINGSSL)
@@ -37,16 +38,14 @@
   public:
     virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_HMAC, purpose()); }
 
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error);
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
 
     virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const;
 
     virtual keymaster_purpose_t purpose() const = 0;
 };
 
-Operation* HmacOperationFactory::CreateOperation(const Key& key, const Logger& logger,
-                                                 keymaster_error_t* error) {
+Operation* HmacOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
     *error = KM_ERROR_OK;
 
     uint32_t tag_length;
@@ -66,7 +65,7 @@
         return NULL;
     }
 
-    Operation* op = new HmacOperation(purpose(), logger, symmetric_key->key_data(),
+    Operation* op = new HmacOperation(purpose(), symmetric_key->key_data(),
                                       symmetric_key->key_data_size(), digest, tag_length);
     if (!op)
         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
@@ -97,10 +96,9 @@
 };
 static OperationFactoryRegistry::Registration<HmacVerifyOperationFactory> verify_registration;
 
-HmacOperation::HmacOperation(keymaster_purpose_t purpose, const Logger& logger,
-                             const uint8_t* key_data, size_t key_data_size,
-                             keymaster_digest_t digest, size_t tag_length)
-    : Operation(purpose, logger), error_(KM_ERROR_OK), tag_length_(tag_length) {
+HmacOperation::HmacOperation(keymaster_purpose_t purpose, const uint8_t* key_data,
+                             size_t key_data_size, keymaster_digest_t digest, size_t tag_length)
+    : Operation(purpose), error_(KM_ERROR_OK), tag_length_(tag_length) {
     // Initialize CTX first, so dtor won't crash even if we error out later.
     HMAC_CTX_init(&ctx_);
 
@@ -144,7 +142,7 @@
                                         const Buffer& input, Buffer* /* output */,
                                         size_t* input_consumed) {
     if (!HMAC_Update(&ctx_, input.peek_read(), input.available_read()))
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
     *input_consumed = input.available_read();
     return KM_ERROR_OK;
 }
@@ -158,7 +156,7 @@
     uint8_t digest[EVP_MAX_MD_SIZE];
     unsigned int digest_len;
     if (!HMAC_Final(&ctx_, digest, &digest_len))
-        return KM_ERROR_UNKNOWN_ERROR;
+        return TranslateLastOpenSslError();
 
     switch (purpose()) {
     case KM_PURPOSE_SIGN:
diff --git a/hmac_operation.h b/hmac_operation.h
index 41325b6..8baabe0 100644
--- a/hmac_operation.h
+++ b/hmac_operation.h
@@ -25,8 +25,8 @@
 
 class HmacOperation : public Operation {
   public:
-    HmacOperation(keymaster_purpose_t purpose, const Logger& logger, const uint8_t* key_data,
-                  size_t key_data_size, keymaster_digest_t digest, size_t tag_length);
+    HmacOperation(keymaster_purpose_t purpose, const uint8_t* key_data, size_t key_data_size,
+                  keymaster_digest_t digest, size_t tag_length);
     ~HmacOperation();
 
     virtual keymaster_error_t Begin(const AuthorizationSet& input_params,
diff --git a/include/keymaster/google_keymaster.h b/include/keymaster/google_keymaster.h
index dfff076..166eb09 100644
--- a/include/keymaster/google_keymaster.h
+++ b/include/keymaster/google_keymaster.h
@@ -19,7 +19,6 @@
 
 #include <keymaster/authorization_set.h>
 #include <keymaster/google_keymaster_messages.h>
-#include <keymaster/logger.h>
 
 namespace keymaster {
 
@@ -44,7 +43,7 @@
  */
 class GoogleKeymaster {
   public:
-    GoogleKeymaster(size_t operation_table_size, Logger* logger);
+    GoogleKeymaster(size_t operation_table_size);
     virtual ~GoogleKeymaster();
 
     void SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const;
@@ -78,8 +77,6 @@
     keymaster_error_t AbortOperation(const keymaster_operation_handle_t op_handle);
     void GetVersion(const GetVersionRequest& request, GetVersionResponse* response);
 
-    const Logger& logger() const { return *logger_; }
-
   private:
     virtual bool is_enforced(keymaster_tag_t tag) = 0;
     virtual keymaster_key_origin_t origin() = 0;
@@ -120,7 +117,6 @@
 
     UniquePtr<OpTableEntry[]> operation_table_;
     size_t operation_table_size_;
-    UniquePtr<Logger> logger_;
 };
 
 }  // namespace keymaster
diff --git a/include/keymaster/soft_keymaster_device.h b/include/keymaster/soft_keymaster_device.h
index c749e5d..565210c 100644
--- a/include/keymaster/soft_keymaster_device.h
+++ b/include/keymaster/soft_keymaster_device.h
@@ -40,7 +40,7 @@
  */
 class SoftKeymasterDevice {
   public:
-    SoftKeymasterDevice(Logger* logger);
+    SoftKeymasterDevice();
 
     hw_device_t* hw_device();
 
diff --git a/key.cpp b/key.cpp
index 00affef..6efa6f9 100644
--- a/key.cpp
+++ b/key.cpp
@@ -29,7 +29,7 @@
 /* static */
 template <> KeyFactoryRegistry* KeyFactoryRegistry::instance_ptr = 0;
 
-Key::Key(const KeyBlob& blob, const Logger& logger) : logger_(logger) {
+Key::Key(const KeyBlob& blob) {
     authorizations_.push_back(blob.unenforced());
     authorizations_.push_back(blob.enforced());
 }
diff --git a/key.h b/key.h
index 96200bd..f7d2a1c 100644
--- a/key.h
+++ b/key.h
@@ -41,14 +41,11 @@
     virtual keymaster_algorithm_t registry_key() const = 0;
 
     // Factory methods.
-    virtual Key* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
-                             keymaster_error_t* error) = 0;
+    virtual Key* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error) = 0;
     virtual Key* ImportKey(const AuthorizationSet& key_description,
                            keymaster_key_format_t key_format, const uint8_t* key_data,
-                           size_t key_data_length, const Logger& logger,
-                           keymaster_error_t* error) = 0;
-    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, const Logger& logger,
-                         keymaster_error_t* error) = 0;
+                           size_t key_data_length, keymaster_error_t* error) = 0;
+    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) = 0;
 
     // Informational methods.
     virtual const keymaster_key_format_t* SupportedImportFormats(size_t* format_count) = 0;
@@ -80,11 +77,8 @@
     const AuthorizationSet& authorizations() const { return authorizations_; }
 
   protected:
-    Key(const KeyBlob& blob, const Logger& logger);
-    Key(const AuthorizationSet& authorizations, const Logger& logger)
-        : logger_(logger), authorizations_(authorizations) {}
-
-    const Logger& logger_;
+    Key(const KeyBlob& blob);
+    Key(const AuthorizationSet& authorizations) : authorizations_(authorizations) {}
 
   private:
     AuthorizationSet authorizations_;
diff --git a/operation.h b/operation.h
index 594adb4..0c3c0b5 100644
--- a/operation.h
+++ b/operation.h
@@ -52,8 +52,7 @@
     virtual KeyType registry_key() const = 0;
 
     // Factory methods
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error) = 0;
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error) = 0;
 
     // Informational methods.  The returned arrays reference static memory and must not be
     // deallocated or modified.
@@ -78,14 +77,11 @@
  */
 class Operation {
   public:
-    Operation(keymaster_purpose_t purpose, const Logger& logger)
-        : purpose_(purpose), logger_(logger) {}
+    Operation(keymaster_purpose_t purpose) : purpose_(purpose) {}
     virtual ~Operation() {}
 
     keymaster_purpose_t purpose() const { return purpose_; }
 
-    const Logger& logger() { return logger_; }
-
     virtual keymaster_error_t Begin(const AuthorizationSet& input_params,
                                     AuthorizationSet* output_params) = 0;
     virtual keymaster_error_t Update(const AuthorizationSet& additional_params, const Buffer& input,
@@ -96,7 +92,6 @@
 
   private:
     const keymaster_purpose_t purpose_;
-    const Logger& logger_;
 };
 
 }  // namespace keymaster
diff --git a/rsa_key.cpp b/rsa_key.cpp
index f060274..614dbe8 100644
--- a/rsa_key.cpp
+++ b/rsa_key.cpp
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-#include "openssl_utils.h"
 #include "rsa_key.h"
+
+#include "openssl_err.h"
+#include "openssl_utils.h"
 #include "rsa_operation.h"
 #include "unencrypted_key_blob.h"
 
@@ -33,20 +35,17 @@
 class RsaKeyFactory : public AsymmetricKeyFactory {
   public:
     virtual keymaster_algorithm_t registry_key() const { return KM_ALGORITHM_RSA; }
-    virtual Key* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
-                             keymaster_error_t* error);
+    virtual Key* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
     virtual Key* ImportKey(const AuthorizationSet& key_description,
                            keymaster_key_format_t key_format, const uint8_t* key_data,
-                           size_t key_data_length, const Logger& logger, keymaster_error_t* error);
-    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, const Logger& logger,
-                         keymaster_error_t* error) {
-        return new RsaKey(blob, logger, error);
+                           size_t key_data_length, keymaster_error_t* error);
+    virtual Key* LoadKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) {
+        return new RsaKey(blob, error);
     }
 };
 static KeyFactoryRegistry::Registration<RsaKeyFactory> registration;
 
-Key* RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
-                                keymaster_error_t* error) {
+Key* RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error) {
     if (!error)
         return NULL;
 
@@ -70,19 +69,18 @@
 
     if (!BN_set_word(exponent.get(), public_exponent) ||
         !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */)) {
-        *error = KM_ERROR_UNKNOWN_ERROR;
+        *error = TranslateLastOpenSslError();
         return NULL;
     }
 
-    RsaKey* new_key = new RsaKey(rsa_key.release(), authorizations, logger);
+    RsaKey* new_key = new RsaKey(rsa_key.release(), authorizations);
     *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return new_key;
 }
 
 Key* RsaKeyFactory::ImportKey(const AuthorizationSet& key_description,
                               keymaster_key_format_t key_format, const uint8_t* key_data,
-                              size_t key_data_length, const Logger& logger,
-                              keymaster_error_t* error) {
+                              size_t key_data_length, keymaster_error_t* error) {
     if (!error)
         return NULL;
 
@@ -94,7 +92,7 @@
 
     UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(EVP_PKEY_get1_RSA(pkey.get()));
     if (!rsa_key.get()) {
-        *error = KM_ERROR_UNKNOWN_ERROR;
+        *error = TranslateLastOpenSslError();
         return NULL;
     }
 
@@ -146,11 +144,10 @@
     // missing, the error will be diagnosed when the key is used (when auth checking is
     // implemented).
     *error = KM_ERROR_OK;
-    return new RsaKey(rsa_key.release(), authorizations, logger);
+    return new RsaKey(rsa_key.release(), authorizations);
 }
 
-RsaKey::RsaKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error)
-    : AsymmetricKey(blob, logger) {
+RsaKey::RsaKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) : AsymmetricKey(blob) {
     if (error)
         *error = LoadKey(blob);
 }
diff --git a/rsa_key.h b/rsa_key.h
index b218e89..1c22399 100644
--- a/rsa_key.h
+++ b/rsa_key.h
@@ -31,9 +31,8 @@
     friend class RsaKeyFactory;
     friend class RsaOperationFactory;
 
-    RsaKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error);
-    RsaKey(RSA* rsa_key, const AuthorizationSet& auths, const Logger& logger)
-        : AsymmetricKey(auths, logger), rsa_key_(rsa_key) {}
+    RsaKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error);
+    RsaKey(RSA* rsa_key, const AuthorizationSet& auths) : AsymmetricKey(auths), rsa_key_(rsa_key) {}
 
     virtual int evp_key_type() { return EVP_PKEY_RSA; }
     virtual bool InternalToEvp(EVP_PKEY* pkey) const;
diff --git a/rsa_operation.cpp b/rsa_operation.cpp
index a75d9ae..a25231b 100644
--- a/rsa_operation.cpp
+++ b/rsa_operation.cpp
@@ -20,6 +20,9 @@
 
 #include <openssl/err.h>
 
+#include <keymaster/logger.h>
+
+#include "openssl_err.h"
 #include "openssl_utils.h"
 #include "rsa_key.h"
 
@@ -98,8 +101,7 @@
  */
 class RsaDigestingOperationFactory : public RsaOperationFactory {
   public:
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error);
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
 
     virtual const keymaster_digest_t* SupportedDigests(size_t* digest_count) const {
         *digest_count = array_length(supported_digests);
@@ -112,12 +114,11 @@
     }
 
   private:
-    virtual Operation* InstantiateOperation(const Logger& logger, keymaster_digest_t digest,
-                                            keymaster_padding_t padding, RSA* key) = 0;
+    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                            RSA* key) = 0;
 };
 
-Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key, const Logger& logger,
-                                                         keymaster_error_t* error) {
+Operation* RsaDigestingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
     keymaster_padding_t padding;
     keymaster_digest_t digest;
     RSA* rsa;
@@ -125,7 +126,7 @@
         !GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
         return NULL;
 
-    Operation* op = InstantiateOperation(logger, digest, padding, rsa);
+    Operation* op = InstantiateOperation(digest, padding, rsa);
     if (!op)
         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return op;
@@ -140,8 +141,7 @@
  */
 class RsaCryptingOperationFactory : public RsaOperationFactory {
   public:
-    virtual Operation* CreateOperation(const Key& key, const Logger& logger,
-                                       keymaster_error_t* error);
+    virtual Operation* CreateOperation(const Key& key, keymaster_error_t* error);
 
     virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_mode_count) const {
         *padding_mode_count = array_length(supported_crypt_padding);
@@ -154,18 +154,16 @@
     }
 
   private:
-    virtual Operation* InstantiateOperation(const Logger& logger, keymaster_padding_t padding,
-                                            RSA* key) = 0;
+    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) = 0;
 };
 
-Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key, const Logger& logger,
-                                                        keymaster_error_t* error) {
+Operation* RsaCryptingOperationFactory::CreateOperation(const Key& key, keymaster_error_t* error) {
     keymaster_padding_t padding;
     RSA* rsa;
     if (!GetAndValidatePadding(key, &padding, error) || !(rsa = GetRsaKey(key, error)))
         return NULL;
 
-    Operation* op = InstantiateOperation(logger, padding, rsa);
+    Operation* op = InstantiateOperation(padding, rsa);
     if (!op)
         *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
     return op;
@@ -177,9 +175,9 @@
 class RsaSigningOperationFactory : public RsaDigestingOperationFactory {
   public:
     virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_SIGN; }
-    virtual Operation* InstantiateOperation(const Logger& logger, keymaster_digest_t digest,
-                                            keymaster_padding_t padding, RSA* key) {
-        return new RsaSignOperation(logger, digest, padding, key);
+    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                            RSA* key) {
+        return new RsaSignOperation(digest, padding, key);
     }
 };
 static OperationFactoryRegistry::Registration<RsaSigningOperationFactory> sign_registration;
@@ -189,9 +187,9 @@
  */
 class RsaVerificationOperationFactory : public RsaDigestingOperationFactory {
     virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_VERIFY; }
-    virtual Operation* InstantiateOperation(const Logger& logger, keymaster_digest_t digest,
-                                            keymaster_padding_t padding, RSA* key) {
-        return new RsaVerifyOperation(logger, digest, padding, key);
+    virtual Operation* InstantiateOperation(keymaster_digest_t digest, keymaster_padding_t padding,
+                                            RSA* key) {
+        return new RsaVerifyOperation(digest, padding, key);
     }
 };
 static OperationFactoryRegistry::Registration<RsaVerificationOperationFactory> verify_registration;
@@ -201,9 +199,8 @@
  */
 class RsaEncryptionOperationFactory : public RsaCryptingOperationFactory {
     virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
-    virtual Operation* InstantiateOperation(const Logger& logger, keymaster_padding_t padding,
-                                            RSA* key) {
-        return new RsaEncryptOperation(logger, padding, key);
+    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
+        return new RsaEncryptOperation(padding, key);
     }
 };
 static OperationFactoryRegistry::Registration<RsaEncryptionOperationFactory> encrypt_registration;
@@ -213,9 +210,8 @@
  */
 class RsaDecryptionOperationFactory : public RsaCryptingOperationFactory {
     virtual keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
-    virtual Operation* InstantiateOperation(const Logger& logger, keymaster_padding_t padding,
-                                            RSA* key) {
-        return new RsaDecryptOperation(logger, padding, key);
+    virtual Operation* InstantiateOperation(keymaster_padding_t padding, RSA* key) {
+        return new RsaDecryptOperation(padding, key);
     }
 };
 
@@ -315,21 +311,21 @@
     case KM_PAD_RSA_OAEP:
         openssl_padding = RSA_PKCS1_OAEP_PADDING;
         if (message_size >= RSA_size(rsa_key_) - OAEP_PADDING_OVERHEAD) {
-            logger().error("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
-                           data_.available_read(), RSA_size(rsa_key_));
+            LOG_E("Cannot encrypt %d bytes with %d-byte key and OAEP padding",
+                  data_.available_read(), RSA_size(rsa_key_));
             return KM_ERROR_INVALID_INPUT_LENGTH;
         }
         break;
     case KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
         openssl_padding = RSA_PKCS1_PADDING;
         if (message_size >= RSA_size(rsa_key_) - PKCS1_PADDING_OVERHEAD) {
-            logger().error("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
-                           data_.available_read(), RSA_size(rsa_key_));
+            LOG_E("Cannot encrypt %d bytes with %d-byte key and PKCS1 padding",
+                  data_.available_read(), RSA_size(rsa_key_));
             return KM_ERROR_INVALID_INPUT_LENGTH;
         }
         break;
     default:
-        logger().error("Padding mode %d not supported", padding_);
+        LOG_E("Padding mode %d not supported", padding_);
         return KM_ERROR_UNSUPPORTED_PADDING_MODE;
     }
 
@@ -338,7 +334,7 @@
                                              output->peek_write(), rsa_key_, openssl_padding);
 
     if (bytes_encrypted < 0) {
-        logger().error("Error %d encrypting data with RSA", ERR_get_error());
+        LOG_E("Error %d encrypting data with RSA", ERR_get_error());
         return KM_ERROR_UNKNOWN_ERROR;
     }
     assert(bytes_encrypted == RSA_size(rsa_key_));
@@ -359,7 +355,7 @@
         openssl_padding = RSA_PKCS1_PADDING;
         break;
     default:
-        logger().error("Padding mode %d not supported", padding_);
+        LOG_E("Padding mode %d not supported", padding_);
         return KM_ERROR_UNSUPPORTED_PADDING_MODE;
     }
 
@@ -368,7 +364,7 @@
                                               output->peek_write(), rsa_key_, openssl_padding);
 
     if (bytes_decrypted < 0) {
-        logger().error("Error %d decrypting data with RSA", ERR_get_error());
+        LOG_E("Error %d decrypting data with RSA", ERR_get_error());
         return KM_ERROR_UNKNOWN_ERROR;
     }
     output->advance_write(bytes_decrypted);
diff --git a/rsa_operation.h b/rsa_operation.h
index 2c9680f..99530f8 100644
--- a/rsa_operation.h
+++ b/rsa_operation.h
@@ -30,9 +30,8 @@
 
 class RsaOperation : public Operation {
   public:
-    RsaOperation(keymaster_purpose_t purpose, const Logger& logger, keymaster_padding_t padding,
-                 RSA* key)
-        : Operation(purpose, logger), rsa_key_(key), padding_(padding) {}
+    RsaOperation(keymaster_purpose_t purpose, keymaster_padding_t padding, RSA* key)
+        : Operation(purpose), rsa_key_(key), padding_(padding) {}
     ~RsaOperation();
 
     virtual keymaster_error_t Begin(const AuthorizationSet& /* input_params */,
@@ -53,9 +52,8 @@
 
 class RsaSignOperation : public RsaOperation {
   public:
-    RsaSignOperation(const Logger& logger, keymaster_digest_t digest, keymaster_padding_t padding,
-                     RSA* key)
-        : RsaOperation(KM_PURPOSE_SIGN, logger, padding, key), digest_(digest) {}
+    RsaSignOperation(keymaster_digest_t digest, keymaster_padding_t padding, RSA* key)
+        : RsaOperation(KM_PURPOSE_SIGN, padding, key), digest_(digest) {}
     virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
                                      const Buffer& signature, Buffer* output);
 
@@ -65,9 +63,8 @@
 
 class RsaVerifyOperation : public RsaOperation {
   public:
-    RsaVerifyOperation(const Logger& logger, keymaster_digest_t digest, keymaster_padding_t padding,
-                       RSA* key)
-        : RsaOperation(KM_PURPOSE_VERIFY, logger, padding, key), digest_(digest) {}
+    RsaVerifyOperation(keymaster_digest_t digest, keymaster_padding_t padding, RSA* key)
+        : RsaOperation(KM_PURPOSE_VERIFY, padding, key), digest_(digest) {}
     virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
                                      const Buffer& signature, Buffer* output);
 
@@ -77,16 +74,16 @@
 
 class RsaEncryptOperation : public RsaOperation {
   public:
-    RsaEncryptOperation(const Logger& logger, keymaster_padding_t padding, RSA* key)
-        : RsaOperation(KM_PURPOSE_ENCRYPT, logger, padding, key) {}
+    RsaEncryptOperation(keymaster_padding_t padding, RSA* key)
+        : RsaOperation(KM_PURPOSE_ENCRYPT, padding, key) {}
     virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
                                      const Buffer& signature, Buffer* output);
 };
 
 class RsaDecryptOperation : public RsaOperation {
   public:
-    RsaDecryptOperation(const Logger& logger, keymaster_padding_t padding, RSA* key)
-        : RsaOperation(KM_PURPOSE_DECRYPT, logger, padding, key) {}
+    RsaDecryptOperation(keymaster_padding_t padding, RSA* key)
+        : RsaOperation(KM_PURPOSE_DECRYPT, padding, key) {}
     virtual keymaster_error_t Finish(const AuthorizationSet& additional_params,
                                      const Buffer& signature, Buffer* output);
 };
diff --git a/soft_keymaster_device.cpp b/soft_keymaster_device.cpp
index 0f4eda4..0724765 100644
--- a/soft_keymaster_device.cpp
+++ b/soft_keymaster_device.cpp
@@ -58,8 +58,7 @@
 
 namespace keymaster {
 
-SoftKeymasterDevice::SoftKeymasterDevice(Logger* logger)
-    : impl_(new GoogleSoftKeymaster(16, logger)) {
+SoftKeymasterDevice::SoftKeymasterDevice() : impl_(new GoogleSoftKeymaster(16)) {
 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
     static_assert(std::is_standard_layout<SoftKeymasterDevice>::value,
                   "SoftKeymasterDevice must be standard layout");
@@ -71,8 +70,8 @@
     assert(reinterpret_cast<keymaster_device*>(this) == &device_);
     assert(reinterpret_cast<hw_device_t*>(this) == &(device_.common));
 #endif
-    logger->info("Creating device");
-    logger->debug("Device address: %p", this);
+    LOG_I("Creating device");
+    LOG_D("Device address: %p", this);
 
     memset(&device_, 0, sizeof(device_));
 
@@ -159,7 +158,7 @@
                                           const keymaster_keypair_t key_type,
                                           const void* key_params, uint8_t** key_blob,
                                           size_t* key_blob_length) {
-    convert_device(dev)->impl_->logger().debug("Device received generate_keypair");
+    LOG_D("%s", "Device received generate_keypair");
 
     GenerateKeyRequest req;
     StoreDefaultNewKeyParams(&req.key_description);
@@ -169,9 +168,8 @@
         req.key_description.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
         const keymaster_rsa_keygen_params_t* rsa_params =
             static_cast<const keymaster_rsa_keygen_params_t*>(key_params);
-        convert_device(dev)->impl_->logger().debug(
-            "Generating RSA pair, modulus size: %u, public exponent: %lu", rsa_params->modulus_size,
-            rsa_params->public_exponent);
+        LOG_D("Generating RSA pair, modulus size: %u, public exponent: %lu",
+              rsa_params->modulus_size, rsa_params->public_exponent);
         req.key_description.push_back(TAG_KEY_SIZE, rsa_params->modulus_size);
         req.key_description.push_back(TAG_RSA_PUBLIC_EXPONENT, rsa_params->public_exponent);
         break;
@@ -181,35 +179,31 @@
         req.key_description.push_back(TAG_ALGORITHM, KM_ALGORITHM_ECDSA);
         const keymaster_ec_keygen_params_t* ec_params =
             static_cast<const keymaster_ec_keygen_params_t*>(key_params);
-        convert_device(dev)->impl_->logger().debug("Generating ECDSA pair, key size: %u",
-                                                   ec_params->field_size);
+        LOG_D("Generating ECDSA pair, key size: %u", ec_params->field_size);
         req.key_description.push_back(TAG_KEY_SIZE, ec_params->field_size);
         break;
     }
 
     default:
-        convert_device(dev)->impl_->logger().debug("Received request for unsuported key type %d",
-                                                   key_type);
+        LOG_D("Received request for unsuported key type %d", key_type);
         return KM_ERROR_UNSUPPORTED_ALGORITHM;
     }
 
     GenerateKeyResponse rsp;
     convert_device(dev)->impl_->GenerateKey(req, &rsp);
     if (rsp.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("Key generation failed with error: %d",
-                                                   rsp.error);
+        LOG_E("Key generation failed with error: %d", rsp.error);
         return rsp.error;
     }
 
     *key_blob_length = rsp.key_blob.key_material_size;
     *key_blob = static_cast<uint8_t*>(malloc(*key_blob_length));
     if (!*key_blob) {
-        convert_device(dev)->impl_->logger().error("Failed to allocate %d bytes", *key_blob_length);
+        LOG_E("Failed to allocate %d bytes", *key_blob_length);
         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     }
     memcpy(*key_blob, rsp.key_blob.key_material, *key_blob_length);
-    convert_device(dev)->impl_->logger().debug("Returning %d bytes in key blob\n",
-                                               (int)*key_blob_length);
+    LOG_D("Returning %d bytes in key blob\n", (int)*key_blob_length);
 
     return KM_ERROR_OK;
 }
@@ -218,7 +212,7 @@
 int SoftKeymasterDevice::import_keypair(const keymaster1_device_t* dev, const uint8_t* key,
                                         const size_t key_length, uint8_t** key_blob,
                                         size_t* key_blob_length) {
-    convert_device(dev)->impl_->logger().debug("Device received import_keypair");
+    LOG_D("Device received import_keypair");
 
     ImportKeyRequest request;
     StoreDefaultNewKeyParams(&request.key_description);
@@ -228,20 +222,18 @@
     ImportKeyResponse response;
     convert_device(dev)->impl_->ImportKey(request, &response);
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("Key import failed with error: %d",
-                                                   response.error);
+        LOG_E("Key import failed with error: %d", response.error);
         return response.error;
     }
 
     *key_blob_length = response.key_blob.key_material_size;
     *key_blob = static_cast<uint8_t*>(malloc(*key_blob_length));
     if (!*key_blob) {
-        convert_device(dev)->impl_->logger().error("Failed to allocate %d bytes", *key_blob_length);
+        LOG_E("Failed to allocate %d bytes", *key_blob_length);
         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     }
     memcpy(*key_blob, response.key_blob.key_material, *key_blob_length);
-    convert_device(dev)->impl_->logger().debug("Returning %d bytes in key blob\n",
-                                               (int)*key_blob_length);
+    LOG_D("Returning %d bytes in key blob\n", (int)*key_blob_length);
 
     return KM_ERROR_OK;
 }
@@ -250,7 +242,7 @@
 int SoftKeymasterDevice::get_keypair_public(const struct keymaster1_device* dev,
                                             const uint8_t* key_blob, const size_t key_blob_length,
                                             uint8_t** x509_data, size_t* x509_data_length) {
-    convert_device(dev)->impl_->logger().debug("Device received get_keypair_public");
+    LOG_D("Device received get_keypair_public");
 
     ExportKeyRequest req;
     req.SetKeyMaterial(key_blob, key_blob_length);
@@ -259,8 +251,7 @@
     ExportKeyResponse rsp;
     convert_device(dev)->impl_->ExportKey(req, &rsp);
     if (rsp.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_keypair_public failed with error: %d",
-                                                   rsp.error);
+        LOG_E("get_keypair_public failed with error: %d", rsp.error);
         return rsp.error;
     }
 
@@ -269,8 +260,7 @@
     if (!*x509_data)
         return KM_ERROR_MEMORY_ALLOCATION_FAILED;
     memcpy(*x509_data, rsp.key_data, *x509_data_length);
-    convert_device(dev)->impl_->logger().debug("Returning %d bytes in x509 key\n",
-                                               (int)*x509_data_length);
+    LOG_D("Returning %d bytes in x509 key\n", (int)*x509_data_length);
 
     return KM_ERROR_OK;
 }
@@ -280,7 +270,7 @@
                                    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) {
-    convert_device(dev)->impl_->logger().debug("Device received sign_data");
+    LOG_D("Device received sign_data");
 
     *signed_data_length = 0;
 
@@ -295,8 +285,7 @@
     BeginOperationResponse begin_response;
     convert_device(dev)->impl_->BeginOperation(begin_request, &begin_response);
     if (begin_response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error(
-            "sign_data begin operation failed with error: %d", begin_response.error);
+        LOG_E("sign_data begin operation failed with error: %d", begin_response.error);
         return begin_response.error;
     }
 
@@ -306,8 +295,7 @@
     UpdateOperationResponse update_response;
     convert_device(dev)->impl_->UpdateOperation(update_request, &update_response);
     if (update_response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error(
-            "sign_data update operation failed with error: %d", update_response.error);
+        LOG_E("sign_data update operation failed with error: %d", update_response.error);
         return update_response.error;
     }
 
@@ -316,8 +304,7 @@
     FinishOperationResponse finish_response;
     convert_device(dev)->impl_->FinishOperation(finish_request, &finish_response);
     if (finish_response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error(
-            "sign_data finish operation failed with error: %d", finish_response.error);
+        LOG_E("sign_data finish operation failed with error: %d", finish_response.error);
         return finish_response.error;
     }
 
@@ -335,7 +322,7 @@
                                      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) {
-    convert_device(dev)->impl_->logger().debug("Device received verify_data");
+    LOG_D("Device received verify_data");
 
     BeginOperationRequest begin_request;
     begin_request.purpose = KM_PURPOSE_VERIFY;
@@ -350,8 +337,7 @@
     BeginOperationResponse begin_response;
     convert_device(dev)->impl_->BeginOperation(begin_request, &begin_response);
     if (begin_response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error(
-            "verify_data begin operation failed with error: %d", begin_response.error);
+        LOG_E("verify_data begin operation failed with error: %d", begin_response.error);
         return begin_response.error;
     }
 
@@ -361,8 +347,7 @@
     UpdateOperationResponse update_response;
     convert_device(dev)->impl_->UpdateOperation(update_request, &update_response);
     if (update_response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error(
-            "verify_data update operation failed with error: %d", update_response.error);
+        LOG_E("verify_data update operation failed with error: %d", update_response.error);
         return update_response.error;
     }
 
@@ -372,8 +357,7 @@
     FinishOperationResponse finish_response;
     convert_device(dev)->impl_->FinishOperation(finish_request, &finish_response);
     if (finish_response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error(
-            "verify_data finish operation failed with error: %d", finish_response.error);
+        LOG_E("verify_data finish operation failed with error: %d", finish_response.error);
         return finish_response.error;
     }
     return KM_ERROR_OK;
@@ -389,8 +373,7 @@
     SupportedResponse<keymaster_algorithm_t> response;
     convert_device(dev)->impl_->SupportedAlgorithms(&response);
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_supported_algorithms failed with %d",
-                                                   response.error);
+        LOG_E("get_supported_algorithms failed with %d", response.error);
 
         return response.error;
     }
@@ -417,8 +400,7 @@
     convert_device(dev)->impl_->SupportedBlockModes(algorithm, purpose, &response);
 
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_supported_block_modes failed with %d",
-                                                   response.error);
+        LOG_E("get_supported_block_modes failed with %d", response.error);
 
         return response.error;
     }
@@ -444,8 +426,7 @@
     convert_device(dev)->impl_->SupportedPaddingModes(algorithm, purpose, &response);
 
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_supported_padding_modes failed with %d",
-                                                   response.error);
+        LOG_E("get_supported_padding_modes failed with %d", response.error);
         return response.error;
     }
 
@@ -470,8 +451,7 @@
     convert_device(dev)->impl_->SupportedDigests(algorithm, purpose, &response);
 
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_supported_digests failed with %d",
-                                                   response.error);
+        LOG_E("get_supported_digests failed with %d", response.error);
         return response.error;
     }
 
@@ -494,8 +474,7 @@
     convert_device(dev)->impl_->SupportedImportFormats(algorithm, &response);
 
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_supported_import_formats failed with %d",
-                                                   response.error);
+        LOG_E("get_supported_import_formats failed with %d", response.error);
         return response.error;
     }
 
@@ -519,8 +498,7 @@
     convert_device(dev)->impl_->SupportedExportFormats(algorithm, &response);
 
     if (response.error != KM_ERROR_OK) {
-        convert_device(dev)->impl_->logger().error("get_supported_export_formats failed with %d",
-                                                   response.error);
+        LOG_E("get_supported_export_formats failed with %d", response.error);
         return response.error;
     }
 
diff --git a/symmetric_key.cpp b/symmetric_key.cpp
index a850076..fc8472f 100644
--- a/symmetric_key.cpp
+++ b/symmetric_key.cpp
@@ -21,19 +21,22 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 
+#include <keymaster/logger.h>
+
 #include "aes_key.h"
 #include "hmac_key.h"
+#include "openssl_err.h"
 #include "unencrypted_key_blob.h"
 
 namespace keymaster {
 
-Key* SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
+Key* SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description,
                                       keymaster_error_t* error) {
     if (!error)
         return NULL;
     *error = KM_ERROR_OK;
 
-    UniquePtr<SymmetricKey> key(CreateKey(key_description, logger));
+    UniquePtr<SymmetricKey> key(CreateKey(key_description));
 
     uint32_t key_size_bits;
     if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size_bits) || key_size_bits % 8 != 0) {
@@ -47,8 +50,8 @@
         return NULL;
     }
     if (!RAND_bytes(key->key_data_, key->key_data_size_)) {
-        logger.error("Error %ul generating %d bit AES key", ERR_get_error(), key_size_bits);
-        *error = KM_ERROR_UNKNOWN_ERROR;
+        LOG_E("Error %ul generating %d bit AES key", ERR_get_error(), key_size_bits);
+        *error = TranslateLastOpenSslError();
         return NULL;
     }
 
@@ -57,9 +60,8 @@
     return key.release();
 }
 
-SymmetricKey::SymmetricKey(const UnencryptedKeyBlob& blob, const Logger& logger,
-                           keymaster_error_t* error)
-    : Key(blob, logger), key_data_size_(blob.unencrypted_key_material_length()) {
+SymmetricKey::SymmetricKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error)
+    : Key(blob), key_data_size_(blob.unencrypted_key_material_length()) {
     memcpy(key_data_, blob.unencrypted_key_material(), key_data_size_);
     if (error)
         *error = KM_ERROR_OK;
diff --git a/symmetric_key.h b/symmetric_key.h
index 48895d8..74ca4bd 100644
--- a/symmetric_key.h
+++ b/symmetric_key.h
@@ -24,10 +24,9 @@
 class SymmetricKey;
 
 class SymmetricKeyFactory : public KeyFactory {
-    virtual Key* GenerateKey(const AuthorizationSet& key_description, const Logger& logger,
-                             keymaster_error_t* error);
+    virtual Key* GenerateKey(const AuthorizationSet& key_description, keymaster_error_t* error);
     virtual Key* ImportKey(const AuthorizationSet&, keymaster_key_format_t, const uint8_t*, size_t,
-                           const Logger&, keymaster_error_t* error) {
+                           keymaster_error_t* error) {
         *error = KM_ERROR_UNIMPLEMENTED;
         return NULL;
     }
@@ -40,7 +39,7 @@
     };
 
   private:
-    virtual SymmetricKey* CreateKey(const AuthorizationSet& auths, const Logger& logger) = 0;
+    virtual SymmetricKey* CreateKey(const AuthorizationSet& auths) = 0;
     const keymaster_key_format_t* NoFormats(size_t* format_count) {
         *format_count = 0;
         return NULL;
@@ -65,8 +64,8 @@
     size_t key_data_size() const { return key_data_size_; }
 
   protected:
-    SymmetricKey(const UnencryptedKeyBlob& blob, const Logger& logger, keymaster_error_t* error);
-    SymmetricKey(const AuthorizationSet& auths, const Logger& logger) : Key(auths, logger) {}
+    SymmetricKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error);
+    SymmetricKey(const AuthorizationSet& auths) : Key(auths) {}
 
   private:
     friend SymmetricKeyFactory;
diff --git a/unencrypted_key_blob.cpp b/unencrypted_key_blob.cpp
index 129d2cf..a153eca 100644
--- a/unencrypted_key_blob.cpp
+++ b/unencrypted_key_blob.cpp
@@ -24,6 +24,7 @@
 #include "ae.h"
 #include "unencrypted_key_blob.h"
 #include "ocb_utils.h"
+#include "openssl_err.h"
 
 namespace keymaster {
 
@@ -155,7 +156,7 @@
     AES_KEY aes_key;
     Eraser aes_key_eraser(AES_KEY);
     if (AES_set_encrypt_key(master_key, master_key_length * 8, &aes_key) != 0) {
-        error_ = KM_ERROR_UNKNOWN_ERROR;
+        error_ = TranslateLastOpenSslError();
         return NULL;
     }
     AES_encrypt(hash_buf.get(), derived_key.get(), &aes_key);