Refactor AndroidKeymaster so all methods use message objects.

Methods with simple argument or return types eschewed message objects,
but this complicates the TrustyKeymaster implementation by requiring it
to build its own system for marshalling and unmarshalling.

Bug: 14674558
Change-Id: I5a88523c9d1a76c8629ff6f93040ceb3c2a9426b
diff --git a/android_keymaster.cpp b/android_keymaster.cpp
index 57b02ac..68cd39a 100644
--- a/android_keymaster.cpp
+++ b/android_keymaster.cpp
@@ -80,8 +80,8 @@
     rsp->error = KM_ERROR_OK;
 }
 
-void AndroidKeymaster::SupportedAlgorithms(
-    SupportedResponse<keymaster_algorithm_t>* response) const {
+void AndroidKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& /* request */,
+                                           SupportedAlgorithmsResponse* response) {
     if (response == NULL)
         return;
 
@@ -116,49 +116,50 @@
     response->SetResults(supported, count);
 }
 
-void AndroidKeymaster::SupportedBlockModes(
-    keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
-    SupportedResponse<keymaster_block_mode_t>* response) const {
-    GetSupported(*context_, algorithm, purpose, &OperationFactory::SupportedBlockModes, response);
+void AndroidKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
+                                           SupportedBlockModesResponse* response) {
+    GetSupported(*context_, request.algorithm, request.purpose,
+                 &OperationFactory::SupportedBlockModes, response);
 }
 
-void AndroidKeymaster::SupportedPaddingModes(
-    keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
-    SupportedResponse<keymaster_padding_t>* response) const {
-    GetSupported(*context_, algorithm, purpose, &OperationFactory::SupportedPaddingModes, response);
+void AndroidKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
+                                             SupportedPaddingModesResponse* response) {
+    GetSupported(*context_, request.algorithm, request.purpose,
+                 &OperationFactory::SupportedPaddingModes, response);
 }
 
-void AndroidKeymaster::SupportedDigests(keymaster_algorithm_t algorithm,
-                                        keymaster_purpose_t purpose,
-                                        SupportedResponse<keymaster_digest_t>* response) const {
-    GetSupported(*context_, algorithm, purpose, &OperationFactory::SupportedDigests, response);
+void AndroidKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
+                                        SupportedDigestsResponse* response) {
+    GetSupported(*context_, request.algorithm, request.purpose, &OperationFactory::SupportedDigests,
+                 response);
 }
 
-void AndroidKeymaster::SupportedImportFormats(
-    keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
-    if (response == NULL || !check_supported(*context_, algorithm, 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(algorithm)->SupportedImportFormats(&count);
+        context_->GetKeyFactory(request.algorithm)->SupportedImportFormats(&count);
     response->SetResults(formats, count);
 }
 
-void AndroidKeymaster::SupportedExportFormats(
-    keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const {
-    if (response == NULL || !check_supported(*context_, algorithm, response))
+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(algorithm)->SupportedExportFormats(&count);
+        context_->GetKeyFactory(request.algorithm)->SupportedExportFormats(&count);
     response->SetResults(formats, count);
 }
 
-keymaster_error_t AndroidKeymaster::AddRngEntropy(const AddEntropyRequest& request) {
-    return context_->AddRngEntropy(request.random_data.peek_read(),
-                                   request.random_data.available_read());
+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,
@@ -284,16 +285,19 @@
     operation_table_->Delete(request.op_handle);
 }
 
-keymaster_error_t AndroidKeymaster::AbortOperation(const keymaster_operation_handle_t op_handle) {
-    Operation* operation = operation_table_->Find(op_handle);
-    if (operation == NULL)
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+void AndroidKeymaster::AbortOperation(const AbortOperationRequest& request,
+                                      AbortOperationResponse* response) {
+    if (!response)
+        return;
 
-    keymaster_error_t error = operation->Abort();
-    operation_table_->Delete(op_handle);
-    if (error != KM_ERROR_OK)
-        return error;
-    return KM_ERROR_OK;
+    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) {
@@ -350,12 +354,16 @@
     }
 }
 
-keymaster_error_t AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request) {
-    return context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
+void AndroidKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
+    if (!response)
+        return;
+    response->error = context_->DeleteKey(KeymasterKeyBlob(request.key_blob));
 }
 
-keymaster_error_t AndroidKeymaster::DeleteAllKeys() {
-    return context_->DeleteAllKeys();
+void AndroidKeymaster::DeleteAllKeys(const DeleteAllKeysRequest&, DeleteAllKeysResponse* response) {
+    if (!response)
+        return;
+    response->error = context_->DeleteAllKeys();
 }
 
 keymaster_error_t AndroidKeymaster::LoadKey(const keymaster_key_blob_t& key_blob,
diff --git a/android_keymaster_messages.cpp b/android_keymaster_messages.cpp
index 709b8dc..bedb058 100644
--- a/android_keymaster_messages.cpp
+++ b/android_keymaster_messages.cpp
@@ -72,24 +72,6 @@
     return NonErrorDeserialize(buf_ptr, end);
 }
 
-size_t SupportedAlgorithmsResponse::NonErrorSerializedSize() const {
-    return sizeof(uint32_t) + sizeof(uint32_t) * algorithms_length;
-}
-
-uint8_t* SupportedAlgorithmsResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const {
-    return append_uint32_array_to_buf(buf, end, algorithms, algorithms_length);
-}
-
-bool SupportedAlgorithmsResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
-    delete[] algorithms;
-    algorithms = NULL;
-    UniquePtr<keymaster_algorithm_t[]> deserialized_algorithms;
-    if (!copy_uint32_array_from_buf(buf_ptr, end, &deserialized_algorithms, &algorithms_length))
-        return false;
-    algorithms = deserialized_algorithms.release();
-    return true;
-}
-
 GenerateKeyResponse::~GenerateKeyResponse() {
     delete[] key_blob.key_material;
 }
diff --git a/android_keymaster_messages_test.cpp b/android_keymaster_messages_test.cpp
index 012d4b3..5f53b87 100644
--- a/android_keymaster_messages_test.cpp
+++ b/android_keymaster_messages_test.cpp
@@ -81,17 +81,25 @@
     }
 }
 
