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