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