-TEST(RoundTrip, SupportedAlgorithmsResponse) {
+TEST(RoundTrip, SupportedByAlgorithmRequest) {
     for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) {
-        SupportedAlgorithmsResponse rsp(ver);
-        keymaster_algorithm_t algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC};
-        rsp.error = KM_ERROR_OK;
-        rsp.algorithms = dup_array(algorithms);
-        rsp.algorithms_length = array_length(algorithms);
+        SupportedByAlgorithmRequest req(ver);
+        req.algorithm = KM_ALGORITHM_EC;
 
-        UniquePtr<SupportedAlgorithmsResponse> deserialized(round_trip(ver, rsp, 16));
-        EXPECT_EQ(array_length(algorithms), deserialized->algorithms_length);
-        EXPECT_EQ(0, memcmp(deserialized->algorithms, algorithms, array_size(algorithms)));
+        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);
     }
 }
 
@@ -434,6 +442,27 @@
     }
 }
 
+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;
 
@@ -482,6 +511,27 @@
     }
 }
 
+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));
+    }
+}
+
 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,
@@ -530,23 +580,30 @@
 #define GARBAGE_TEST(Message)                                                                      \
     TEST(GarbageTest, Message) { parse_garbage<Message>(); }
 
-GARBAGE_TEST(SupportedAlgorithmsResponse)
+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(BeginOperationRequest);
-GARBAGE_TEST(BeginOperationResponse);
-GARBAGE_TEST(UpdateOperationRequest);
-GARBAGE_TEST(UpdateOperationResponse);
-GARBAGE_TEST(FinishOperationRequest);
-GARBAGE_TEST(FinishOperationResponse);
-GARBAGE_TEST(AddEntropyRequest);
 GARBAGE_TEST(ImportKeyRequest);
 GARBAGE_TEST(ImportKeyResponse);
-GARBAGE_TEST(ExportKeyRequest);
-GARBAGE_TEST(ExportKeyResponse);
-GARBAGE_TEST(DeleteKeyRequest);
+GARBAGE_TEST(SupportedByAlgorithmAndPurposeRequest)
+GARBAGE_TEST(SupportedByAlgorithmRequest)
+GARBAGE_TEST(UpdateOperationRequest);
+GARBAGE_TEST(UpdateOperationResponse);
 
 // The macro doesn't work on this one.
 TEST(GarbageTest, SupportedResponse) {
diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h
index c9de8ee..e85ba25 100644
--- a/include/keymaster/android_keymaster.h
+++ b/include/keymaster/android_keymaster.h
@@ -50,30 +50,31 @@
     AndroidKeymaster(KeymasterContext* context, size_t operation_table_size);
     virtual ~AndroidKeymaster();
 
-    void SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const;
-    void SupportedBlockModes(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
-                             SupportedResponse<keymaster_block_mode_t>* response) const;
-    void SupportedPaddingModes(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
-                               SupportedResponse<keymaster_padding_t>* response) const;
-    void SupportedDigests(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose,
-                          SupportedResponse<keymaster_digest_t>* response) const;
-    void SupportedImportFormats(keymaster_algorithm_t algorithm,
-                                SupportedResponse<keymaster_key_format_t>* response) const;
-    void SupportedExportFormats(keymaster_algorithm_t algorithm,
-                                SupportedResponse<keymaster_key_format_t>* response) const;
+    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);
 
