blob: 1a53172703d528b8537c3563ac447c00bcef109e [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>
18#include <openssl/engine.h>
19
20#define KEYMASTER_NAME_TAGS
21#include "keymaster_tags.h"
22#include "google_keymaster_utils.h"
23#include "google_softkeymaster.h"
24
25int main(int argc, char** argv) {
26 ::testing::InitGoogleTest(&argc, argv);
27 int result = RUN_ALL_TESTS();
28 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
29 CRYPTO_cleanup_all_ex_data();
30 ERR_free_strings();
31 return result;
32}
33
34namespace keymaster {
35namespace test {
36
37class KeymasterTest : public testing::Test {
38 protected:
39 KeymasterTest() {
40 }
41 ~KeymasterTest() {
42 }
43
44 GoogleSoftKeymaster device;
45};
46
47template <keymaster_tag_t Tag, typename KeymasterEnum>
48bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
49 KeymasterEnum val) {
50 int pos = set.find(tag);
51 return pos != -1 && set[pos].enumerated == val;
52}
53
54template <keymaster_tag_t Tag, typename KeymasterEnum>
55bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
56 KeymasterEnum val) {
57 int pos = -1;
58 while ((pos = set.find(tag, pos)) != -1)
59 if (set[pos].enumerated == val)
60 return true;
61 return false;
62}
63
64template <keymaster_tag_t Tag>
65bool contains(const AuthorizationSet& set, TypedTag<KM_INT, Tag> tag, uint32_t val) {
66 int pos = set.find(tag);
67 return pos != -1 && set[pos].integer == val;
68}
69
70template <keymaster_tag_t Tag>
71bool contains(const AuthorizationSet& set, TypedTag<KM_INT_REP, Tag> tag, uint32_t val) {
72 int pos = -1;
73 while ((pos = set.find(tag, pos)) != -1)
74 if (set[pos].integer == val)
75 return true;
76 return false;
77}
78
79template <keymaster_tag_t Tag>
80bool contains(const AuthorizationSet& set, TypedTag<KM_LONG, Tag> tag, uint64_t val) {
81 int pos = set.find(tag);
82 return pos != -1 && set[pos].long_integer == val;
83}
84
85template <keymaster_tag_t Tag>
86bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
87 int pos = set.find(tag);
88 return pos != -1 &&
89 std::string(reinterpret_cast<const char*>(set[pos].blob.data),
90 set[pos].blob.data_length) == val;
91}
92
93inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) {
94 return set.find(tag) != -1;
95}
96
97typedef KeymasterTest CheckSupported;
98TEST_F(CheckSupported, SupportedAlgorithms) {
99 // Shouldn't blow up on NULL.
100 device.SupportedAlgorithms(NULL);
101
102 SupportedResponse<keymaster_algorithm_t> response;
103 device.SupportedAlgorithms(&response);
104 EXPECT_EQ(KM_ERROR_OK, response.error);
105 EXPECT_EQ(1U, response.results_length);
106 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
107}
108
109TEST_F(CheckSupported, SupportedBlockModes) {
110 // Shouldn't blow up on NULL.
111 device.SupportedBlockModes(KM_ALGORITHM_RSA, NULL);
112
113 SupportedResponse<keymaster_block_mode_t> response;
114 device.SupportedBlockModes(KM_ALGORITHM_RSA, &response);
115 EXPECT_EQ(KM_ERROR_OK, response.error);
116 EXPECT_EQ(0U, response.results_length);
117
118 device.SupportedBlockModes(KM_ALGORITHM_DSA, &response);
119 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
120}
121
122TEST_F(CheckSupported, SupportedPaddingModes) {
123 // Shouldn't blow up on NULL.
124 device.SupportedPaddingModes(KM_ALGORITHM_RSA, NULL);
125
126 SupportedResponse<keymaster_padding_t> response;
127 device.SupportedPaddingModes(KM_ALGORITHM_RSA, &response);
128 EXPECT_EQ(KM_ERROR_OK, response.error);
129 EXPECT_EQ(1U, response.results_length);
130 EXPECT_EQ(KM_PAD_NONE, response.results[0]);
131
132 device.SupportedPaddingModes(KM_ALGORITHM_DSA, &response);
133 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
134}
135
136TEST_F(CheckSupported, SupportedDigests) {
137 // Shouldn't blow up on NULL.
138 device.SupportedDigests(KM_ALGORITHM_RSA, NULL);
139
140 SupportedResponse<keymaster_digest_t> response;
141 device.SupportedDigests(KM_ALGORITHM_RSA, &response);
142 EXPECT_EQ(KM_ERROR_OK, response.error);
143 EXPECT_EQ(1U, response.results_length);
144 EXPECT_EQ(KM_DIGEST_NONE, response.results[0]);
145
146 device.SupportedDigests(KM_ALGORITHM_DSA, &response);
147 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
148}
149
150TEST_F(CheckSupported, SupportedImportFormats) {
151 // Shouldn't blow up on NULL.
152 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
153
154 SupportedResponse<keymaster_key_format_t> response;
155 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
156 EXPECT_EQ(KM_ERROR_OK, response.error);
157 EXPECT_EQ(1U, response.results_length);
158 EXPECT_EQ(KM_KEY_FORMAT_PKCS8, response.results[0]);
159
160 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
161 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
162}
163
164TEST_F(CheckSupported, SupportedExportFormats) {
165 // Shouldn't blow up on NULL.
166 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
167
168 SupportedResponse<keymaster_key_format_t> response;
169 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
170 EXPECT_EQ(KM_ERROR_OK, response.error);
171 EXPECT_EQ(1U, response.results_length);
172 EXPECT_EQ(KM_KEY_FORMAT_X509, response.results[0]);
173
174 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
175 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
176}
177
178typedef KeymasterTest NewKeyGeneration;
179TEST_F(NewKeyGeneration, Rsa) {
180 keymaster_key_param_t params[] = {
181 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
182 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
183 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
184 Authorization(TAG_USER_ID, 7),
185 Authorization(TAG_USER_AUTH_ID, 8),
186 Authorization(TAG_APPLICATION_ID, reinterpret_cast<const uint8_t*>("app_id"), 6),
187 Authorization(TAG_AUTH_TIMEOUT, 300),
188 };
189 GenerateKeyRequest req;
190 req.key_description.Reinitialize(params, array_length(params));
191 GenerateKeyResponse rsp;
192
193 device.GenerateKey(req, &rsp);
194
195 ASSERT_EQ(KM_ERROR_OK, rsp.error);
196 EXPECT_EQ(0U, rsp.enforced.size());
Shawn Willden8d336ae2014-08-09 15:47:05 -0600197 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
198 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
Shawn Willden128ffe02014-08-06 12:31:33 -0600199
200 // Check specified tags are all present in unenforced characteristics
201 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
202 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
203
204 EXPECT_TRUE(contains(rsp.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
205
206 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
207 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
208 EXPECT_TRUE(contains(rsp.unenforced, TAG_APPLICATION_ID, "app_id"));
209 EXPECT_TRUE(contains(rsp.unenforced, TAG_KEY_SIZE, 2048));
210 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
211
212 // Just for giggles, check that some unexpected tags/values are NOT present.
213 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
214 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
215 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
216 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
217
218 // Now check that unspecified, defaulted tags are correct.
219 EXPECT_TRUE(contains(rsp.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
220 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
221 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
222 EXPECT_TRUE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST, "SW"));
223}
224
225} // namespace test
226} // namespace keymaster