blob: 94bc199ca70f0d2979e74b872a850202b473cac9 [file] [log] [blame]
/*
* 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 <android/binder_manager.h>
#include <keymint_support/key_param_output.h>
#include <keymint_support/keymint_utils.h>
namespace aidl::android::hardware::security::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(const Status& result) {
if (result.isOk()) return ErrorCode::OK;
if (result.getExceptionCode() == EX_SERVICE_SPECIFIC) {
return static_cast<ErrorCode>(result.getServiceSpecificError());
}
return ErrorCode::UNKNOWN_ERROR;
}
void KeyMintAidlTestBase::InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint) {
ASSERT_NE(keyMint, nullptr);
keymint_ = std::move(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() {
if (AServiceManager_isDeclared(GetParam().c_str())) {
::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
InitializeKeyMint(IKeyMintDevice::fromBinder(binder));
} else {
InitializeKeyMint(nullptr);
}
}
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.getServiceSpecificError() << 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.getServiceSpecificError() << 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,
std::shared_ptr<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_.reset();
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 std::shared_ptr<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.getServiceSpecificError());
}
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.getServiceSpecificError());
}
void KeyMintAidlTestBase::AbortIfNeeded() {
SCOPED_TRACE("AbortIfNeeded");
if (op_) {
EXPECT_EQ(ErrorCode::OK, Abort());
op_.reset();
}
}
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_.reset();
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);
if (ivVal) *iv_out = *ivVal;
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 aidl::android::hardware::security::keymint