-    keymaster_error_t AddRngEntropy(const AddEntropyRequest& request);
+    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);
-    keymaster_error_t DeleteKey(const DeleteKeyRequest& request);
-    keymaster_error_t DeleteAllKeys();
+    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);
-    keymaster_error_t AbortOperation(const keymaster_operation_handle_t op_handle);
+    void AbortOperation(const AbortOperationRequest& request, AbortOperationResponse* response);
     void GetVersion(const GetVersionRequest& request, GetVersionResponse* response);
 
   private:
diff --git a/include/keymaster/android_keymaster_messages.h b/include/keymaster/android_keymaster_messages.h
index a28a95a..7fc300b 100644
--- a/include/keymaster/android_keymaster_messages.h
+++ b/include/keymaster/android_keymaster_messages.h
@@ -27,15 +27,24 @@
 namespace keymaster {
 
 // Commands
-const uint32_t GENERATE_KEY = 0;
-const uint32_t BEGIN_OPERATION = 1;
-const uint32_t UPDATE_OPERATION = 2;
-const uint32_t FINISH_OPERATION = 3;
-const uint32_t ABORT_OPERATION = 4;
-const uint32_t IMPORT_KEY = 5;
-const uint32_t EXPORT_KEY = 6;
-const uint32_t GET_VERSION = 7;
-const uint32_t ADD_RNG_ENTROPY = 8;
+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,
+};
 
 /**
  * Keymaster message versions are tied to keymaster versions.  We map the keymaster
@@ -89,11 +98,12 @@
  * structure, but in this case it's the cleanest option.
  */
 struct KeymasterResponse : public KeymasterMessage {
-    KeymasterResponse(int32_t ver) : KeymasterMessage(ver), error(KM_ERROR_UNKNOWN_ERROR) {}
+    explicit KeymasterResponse(int32_t ver)
+        : KeymasterMessage(ver), error(KM_ERROR_UNKNOWN_ERROR) {}
 
-    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);
+    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;
@@ -102,21 +112,59 @@
     keymaster_error_t error;
 };
 
-struct SupportedAlgorithmsResponse : public KeymasterResponse {
-    SupportedAlgorithmsResponse(int32_t ver = MAX_MESSAGE_VERSION)
-        : KeymasterResponse(ver), algorithms(NULL), algorithms_length(0) {}
-    ~SupportedAlgorithmsResponse() { delete[] algorithms; }
+struct SupportedAlgorithmsRequest : public KeymasterMessage {
+    explicit SupportedAlgorithmsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver) {}
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
-
-    keymaster_algorithm_t* algorithms;
-    size_t algorithms_length;
+    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;
+};
+
+class SupportedImportFormatsRequest : public SupportedByAlgorithmRequest {};
+class SupportedExportFormatsRequest : public SupportedByAlgorithmRequest {};
+
+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;
+};
+
+class SupportedBlockModesRequest : public SupportedByAlgorithmAndPurposeRequest {};
+class SupportedPaddingModesRequest : public SupportedByAlgorithmAndPurposeRequest {};
+class SupportedDigestsRequest : public SupportedByAlgorithmAndPurposeRequest {};
+
 template <typename T> struct SupportedResponse : public KeymasterResponse {
-    SupportedResponse(int32_t ver = MAX_MESSAGE_VERSION)
+    explicit SupportedResponse(int32_t ver = MAX_MESSAGE_VERSION)
         : KeymasterResponse(ver), results(NULL), results_length(0) {}
     ~SupportedResponse() { delete[] results; }
 
@@ -134,13 +182,13 @@
         }
     }
 
