blob: 4139af653c2498a404a843dc5d69df66405e15c5 [file] [log] [blame]
Shawn Willden128ffe02014-08-06 12:31:33 -06001/*
2 * Copyright (C) 2014 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#include <gtest/gtest.h>
Shawn Willden76364712014-08-11 17:48:04 -060018
Shawn Willden128ffe02014-08-06 12:31:33 -060019#include <openssl/engine.h>
20
21#define KEYMASTER_NAME_TAGS
Shawn Willden76364712014-08-11 17:48:04 -060022#include "google_keymaster_test_utils.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060023#include "google_keymaster_utils.h"
24#include "google_softkeymaster.h"
Shawn Willden76364712014-08-11 17:48:04 -060025#include "keymaster_tags.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060026
27int main(int argc, char** argv) {
28 ::testing::InitGoogleTest(&argc, argv);
29 int result = RUN_ALL_TESTS();
30 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
31 CRYPTO_cleanup_all_ex_data();
32 ERR_free_strings();
33 return result;
34}
35
36namespace keymaster {
37namespace test {
38
39class KeymasterTest : public testing::Test {
40 protected:
41 KeymasterTest() {
42 }
43 ~KeymasterTest() {
44 }
45
46 GoogleSoftKeymaster device;
47};
48
49template <keymaster_tag_t Tag, typename KeymasterEnum>
50bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
51 KeymasterEnum val) {
52 int pos = set.find(tag);
53 return pos != -1 && set[pos].enumerated == val;
54}
55
56template <keymaster_tag_t Tag, typename KeymasterEnum>
57bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
58 KeymasterEnum val) {
59 int pos = -1;
60 while ((pos = set.find(tag, pos)) != -1)
61 if (set[pos].enumerated == val)
62 return true;
63 return false;
64}
65
66template <keymaster_tag_t Tag>
67bool contains(const AuthorizationSet& set, TypedTag<KM_INT, Tag> tag, uint32_t val) {
68 int pos = set.find(tag);
69 return pos != -1 && set[pos].integer == val;
70}
71
72template <keymaster_tag_t Tag>
73bool contains(const AuthorizationSet& set, TypedTag<KM_INT_REP, Tag> tag, uint32_t val) {
74 int pos = -1;
75 while ((pos = set.find(tag, pos)) != -1)
76 if (set[pos].integer == val)
77 return true;
78 return false;
79}
80
81template <keymaster_tag_t Tag>
82bool contains(const AuthorizationSet& set, TypedTag<KM_LONG, Tag> tag, uint64_t val) {
83 int pos = set.find(tag);
84 return pos != -1 && set[pos].long_integer == val;
85}
86
87template <keymaster_tag_t Tag>
88bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
89 int pos = set.find(tag);
90 return pos != -1 &&
91 std::string(reinterpret_cast<const char*>(set[pos].blob.data),
92 set[pos].blob.data_length) == val;
93}
94
95inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) {
96 return set.find(tag) != -1;
97}
98
99typedef KeymasterTest CheckSupported;
100TEST_F(CheckSupported, SupportedAlgorithms) {
101 // Shouldn't blow up on NULL.
102 device.SupportedAlgorithms(NULL);
103
104 SupportedResponse<keymaster_algorithm_t> response;
105 device.SupportedAlgorithms(&response);
106 EXPECT_EQ(KM_ERROR_OK, response.error);
107 EXPECT_EQ(1U, response.results_length);
108 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
109}
110
111TEST_F(CheckSupported, SupportedBlockModes) {
112 // Shouldn't blow up on NULL.
113 device.SupportedBlockModes(KM_ALGORITHM_RSA, NULL);
114
115 SupportedResponse<keymaster_block_mode_t> response;
116 device.SupportedBlockModes(KM_ALGORITHM_RSA, &response);
117 EXPECT_EQ(KM_ERROR_OK, response.error);
118 EXPECT_EQ(0U, response.results_length);
119
120 device.SupportedBlockModes(KM_ALGORITHM_DSA, &response);
121 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
122}
123
124TEST_F(CheckSupported, SupportedPaddingModes) {
125 // Shouldn't blow up on NULL.
126 device.SupportedPaddingModes(KM_ALGORITHM_RSA, NULL);
127
128 SupportedResponse<keymaster_padding_t> response;
129 device.SupportedPaddingModes(KM_ALGORITHM_RSA, &response);
130 EXPECT_EQ(KM_ERROR_OK, response.error);
131 EXPECT_EQ(1U, response.results_length);
132 EXPECT_EQ(KM_PAD_NONE, response.results[0]);
133
134 device.SupportedPaddingModes(KM_ALGORITHM_DSA, &response);
135 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
136}
137
138TEST_F(CheckSupported, SupportedDigests) {
139 // Shouldn't blow up on NULL.
140 device.SupportedDigests(KM_ALGORITHM_RSA, NULL);
141
142 SupportedResponse<keymaster_digest_t> response;
143 device.SupportedDigests(KM_ALGORITHM_RSA, &response);
144 EXPECT_EQ(KM_ERROR_OK, response.error);
145 EXPECT_EQ(1U, response.results_length);
146 EXPECT_EQ(KM_DIGEST_NONE, response.results[0]);
147
148 device.SupportedDigests(KM_ALGORITHM_DSA, &response);
149 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
150}
151
152TEST_F(CheckSupported, SupportedImportFormats) {
153 // Shouldn't blow up on NULL.
154 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
155
156 SupportedResponse<keymaster_key_format_t> response;
157 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
158 EXPECT_EQ(KM_ERROR_OK, response.error);
159 EXPECT_EQ(1U, response.results_length);
160 EXPECT_EQ(KM_KEY_FORMAT_PKCS8, response.results[0]);
161
162 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
163 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
164}
165
166TEST_F(CheckSupported, SupportedExportFormats) {
167 // Shouldn't blow up on NULL.
168 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
169
170 SupportedResponse<keymaster_key_format_t> response;
171 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
172 EXPECT_EQ(KM_ERROR_OK, response.error);
173 EXPECT_EQ(1U, response.results_length);
174 EXPECT_EQ(KM_KEY_FORMAT_X509, response.results[0]);
175
176 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
177 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
178}
179
180typedef KeymasterTest NewKeyGeneration;
181TEST_F(NewKeyGeneration, Rsa) {
182 keymaster_key_param_t params[] = {
183 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
184 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
185 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
Shawn Willden76364712014-08-11 17:48:04 -0600186 Authorization(TAG_KEY_SIZE, 256),
Shawn Willden128ffe02014-08-06 12:31:33 -0600187 Authorization(TAG_USER_ID, 7),
188 Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willden76364712014-08-11 17:48:04 -0600189 Authorization(TAG_APPLICATION_ID, "app_id", 6),
190 Authorization(TAG_APPLICATION_DATA, "app_data", 8),
Shawn Willden128ffe02014-08-06 12:31:33 -0600191 Authorization(TAG_AUTH_TIMEOUT, 300),
192 };
193 GenerateKeyRequest req;
194 req.key_description.Reinitialize(params, array_length(params));
195 GenerateKeyResponse rsp;
196
197 device.GenerateKey(req, &rsp);
198
199 ASSERT_EQ(KM_ERROR_OK, rsp.error);
200 EXPECT_EQ(0U, rsp.enforced.size());
Shawn Willden8d336ae2014-08-09 15:47:05 -0600201 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
202 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
Shawn Willden128ffe02014-08-06 12:31:33 -0600203
204 // Check specified tags are all present in unenforced characteristics
205 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
206 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
207
208 EXPECT_TRUE(contains(rsp.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
209
210 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
211 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
Shawn Willden76364712014-08-11 17:48:04 -0600212 EXPECT_TRUE(contains(rsp.unenforced, TAG_KEY_SIZE, 256));
Shawn Willden128ffe02014-08-06 12:31:33 -0600213 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
214
Shawn Willden39b970b2014-08-11 09:11:21 -0600215 // Verify that App ID, App data and ROT are NOT included.
216 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
217 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
218 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
219
Shawn Willden128ffe02014-08-06 12:31:33 -0600220 // Just for giggles, check that some unexpected tags/values are NOT present.
221 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
222 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
223 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
224 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
225
226 // Now check that unspecified, defaulted tags are correct.
227 EXPECT_TRUE(contains(rsp.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
228 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
229 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
Shawn Willden128ffe02014-08-06 12:31:33 -0600230}
231
Shawn Willden76364712014-08-11 17:48:04 -0600232typedef KeymasterTest GetKeyCharacteristics;
233TEST_F(GetKeyCharacteristics, SimpleRsa) {
234 keymaster_key_param_t params[] = {
235 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
236 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
237 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
238 Authorization(TAG_KEY_SIZE, 256),
239 Authorization(TAG_USER_ID, 7),
240 Authorization(TAG_USER_AUTH_ID, 8),
241 Authorization(TAG_APPLICATION_ID, reinterpret_cast<const uint8_t*>("app_id"), 6),
242 Authorization(TAG_AUTH_TIMEOUT, 300),
243 };
244
245 GenerateKeyRequest gen_req;
246 gen_req.key_description.Reinitialize(params, array_length(params));
247 GenerateKeyResponse gen_rsp;
248
249 device.GenerateKey(gen_req, &gen_rsp);
250
251 GetKeyCharacteristicsRequest req;
252 req.key_blob = gen_rsp.key_blob;
253 req.client_id.data = reinterpret_cast<const uint8_t*>("app_id");
254 req.client_id.data_length = 6;
255 req.app_data.data = NULL;
256 req.app_data.data_length = 0;
257
258 GetKeyCharacteristicsResponse rsp;
259 device.GetKeyCharacteristics(req, &rsp);
260 ASSERT_EQ(KM_ERROR_OK, rsp.error);
261
262 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
263 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
264}
265
Shawn Willden128ffe02014-08-06 12:31:33 -0600266} // namespace test
267} // namespace keymaster