Implement keymint V1 aidl interfaces, service module, and vts tests.

Bug: b/160968242
Test: atest VtsHalKeyMintV1_0TargetTest

Change-Id: I5f9d642f96e262dd567d88f4d582e621d168dceb
diff --git a/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
new file mode 100644
index 0000000..0546149
--- /dev/null
+++ b/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -0,0 +1,756 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "KeyMintAidlTestBase.h"
+
+#include <chrono>
+#include <vector>
+
+#include <android-base/logging.h>
+
+#include <keymintSupport/key_param_output.h>
+#include <keymintSupport/keymint_utils.h>
+
+namespace android {
+namespace hardware {
+namespace keymint {
+
+using namespace std::literals::chrono_literals;
+using std::endl;
+using std::optional;
+
+::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set) {
+    if (set.size() == 0)
+        os << "(Empty)" << ::std::endl;
+    else {
+        os << "\n";
+        for (size_t i = 0; i < set.size(); ++i) os << set[i] << ::std::endl;
+    }
+    return os;
+}
+
+namespace test {
+
+ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(Status result) {
+    if (result.isOk()) return ErrorCode::OK;
+
+    if (result.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
+        return static_cast<ErrorCode>(result.serviceSpecificErrorCode());
+    }
+
+    return ErrorCode::UNKNOWN_ERROR;
+}
+
+void KeyMintAidlTestBase::InitializeKeyMint(sp<IKeyMintDevice> keyMint) {
+    ASSERT_NE(keyMint, nullptr);
+    keymint_ = keyMint;
+
+    KeyMintHardwareInfo info;
+    ASSERT_TRUE(keymint_->getHardwareInfo(&info).isOk());
+
+    securityLevel_ = info.securityLevel;
+    name_.assign(info.keyMintName.begin(), info.keyMintName.end());
+    author_.assign(info.keyMintAuthorName.begin(), info.keyMintAuthorName.end());
+
+    os_version_ = getOsVersion();
+    os_patch_level_ = getOsPatchlevel();
+}
+
+void KeyMintAidlTestBase::SetUp() {
+    InitializeKeyMint(
+            android::waitForDeclaredService<IKeyMintDevice>(String16(GetParam().c_str())));
+}
+
+ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
+                                           vector<uint8_t>* keyBlob, KeyCharacteristics* keyChar) {
+    EXPECT_NE(keyBlob, nullptr) << "Key blob pointer must not be null.  Test bug";
+    EXPECT_NE(keyChar, nullptr)
+            << "Previous characteristics not deleted before generating key.  Test bug.";
+
+    // Aidl does not clear these output parameters if the function returns
+    // error.  This is different from hal where output parameter is always
+    // cleared due to hal returning void.  So now we need to do our own clearing
+    // of the output variables prior to calling keyMint aidl libraries.
+    keyBlob->clear();
+    keyChar->softwareEnforced.clear();
+    keyChar->hardwareEnforced.clear();
+    certChain_.clear();
+
+    Status result;
+    ByteArray blob;
+
+    result = keymint_->generateKey(key_desc.vector_data(), &blob, keyChar, &certChain_);
+
+    // On result, blob & characteristics should be empty.
+    if (result.isOk()) {
+        if (SecLevel() != SecurityLevel::SOFTWARE) {
+            EXPECT_GT(keyChar->hardwareEnforced.size(), 0);
+        }
+        EXPECT_GT(keyChar->softwareEnforced.size(), 0);
+        // TODO(seleneh) in a later version where we return @nullable
+        // single Certificate, check non-null single certificate is always
+        // non-empty.
+        *keyBlob = blob.data;
+    }
+
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc) {
+    return GenerateKey(key_desc, &key_blob_, &key_characteristics_);
+}
+
+ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
+                                         const string& key_material, vector<uint8_t>* key_blob,
+                                         KeyCharacteristics* key_characteristics) {
+    Status result;
+
+    certChain_.clear();
+    key_characteristics->softwareEnforced.clear();
+    key_characteristics->hardwareEnforced.clear();
+    key_blob->clear();
+
+    ByteArray blob;
+    result = keymint_->importKey(key_desc.vector_data(), format,
+                                 vector<uint8_t>(key_material.begin(), key_material.end()), &blob,
+                                 key_characteristics, &certChain_);
+
+    if (result.isOk()) {
+        if (SecLevel() != SecurityLevel::SOFTWARE) {
+            EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0);
+        }
+        EXPECT_GT(key_characteristics->softwareEnforced.size(), 0);
+        *key_blob = blob.data;
+    }
+
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
+                                         const string& key_material) {
+    return ImportKey(key_desc, format, key_material, &key_blob_, &key_characteristics_);
+}
+
+ErrorCode KeyMintAidlTestBase::ImportWrappedKey(string wrapped_key, string wrapping_key,
+                                                const AuthorizationSet& wrapping_key_desc,
+                                                string masking_key,
+                                                const AuthorizationSet& unwrapping_params) {
+    Status result;
+    EXPECT_EQ(ErrorCode::OK, ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key));
+
+    ByteArray outBlob;
+    key_characteristics_.softwareEnforced.clear();
+    key_characteristics_.hardwareEnforced.clear();
+
+    result = keymint_->importWrappedKey(vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()),
+                                        key_blob_,
+                                        vector<uint8_t>(masking_key.begin(), masking_key.end()),
+                                        unwrapping_params.vector_data(), 0 /* passwordSid */,
+                                        0 /* biometricSid */, &outBlob, &key_characteristics_);
+
+    if (result.isOk()) {
+        key_blob_ = outBlob.data;
+        if (SecLevel() != SecurityLevel::SOFTWARE) {
+            EXPECT_GT(key_characteristics_.hardwareEnforced.size(), 0);
+        }
+        EXPECT_GT(key_characteristics_.softwareEnforced.size(), 0);
+    }
+
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
+    Status result = keymint_->deleteKey(*key_blob);
+    if (!keep_key_blob) {
+        *key_blob = vector<uint8_t>();
+    }
+
+    EXPECT_TRUE(result.isOk()) << result.serviceSpecificErrorCode() << endl;
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::DeleteKey(bool keep_key_blob) {
+    return DeleteKey(&key_blob_, keep_key_blob);
+}
+
+ErrorCode KeyMintAidlTestBase::DeleteAllKeys() {
+    Status result = keymint_->deleteAllKeys();
+    EXPECT_TRUE(result.isOk()) << result.serviceSpecificErrorCode() << endl;
+    return GetReturnErrorCode(result);
+}
+
+void KeyMintAidlTestBase::CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
+    ErrorCode result = DeleteKey(key_blob, keep_key_blob);
+    EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
+}
+
+void KeyMintAidlTestBase::CheckedDeleteKey() {
+    CheckedDeleteKey(&key_blob_);
+}
+
+ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
+                                     const AuthorizationSet& in_params,
+                                     AuthorizationSet* out_params, sp<IKeyMintOperation>& op) {
+    SCOPED_TRACE("Begin");
+    Status result;
+    BeginResult out;
+    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out);
+
+    if (result.isOk()) {
+        *out_params = out.params;
+        challenge_ = out.challenge;
+        op = out.operation;
+    }
+
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
+                                     const AuthorizationSet& in_params,
+                                     AuthorizationSet* out_params) {
+    SCOPED_TRACE("Begin");
+    Status result;
+    BeginResult out;
+
+    result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out);
+
+    if (result.isOk()) {
+        *out_params = out.params;
+        challenge_ = out.challenge;
+        op_ = out.operation;
+    }
+
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
+                                     AuthorizationSet* out_params) {
+    SCOPED_TRACE("Begin");
+    EXPECT_EQ(nullptr, op_);
+    return Begin(purpose, key_blob_, in_params, out_params);
+}
+
+ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet& in_params) {
+    SCOPED_TRACE("Begin");
+    AuthorizationSet out_params;
+    ErrorCode result = Begin(purpose, in_params, &out_params);
+    EXPECT_TRUE(out_params.empty());
+    return result;
+}
+
+ErrorCode KeyMintAidlTestBase::Update(const AuthorizationSet& in_params, const string& input,
+                                      AuthorizationSet* out_params, string* output,
+                                      int32_t* input_consumed) {
+    SCOPED_TRACE("Update");
+
+    Status result;
+    EXPECT_NE(op_, nullptr);
+    if (!op_) {
+        return ErrorCode::UNEXPECTED_NULL_POINTER;
+    }
+
+    KeyParameterArray key_params;
+    key_params.params = in_params.vector_data();
+
+    KeyParameterArray in_keyParams;
+    in_keyParams.params = in_params.vector_data();
+
+    optional<KeyParameterArray> out_keyParams;
+    optional<ByteArray> o_put;
+    result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
+                         &out_keyParams, &o_put, input_consumed);
+
+    if (result.isOk()) {
+        if (o_put) {
+            output->append(o_put->data.begin(), o_put->data.end());
+        }
+
+        if (out_keyParams) {
+            out_params->push_back(AuthorizationSet(out_keyParams->params));
+        }
+    }
+
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::Update(const string& input, string* out, int32_t* input_consumed) {
+    SCOPED_TRACE("Update");
+    AuthorizationSet out_params;
+    ErrorCode result =
+            Update(AuthorizationSet() /* in_params */, input, &out_params, out, input_consumed);
+    EXPECT_TRUE(out_params.empty());
+    return result;
+}
+
+ErrorCode KeyMintAidlTestBase::Finish(const AuthorizationSet& in_params, const string& input,
+                                      const string& signature, AuthorizationSet* out_params,
+                                      string* output) {
+    SCOPED_TRACE("Finish");
+    Status result;
+
+    EXPECT_NE(op_, nullptr);
+    if (!op_) {
+        return ErrorCode::UNEXPECTED_NULL_POINTER;
+    }
+
+    KeyParameterArray key_params;
+    key_params.params = in_params.vector_data();
+
+    KeyParameterArray in_keyParams;
+    in_keyParams.params = in_params.vector_data();
+
+    optional<KeyParameterArray> out_keyParams;
+    optional<vector<uint8_t>> o_put;
+
+    vector<uint8_t> oPut;
+    result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
+                         vector<uint8_t>(signature.begin(), signature.end()), {}, {},
+                         &out_keyParams, &oPut);
+
+    if (result.isOk()) {
+        if (out_keyParams) {
+            out_params->push_back(AuthorizationSet(out_keyParams->params));
+        }
+
+        output->append(oPut.begin(), oPut.end());
+    }
+
+    op_.clear();  // So dtor doesn't Abort().
+    return GetReturnErrorCode(result);
+}
+
+ErrorCode KeyMintAidlTestBase::Finish(const string& message, string* output) {
+    SCOPED_TRACE("Finish");
+    AuthorizationSet out_params;
+    string finish_output;
+    ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, "" /* signature */,
+                              &out_params, output);
+    if (result != ErrorCode::OK) {
+        return result;
+    }
+    EXPECT_EQ(0U, out_params.size());
+    return result;
+}
+
+ErrorCode KeyMintAidlTestBase::Finish(const string& message, const string& signature,
+                                      string* output) {
+    SCOPED_TRACE("Finish");
+    AuthorizationSet out_params;
+    ErrorCode result =
+            Finish(AuthorizationSet() /* in_params */, message, signature, &out_params, output);
+
+    if (result != ErrorCode::OK) {
+        return result;
+    }
+
+    EXPECT_EQ(0U, out_params.size());
+    return result;
+}
+
+ErrorCode KeyMintAidlTestBase::Abort(const sp<IKeyMintOperation>& op) {
+    SCOPED_TRACE("Abort");
+
+    EXPECT_NE(op, nullptr);
+    if (!op) {
+        return ErrorCode::UNEXPECTED_NULL_POINTER;
+    }
+
+    Status retval = op->abort();
+    EXPECT_TRUE(retval.isOk());
+    return static_cast<ErrorCode>(retval.serviceSpecificErrorCode());
+}
+
+ErrorCode KeyMintAidlTestBase::Abort() {
+    SCOPED_TRACE("Abort");
+
+    EXPECT_NE(op_, nullptr);
+    if (!op_) {
+        return ErrorCode::UNEXPECTED_NULL_POINTER;
+    }
+
+    Status retval = op_->abort();
+    return static_cast<ErrorCode>(retval.serviceSpecificErrorCode());
+}
+
+void KeyMintAidlTestBase::AbortIfNeeded() {
+    SCOPED_TRACE("AbortIfNeeded");
+    if (op_) {
+        EXPECT_EQ(ErrorCode::OK, Abort());
+        op_.clear();
+    }
+}
+
+string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
+                                           const string& message, const AuthorizationSet& in_params,
+                                           AuthorizationSet* out_params) {
+    SCOPED_TRACE("ProcessMessage");
+    AuthorizationSet begin_out_params;
+    ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
+    EXPECT_EQ(ErrorCode::OK, result);
+    if (result != ErrorCode::OK) {
+        return "";
+    }
+
+    string output;
+    int32_t consumed = 0;
+    AuthorizationSet update_params;
+    AuthorizationSet update_out_params;
+    result = Update(update_params, message, &update_out_params, &output, &consumed);
+    EXPECT_EQ(ErrorCode::OK, result);
+    if (result != ErrorCode::OK) {
+        return "";
+    }
+
+    string unused;
+    AuthorizationSet finish_params;
+    AuthorizationSet finish_out_params;
+    EXPECT_EQ(ErrorCode::OK,
+              Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output));
+
+    out_params->push_back(begin_out_params);
+    out_params->push_back(finish_out_params);
+    return output;
+}
+
+string KeyMintAidlTestBase::SignMessage(const vector<uint8_t>& key_blob, const string& message,
+                                        const AuthorizationSet& params) {
+    SCOPED_TRACE("SignMessage");
+    AuthorizationSet out_params;
+    string signature = ProcessMessage(key_blob, KeyPurpose::SIGN, message, params, &out_params);
+    EXPECT_TRUE(out_params.empty());
+    return signature;
+}
+
+string KeyMintAidlTestBase::SignMessage(const string& message, const AuthorizationSet& params) {
+    SCOPED_TRACE("SignMessage");
+    return SignMessage(key_blob_, message, params);
+}
+
+string KeyMintAidlTestBase::MacMessage(const string& message, Digest digest, size_t mac_length) {
+    SCOPED_TRACE("MacMessage");
+    return SignMessage(
+            key_blob_, message,
+            AuthorizationSetBuilder().Digest(digest).Authorization(TAG_MAC_LENGTH, mac_length));
+}
+
+void KeyMintAidlTestBase::CheckHmacTestVector(const string& key, const string& message,
+                                              Digest digest, const string& expected_mac) {
+    SCOPED_TRACE("CheckHmacTestVector");
+    ASSERT_EQ(ErrorCode::OK,
+              ImportKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .HmacKey(key.size() * 8)
+                                .Authorization(TAG_MIN_MAC_LENGTH, expected_mac.size() * 8)
+                                .Digest(digest),
+                        KeyFormat::RAW, key));
+    string signature = MacMessage(message, digest, expected_mac.size() * 8);
+    EXPECT_EQ(expected_mac, signature)
+            << "Test vector didn't match for key of size " << key.size() << " message of size "
+            << message.size() << " and digest " << digest;
+    CheckedDeleteKey();
+}
+
+void KeyMintAidlTestBase::CheckAesCtrTestVector(const string& key, const string& nonce,
+                                                const string& message,
+                                                const string& expected_ciphertext) {
+    SCOPED_TRACE("CheckAesCtrTestVector");
+    ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
+                                               .Authorization(TAG_NO_AUTH_REQUIRED)
+                                               .AesEncryptionKey(key.size() * 8)
+                                               .BlockMode(BlockMode::CTR)
+                                               .Authorization(TAG_CALLER_NONCE)
+                                               .Padding(PaddingMode::NONE),
+                                       KeyFormat::RAW, key));
+
+    auto params = AuthorizationSetBuilder()
+                          .Authorization(TAG_NONCE, nonce.data(), nonce.size())
+                          .BlockMode(BlockMode::CTR)
+                          .Padding(PaddingMode::NONE);
+    AuthorizationSet out_params;
+    string ciphertext = EncryptMessage(key_blob_, message, params, &out_params);
+    EXPECT_EQ(expected_ciphertext, ciphertext);
+}
+
+void KeyMintAidlTestBase::CheckTripleDesTestVector(KeyPurpose purpose, BlockMode block_mode,
+                                                   PaddingMode padding_mode, const string& key,
+                                                   const string& iv, const string& input,
+                                                   const string& expected_output) {
+    auto authset = AuthorizationSetBuilder()
+                           .TripleDesEncryptionKey(key.size() * 7)
+                           .BlockMode(block_mode)
+                           .Authorization(TAG_NO_AUTH_REQUIRED)
+                           .Padding(padding_mode);
+    if (iv.size()) authset.Authorization(TAG_CALLER_NONCE);
+    ASSERT_EQ(ErrorCode::OK, ImportKey(authset, KeyFormat::RAW, key));
+    ASSERT_GT(key_blob_.size(), 0U);
+
+    auto begin_params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding_mode);
+    if (iv.size()) begin_params.Authorization(TAG_NONCE, iv.data(), iv.size());
+    AuthorizationSet output_params;
+    string output = ProcessMessage(key_blob_, purpose, input, begin_params, &output_params);
+    EXPECT_EQ(expected_output, output);
+}
+
+void KeyMintAidlTestBase::VerifyMessage(const vector<uint8_t>& key_blob, const string& message,
+                                        const string& signature, const AuthorizationSet& params) {
+    SCOPED_TRACE("VerifyMessage");
+    AuthorizationSet begin_out_params;
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params));
+
+    string output;
+    AuthorizationSet update_params;
+    AuthorizationSet update_out_params;
+    int32_t consumed;
+    ASSERT_EQ(ErrorCode::OK,
+              Update(update_params, message, &update_out_params, &output, &consumed));
+    EXPECT_TRUE(output.empty());
+    EXPECT_GT(consumed, 0U);
+
+    string unused;
+    AuthorizationSet finish_params;
+    AuthorizationSet finish_out_params;
+    EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), signature,
+                                    &finish_out_params, &output));
+    op_.clear();
+    EXPECT_TRUE(output.empty());
+}
+
+void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& signature,
+                                        const AuthorizationSet& params) {
+    SCOPED_TRACE("VerifyMessage");
+    VerifyMessage(key_blob_, message, signature, params);
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
+                                           const AuthorizationSet& in_params,
+                                           AuthorizationSet* out_params) {
+    SCOPED_TRACE("EncryptMessage");
+    return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params);
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const string& message, const AuthorizationSet& params,
+                                           AuthorizationSet* out_params) {
+    SCOPED_TRACE("EncryptMessage");
+    return EncryptMessage(key_blob_, message, params, out_params);
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const string& message, const AuthorizationSet& params) {
+    SCOPED_TRACE("EncryptMessage");
+    AuthorizationSet out_params;
+    string ciphertext = EncryptMessage(message, params, &out_params);
+    EXPECT_TRUE(out_params.empty()) << "Output params should be empty. Contained: " << out_params;
+    return ciphertext;
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
+                                           PaddingMode padding) {
+    SCOPED_TRACE("EncryptMessage");
+    auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding);
+    AuthorizationSet out_params;
+    string ciphertext = EncryptMessage(message, params, &out_params);
+    EXPECT_TRUE(out_params.empty()) << "Output params should be empty. Contained: " << out_params;
+    return ciphertext;
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
+                                           PaddingMode padding, vector<uint8_t>* iv_out) {
+    SCOPED_TRACE("EncryptMessage");
+    auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding);
+    AuthorizationSet out_params;
+    string ciphertext = EncryptMessage(message, params, &out_params);
+    EXPECT_EQ(1U, out_params.size());
+    auto ivVal = out_params.GetTagValue(TAG_NONCE);
+    EXPECT_TRUE(ivVal.isOk());
+    if (ivVal.isOk()) *iv_out = ivVal.value();
+    return ciphertext;
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
+                                           PaddingMode padding, const vector<uint8_t>& iv_in) {
+    SCOPED_TRACE("EncryptMessage");
+    auto params = AuthorizationSetBuilder()
+                          .BlockMode(block_mode)
+                          .Padding(padding)
+                          .Authorization(TAG_NONCE, iv_in);
+    AuthorizationSet out_params;
+    string ciphertext = EncryptMessage(message, params, &out_params);
+    return ciphertext;
+}
+
+string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
+                                           PaddingMode padding, uint8_t mac_length_bits,
+                                           const vector<uint8_t>& iv_in) {
+    SCOPED_TRACE("EncryptMessage");
+    auto params = AuthorizationSetBuilder()
+                          .BlockMode(block_mode)
+                          .Padding(padding)
+                          .Authorization(TAG_MAC_LENGTH, mac_length_bits)
+                          .Authorization(TAG_NONCE, iv_in);
+    AuthorizationSet out_params;
+    string ciphertext = EncryptMessage(message, params, &out_params);
+    return ciphertext;
+}
+
+string KeyMintAidlTestBase::DecryptMessage(const vector<uint8_t>& key_blob,
+                                           const string& ciphertext,
+                                           const AuthorizationSet& params) {
+    SCOPED_TRACE("DecryptMessage");
+    AuthorizationSet out_params;
+    string plaintext =
+            ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params);
+    EXPECT_TRUE(out_params.empty());
+    return plaintext;
+}
+
+string KeyMintAidlTestBase::DecryptMessage(const string& ciphertext,
+                                           const AuthorizationSet& params) {
+    SCOPED_TRACE("DecryptMessage");
+    return DecryptMessage(key_blob_, ciphertext, params);
+}
+
+string KeyMintAidlTestBase::DecryptMessage(const string& ciphertext, BlockMode block_mode,
+                                           PaddingMode padding_mode, const vector<uint8_t>& iv) {
+    SCOPED_TRACE("DecryptMessage");
+    auto params = AuthorizationSetBuilder()
+                          .BlockMode(block_mode)
+                          .Padding(padding_mode)
+                          .Authorization(TAG_NONCE, iv);
+    return DecryptMessage(key_blob_, ciphertext, params);
+}
+
+std::pair<ErrorCode, vector<uint8_t>> KeyMintAidlTestBase::UpgradeKey(
+        const vector<uint8_t>& key_blob) {
+    std::pair<ErrorCode, vector<uint8_t>> retval;
+    vector<uint8_t> outKeyBlob;
+    Status result = keymint_->upgradeKey(key_blob, vector<KeyParameter>(), &outKeyBlob);
+    ErrorCode errorcode = GetReturnErrorCode(result);
+    retval = std::tie(errorcode, outKeyBlob);
+
+    return retval;
+}
+vector<uint32_t> KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) {
+    switch (algorithm) {
+        case Algorithm::RSA:
+            switch (SecLevel()) {
+                case SecurityLevel::SOFTWARE:
+                case SecurityLevel::TRUSTED_ENVIRONMENT:
+                    return {2048, 3072, 4096};
+                case SecurityLevel::STRONGBOX:
+                    return {2048};
+                default:
+                    ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
+                    break;
+            }
+            break;
+        case Algorithm::EC:
+            switch (SecLevel()) {
+                case SecurityLevel::SOFTWARE:
+                case SecurityLevel::TRUSTED_ENVIRONMENT:
+                    return {224, 256, 384, 521};
+                case SecurityLevel::STRONGBOX:
+                    return {256};
+                default:
+                    ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
+                    break;
+            }
+            break;
+        case Algorithm::AES:
+            return {128, 256};
+        case Algorithm::TRIPLE_DES:
+            return {168};
+        case Algorithm::HMAC: {
+            vector<uint32_t> retval((512 - 64) / 8 + 1);
+            uint32_t size = 64 - 8;
+            std::generate(retval.begin(), retval.end(), [&]() { return (size += 8); });
+            return retval;
+        }
+        default:
+            ADD_FAILURE() << "Invalid Algorithm: " << algorithm;
+            return {};
+    }
+    ADD_FAILURE() << "Should be impossible to get here";
+    return {};
+}
+
+vector<uint32_t> KeyMintAidlTestBase::InvalidKeySizes(Algorithm algorithm) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        switch (algorithm) {
+            case Algorithm::RSA:
+                return {3072, 4096};
+            case Algorithm::EC:
+                return {224, 384, 521};
+            case Algorithm::AES:
+                return {192};
+            default:
+                return {};
+        }
+    }
+    return {};
+}
+
+vector<EcCurve> KeyMintAidlTestBase::ValidCurves() {
+    if (securityLevel_ == SecurityLevel::STRONGBOX) {
+        return {EcCurve::P_256};
+    } else {
+        return {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521};
+    }
+}
+
+vector<EcCurve> KeyMintAidlTestBase::InvalidCurves() {
+    if (SecLevel() == SecurityLevel::TRUSTED_ENVIRONMENT) return {};
+    CHECK(SecLevel() == SecurityLevel::STRONGBOX);
+    return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521};
+}
+
+vector<Digest> KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) {
+    switch (SecLevel()) {
+        case SecurityLevel::SOFTWARE:
+        case SecurityLevel::TRUSTED_ENVIRONMENT:
+            if (withNone) {
+                if (withMD5)
+                    return {Digest::NONE,      Digest::MD5,       Digest::SHA1,
+                            Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384,
+                            Digest::SHA_2_512};
+                else
+                    return {Digest::NONE,      Digest::SHA1,      Digest::SHA_2_224,
+                            Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512};
+            } else {
+                if (withMD5)
+                    return {Digest::MD5,       Digest::SHA1,      Digest::SHA_2_224,
+                            Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512};
+                else
+                    return {Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384,
+                            Digest::SHA_2_512};
+            }
+            break;
+        case SecurityLevel::STRONGBOX:
+            if (withNone)
+                return {Digest::NONE, Digest::SHA_2_256};
+            else
+                return {Digest::SHA_2_256};
+            break;
+        default:
+            ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
+            break;
+    }
+    ADD_FAILURE() << "Should be impossible to get here";
+    return {};
+}
+
+}  // namespace test
+}  // namespace keymint
+}  // namespace hardware
+}  // namespace android