-    size_t NonErrorSerializedSize() const {
+    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 {
+    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) {
+    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
         delete[] results;
         results = NULL;
         UniquePtr<T[]> tmp;
@@ -154,14 +202,21 @@
     size_t results_length;
 };
 
-struct GenerateKeyRequest : public KeymasterMessage {
-    GenerateKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+class SupportedAlgorithmsResponse : public SupportedResponse<keymaster_algorithm_t> {};
+class SupportedBlockModesResponse : public SupportedResponse<keymaster_block_mode_t> {};
+class SupportedPaddingModesResponse : public SupportedResponse<keymaster_padding_t> {};
+class SupportedDigestsResponse : public SupportedResponse<keymaster_digest_t> {};
+class SupportedImportFormatsResponse : public SupportedResponse<keymaster_key_format_t> {};
+class SupportedExportFormatsResponse : public SupportedResponse<keymaster_key_format_t> {};
 
-    size_t SerializedSize() const { return key_description.SerializedSize(); }
-    uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const {
+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) {
+    bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override {
         return key_description.Deserialize(buf_ptr, end);
     }
 
@@ -169,15 +224,15 @@
 };
 
 struct GenerateKeyResponse : public KeymasterResponse {
-    GenerateKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
+    explicit GenerateKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
         key_blob.key_material = NULL;
         key_blob.key_material_size = 0;
     }
     ~GenerateKeyResponse();
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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;
@@ -185,7 +240,8 @@
 };
 
 struct GetKeyCharacteristicsRequest : public KeymasterMessage {
-    GetKeyCharacteristicsRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+    explicit GetKeyCharacteristicsRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver) {
         key_blob.key_material = NULL;
         key_blob.key_material_size = 0;
     }
@@ -196,26 +252,27 @@
         SetKeyMaterial(blob.key_material, blob.key_material_size);
     }
 
-    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);
+    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 {
-    GetKeyCharacteristicsResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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 {
-    BeginOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+    explicit BeginOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
         key_blob.key_material = NULL;
         key_blob.key_material_size = 0;
     }
@@ -227,8 +284,8 @@
     }
 
     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);
+    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;
@@ -236,22 +293,22 @@
 };
 
 struct BeginOperationResponse : public KeymasterResponse {
-    BeginOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+    explicit BeginOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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 {
-    UpdateOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+    explicit UpdateOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
 
-    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);
+    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;
@@ -259,12 +316,12 @@
 };
 
 struct UpdateOperationResponse : public KeymasterResponse {
-    UpdateOperationResponse(int32_t ver = MAX_MESSAGE_VERSION)
+    explicit UpdateOperationResponse(int32_t ver = MAX_MESSAGE_VERSION)
         : KeymasterResponse(ver), input_consumed(0) {}
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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;
@@ -272,11 +329,11 @@
 };
 
 struct FinishOperationRequest : public KeymasterMessage {
-    FinishOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+    explicit FinishOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
 
-    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);
+    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 signature;
@@ -284,28 +341,63 @@
 };
 
 struct FinishOperationResponse : public KeymasterResponse {
-    FinishOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
+    explicit FinishOperationResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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 AddEntropyRequest : public KeymasterMessage {
-    AddEntropyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
+struct AbortOperationRequest : public KeymasterMessage {
+    explicit AbortOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {}
 
-    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);
+    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 {
-    ImportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver), key_data(NULL) {}
+    explicit ImportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterMessage(ver), key_data(NULL) {}
     ~ImportKeyRequest() { delete[] key_data; }
 
     void SetKeyMaterial(const void* key_material, size_t length);
@@ -313,9 +405,9 @@
         SetKeyMaterial(blob.key_material, blob.key_material_size);
     }
 
-    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);
+    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;
@@ -324,7 +416,7 @@
 };
 
 struct ImportKeyResponse : public KeymasterResponse {
-    ImportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
+    explicit ImportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {
         key_blob.key_material = NULL;
         key_blob.key_material_size = 0;
     }
@@ -335,9 +427,9 @@
         SetKeyMaterial(blob.key_material, blob.key_material_size);
     }
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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;
@@ -345,7 +437,7 @@
 };
 
 struct ExportKeyRequest : public KeymasterMessage {
-    ExportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+    explicit ExportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
         key_blob.key_material = NULL;
         key_blob.key_material_size = 0;
     }
@@ -356,9 +448,9 @@
         SetKeyMaterial(blob.key_material, blob.key_material_size);
     }
 
-    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);
+    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;
@@ -366,7 +458,8 @@
 };
 
 struct ExportKeyResponse : public KeymasterResponse {
-    ExportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver), key_data(NULL) {}
+    explicit ExportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION)
+        : KeymasterResponse(ver), key_data(NULL) {}
     ~ExportKeyResponse() { delete[] key_data; }
 
     void SetKeyMaterial(const void* key_material, size_t length);
@@ -374,16 +467,16 @@
         SetKeyMaterial(blob.key_material, blob.key_material_size);
     }
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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 {
-    DeleteKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
+    explicit DeleteKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) {
         key_blob.key_material = nullptr;
         key_blob.key_material_size = 0;
     }
