1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <android/hardware/keymaster/4.1/IKeymasterDevice.h>
20
21 #include <android-base/properties.h>
22
23 #include <KeymasterHidlTest.h>
24 #include <keymasterV4_1/authorization_set.h>
25
26 namespace android::hardware::keymaster::V4_1::test {
27
28 using V4_0::test::HidlBuf;
29
30 class Keymaster4_1HidlTest : public V4_0::test::KeymasterHidlTest {
31 public:
32 using super = V4_0::test::KeymasterHidlTest;
33
convert(V4_0::ErrorCode error_code)34 ErrorCode convert(V4_0::ErrorCode error_code) { return static_cast<ErrorCode>(error_code); }
35
36 // These methods hide the base class versions.
37 void SetUp();
keymaster()38 IKeymasterDevice& keymaster() { return *keymaster41_; };
39
40 struct KeyData {
41 HidlBuf blob;
42 KeyCharacteristics characteristics;
43 };
44
GenerateKeyData(const AuthorizationSet & keyDescription)45 std::tuple<ErrorCode, KeyData> GenerateKeyData(const AuthorizationSet& keyDescription) {
46 KeyData keyData;
47 ErrorCode errorCode = convert(
48 super::GenerateKey(keyDescription, &keyData.blob, &keyData.characteristics));
49 return {errorCode, keyData};
50 }
51
CheckedDeleteKeyData(KeyData * keyData)52 void CheckedDeleteKeyData(KeyData* keyData) { CheckedDeleteKey(&keyData->blob); }
53
54 template <typename TagType>
55 std::tuple<KeyData /* aesKey */, KeyData /* hmacKey */, KeyData /* rsaKey */,
56 KeyData /* ecdsaKey */>
CreateTestKeys(TagType tagToTest,ErrorCode expectedReturn)57 CreateTestKeys(TagType tagToTest, ErrorCode expectedReturn) {
58 ErrorCode errorCode;
59
60 /* AES */
61 KeyData aesKeyData;
62 std::tie(errorCode, aesKeyData) =
63 GenerateKeyData(AuthorizationSetBuilder()
64 .AesEncryptionKey(128)
65 .Authorization(tagToTest)
66 .BlockMode(BlockMode::ECB)
67 .Padding(PaddingMode::NONE)
68 .Authorization(TAG_NO_AUTH_REQUIRED));
69 EXPECT_EQ(expectedReturn, errorCode);
70
71 /* HMAC */
72 KeyData hmacKeyData;
73 std::tie(errorCode, hmacKeyData) =
74 GenerateKeyData(AuthorizationSetBuilder()
75 .HmacKey(128)
76 .Authorization(tagToTest)
77 .Digest(Digest::SHA_2_256)
78 .Authorization(TAG_MIN_MAC_LENGTH, 128)
79 .Authorization(TAG_NO_AUTH_REQUIRED));
80 EXPECT_EQ(expectedReturn, errorCode);
81
82 /* RSA */
83 KeyData rsaKeyData;
84 std::tie(errorCode, rsaKeyData) =
85 GenerateKeyData(AuthorizationSetBuilder()
86 .RsaSigningKey(2048, 65537)
87 .Authorization(tagToTest)
88 .Digest(Digest::NONE)
89 .Padding(PaddingMode::NONE)
90 .Authorization(TAG_NO_AUTH_REQUIRED));
91 EXPECT_EQ(expectedReturn, errorCode);
92
93 /* ECDSA */
94 KeyData ecdsaKeyData;
95 std::tie(errorCode, ecdsaKeyData) =
96 GenerateKeyData(AuthorizationSetBuilder()
97 .EcdsaSigningKey(256)
98 .Authorization(tagToTest)
99 .Digest(Digest::SHA_2_256)
100 .Authorization(TAG_NO_AUTH_REQUIRED));
101 EXPECT_EQ(expectedReturn, errorCode);
102
103 return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData};
104 }
105
106 std::tuple<ErrorCode, std::string /* processedMessage */, AuthorizationSet /* out_params */>
107 ProcessMessage(const HidlBuf& key_blob, KeyPurpose operation, const std::string& message,
108 const AuthorizationSet& in_params);
109
UseAesKey(const HidlBuf & aesKeyBlob)110 ErrorCode UseAesKey(const HidlBuf& aesKeyBlob) {
111 auto [result, ciphertext, out_params] = ProcessMessage(
112 aesKeyBlob, KeyPurpose::ENCRYPT, "1234567890123456",
113 AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE));
114 return result;
115 }
116
UseHmacKey(const HidlBuf & hmacKeyBlob)117 ErrorCode UseHmacKey(const HidlBuf& hmacKeyBlob) {
118 auto [result, mac, out_params] =
119 ProcessMessage(hmacKeyBlob, KeyPurpose::SIGN, "1234567890123456",
120 AuthorizationSetBuilder()
121 .Authorization(TAG_MAC_LENGTH, 128)
122 .Digest(Digest::SHA_2_256));
123 return result;
124 }
125
UseRsaKey(const HidlBuf & rsaKeyBlob)126 ErrorCode UseRsaKey(const HidlBuf& rsaKeyBlob) {
127 std::string message(2048 / 8, 'a');
128 auto [result, signature, out_params] = ProcessMessage(
129 rsaKeyBlob, KeyPurpose::SIGN, message,
130 AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
131 return result;
132 }
133
UseEcdsaKey(const HidlBuf & ecdsaKeyBlob)134 ErrorCode UseEcdsaKey(const HidlBuf& ecdsaKeyBlob) {
135 auto [result, signature, out_params] =
136 ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
137 AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
138 return result;
139 }
140
build_params()141 static std::vector<std::string> build_params() {
142 auto params = android::hardware::getAllHalInstanceNames(IKeymasterDevice::descriptor);
143 return params;
144 }
145
146 private:
147 sp<IKeymasterDevice> keymaster41_;
148 };
149
150 template <typename TypedTag>
contains(hidl_vec<KeyParameter> & set,TypedTag typedTag)151 bool contains(hidl_vec<KeyParameter>& set, TypedTag typedTag) {
152 return std::find_if(set.begin(), set.end(), [&](const KeyParameter& param) {
153 return param.tag == static_cast<V4_0::Tag>(typedTag);
154 }) != set.end();
155 }
156
157 #define INSTANTIATE_KEYMASTER_4_1_HIDL_TEST(name) \
158 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \
159 INSTANTIATE_TEST_SUITE_P(PerInstance, name, \
160 testing::ValuesIn(Keymaster4_1HidlTest::build_params()), \
161 android::hardware::PrintInstanceNameToString)
162
163 } // namespace android::hardware::keymaster::V4_1::test
164
165 namespace android::hardware::keymaster::V4_0::test {
166
167 // If the given property is available, add it to the tag set under the given tag ID.
168 template <Tag tag>
add_tag_from_prop(AuthorizationSetBuilder * tags,TypedTag<TagType::BYTES,tag> ttag,const char * prop)169 void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
170 const char* prop) {
171 std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
172 if (!prop_value.empty()) {
173 tags->Authorization(ttag, prop_value.data(), prop_value.size());
174 }
175 }
176
177 } // namespace android::hardware::keymaster::V4_0::test
178