@@ -394,28 +487,52 @@
         SetKeyMaterial(blob.key_material, blob.key_material_size);
     }
 
-    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);
+    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 GetVersionRequest : public KeymasterMessage {
-    GetVersionRequest() : KeymasterMessage(0 /* not versionable */) {}
+struct DeleteKeyResponse : public KeymasterResponse {
+    explicit DeleteKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) {}
 
-    size_t SerializedSize() const { return 0; }
-    uint8_t* Serialize(uint8_t* buf, const uint8_t*) const { return buf; }
-    bool Deserialize(const uint8_t**, const uint8_t*) { return true; };
+    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 {
+    explicit 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()
+    explicit GetVersionResponse()
         : KeymasterResponse(0 /* not versionable */), major_ver(0), minor_ver(0), subminor_ver(0) {}
 
-    size_t NonErrorSerializedSize() const;
-    uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const;
-    bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end);
+    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;
diff --git a/integrity_assured_key_blob.cpp b/integrity_assured_key_blob.cpp
index 1376cff..9ae349d 100644
--- a/integrity_assured_key_blob.cpp
+++ b/integrity_assured_key_blob.cpp
@@ -47,7 +47,7 @@
     HMAC_CTX* ctx_;
 };
 
-keymaster_error_t ComputeHmac(const uint8_t* serialized_data, size_t serialized_data_size,
+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 uint8_t[hidden_bytes_size]);
diff --git a/soft_keymaster_device.cpp b/soft_keymaster_device.cpp
index d755789..441ed0e 100644
--- a/soft_keymaster_device.cpp
+++ b/soft_keymaster_device.cpp
@@ -323,10 +323,12 @@
 }
 
 /* static */
-int SoftKeymasterDevice::delete_keypair(const struct keymaster1_device* /* dev */,
-                                        const uint8_t* /* key_blob */,
-                                        const size_t /* key_blob_length */) {
-    return KM_ERROR_UNIMPLEMENTED;
+int SoftKeymasterDevice::delete_keypair(const struct keymaster1_device* dev,
+                                        const uint8_t* key_blob, const size_t key_blob_length) {
+    if (!dev || !dev->delete_keypair) {
+        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+    }
+    return dev->delete_keypair(dev, key_blob, key_blob_length);
 }
 
 /* static */
@@ -445,8 +447,9 @@
     if (!algorithms || !algorithms_length)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    SupportedResponse<keymaster_algorithm_t> response;
-    convert_device(dev)->impl_->SupportedAlgorithms(&response);
+    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);
 
@@ -474,8 +477,11 @@
     if (!modes || !modes_length)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    SupportedResponse<keymaster_block_mode_t> response;
-    convert_device(dev)->impl_->SupportedBlockModes(algorithm, purpose, &response);
+    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);
@@ -503,8 +509,11 @@
     if (!modes || !modes_length)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    SupportedResponse<keymaster_padding_t> response;
-    convert_device(dev)->impl_->SupportedPaddingModes(algorithm, purpose, &response);
+    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);
@@ -531,8 +540,11 @@
     if (!digests || !digests_length)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    SupportedResponse<keymaster_digest_t> response;
-    convert_device(dev)->impl_->SupportedDigests(algorithm, purpose, &response);
+    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);
@@ -557,8 +569,10 @@
     if (!formats || !formats_length)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    SupportedResponse<keymaster_key_format_t> response;
-    convert_device(dev)->impl_->SupportedImportFormats(algorithm, &response);
+    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);
@@ -584,8 +598,10 @@
     if (!formats || !formats_length)
         return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    SupportedResponse<keymaster_key_format_t> response;
-    convert_device(dev)->impl_->SupportedExportFormats(algorithm, &response);
+    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);
@@ -609,7 +625,11 @@
 
     AddEntropyRequest request;
     request.random_data.Reinitialize(data, data_length);
-    return convert_device(dev)->impl_->AddRngEntropy(request);
+    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 */
@@ -874,7 +894,11 @@
 /* static */
 keymaster_error_t SoftKeymasterDevice::abort(const keymaster1_device_t* dev,
                                              keymaster_operation_handle_t operation_handle) {
-    return convert_device(dev)->impl_->AbortOperation(operation_handle);
+    AbortOperationRequest request;
+    request.op_handle = operation_handle;
+    AbortOperationResponse response;
+    convert_device(dev)->impl_->AbortOperation(request, &response);
+    return response.error;
 }
 
 /* static */