blob: 199b523beec901263027c2083c5796906fa80567 [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
Shawn Willden437fbd12014-08-20 11:59:49 -060017#include <string>
18#include <fstream>
19
Shawn Willden128ffe02014-08-06 12:31:33 -060020#include <gtest/gtest.h>
Shawn Willden76364712014-08-11 17:48:04 -060021
Shawn Willden128ffe02014-08-06 12:31:33 -060022#include <openssl/engine.h>
23
Shawn Willden98d9b922014-08-26 08:14:10 -060024#include <keymaster/google_keymaster_utils.h>
25#include <keymaster/keymaster_tags.h>
26
Shawn Willden76364712014-08-11 17:48:04 -060027#include "google_keymaster_test_utils.h"
Brian Carlstromecf2ae92015-01-29 09:56:10 -080028#include "google_softkeymaster.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060029
Shawn Willden437fbd12014-08-20 11:59:49 -060030using std::string;
31using std::ifstream;
32using std::istreambuf_iterator;
33
Shawn Willden128ffe02014-08-06 12:31:33 -060034int main(int argc, char** argv) {
35 ::testing::InitGoogleTest(&argc, argv);
36 int result = RUN_ALL_TESTS();
37 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
38 CRYPTO_cleanup_all_ex_data();
Shawn Willden7c0a82b2014-09-17 12:57:32 -060039 ERR_remove_thread_state(NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -060040 ERR_free_strings();
41 return result;
42}
43
44namespace keymaster {
45namespace test {
46
Shawn Willden6bbe6782014-09-18 11:26:15 -060047// Note that these DSA generator, p and q values must match the values from dsa_privkey_pk8.der.
48const uint8_t dsa_g[] = {
49 0x19, 0x1C, 0x71, 0xFD, 0xE0, 0x03, 0x0C, 0x43, 0xD9, 0x0B, 0xF6, 0xCD, 0xD6, 0xA9, 0x70, 0xE7,
50 0x37, 0x86, 0x3A, 0x78, 0xE9, 0xA7, 0x47, 0xA7, 0x47, 0x06, 0x88, 0xB1, 0xAF, 0xD7, 0xF3, 0xF1,
51 0xA1, 0xD7, 0x00, 0x61, 0x28, 0x88, 0x31, 0x48, 0x60, 0xD8, 0x11, 0xEF, 0xA5, 0x24, 0x1A, 0x81,
52 0xC4, 0x2A, 0xE2, 0xEA, 0x0E, 0x36, 0xD2, 0xD2, 0x05, 0x84, 0x37, 0xCF, 0x32, 0x7D, 0x09, 0xE6,
53 0x0F, 0x8B, 0x0C, 0xC8, 0xC2, 0xA4, 0xB1, 0xDC, 0x80, 0xCA, 0x68, 0xDF, 0xAF, 0xD2, 0x90, 0xC0,
54 0x37, 0x58, 0x54, 0x36, 0x8F, 0x49, 0xB8, 0x62, 0x75, 0x8B, 0x48, 0x47, 0xC0, 0xBE, 0xF7, 0x9A,
55 0x92, 0xA6, 0x68, 0x05, 0xDA, 0x9D, 0xAF, 0x72, 0x9A, 0x67, 0xB3, 0xB4, 0x14, 0x03, 0xAE, 0x4F,
56 0x4C, 0x76, 0xB9, 0xD8, 0x64, 0x0A, 0xBA, 0x3B, 0xA8, 0x00, 0x60, 0x4D, 0xAE, 0x81, 0xC3, 0xC5,
57};
58const uint8_t dsa_p[] = {
59 0xA3, 0xF3, 0xE9, 0xB6, 0x7E, 0x7D, 0x88, 0xF6, 0xB7, 0xE5, 0xF5, 0x1F, 0x3B, 0xEE, 0xAC, 0xD7,
60 0xAD, 0xBC, 0xC9, 0xD1, 0x5A, 0xF8, 0x88, 0xC4, 0xEF, 0x6E, 0x3D, 0x74, 0x19, 0x74, 0xE7, 0xD8,
61 0xE0, 0x26, 0x44, 0x19, 0x86, 0xAF, 0x19, 0xDB, 0x05, 0xE9, 0x3B, 0x8B, 0x58, 0x58, 0xDE, 0xE5,
62 0x4F, 0x48, 0x15, 0x01, 0xEA, 0xE6, 0x83, 0x52, 0xD7, 0xC1, 0x21, 0xDF, 0xB9, 0xB8, 0x07, 0x66,
63 0x50, 0xFB, 0x3A, 0x0C, 0xB3, 0x85, 0xEE, 0xBB, 0x04, 0x5F, 0xC2, 0x6D, 0x6D, 0x95, 0xFA, 0x11,
64 0x93, 0x1E, 0x59, 0x5B, 0xB1, 0x45, 0x8D, 0xE0, 0x3D, 0x73, 0xAA, 0xF2, 0x41, 0x14, 0x51, 0x07,
65 0x72, 0x3D, 0xA2, 0xF7, 0x58, 0xCD, 0x11, 0xA1, 0x32, 0xCF, 0xDA, 0x42, 0xB7, 0xCC, 0x32, 0x80,
66 0xDB, 0x87, 0x82, 0xEC, 0x42, 0xDB, 0x5A, 0x55, 0x24, 0x24, 0xA2, 0xD1, 0x55, 0x29, 0xAD, 0xEB,
67};
68const uint8_t dsa_q[] = {
69 0xEB, 0xEA, 0x17, 0xD2, 0x09, 0xB3, 0xD7, 0x21, 0x9A, 0x21,
70 0x07, 0x82, 0x8F, 0xAB, 0xFE, 0x88, 0x71, 0x68, 0xF7, 0xE3,
71};
72
Shawn Willden128ffe02014-08-06 12:31:33 -060073class KeymasterTest : public testing::Test {
74 protected:
Brian Carlstromecf2ae92015-01-29 09:56:10 -080075 KeymasterTest() : device(5, new StdoutLogger) { RAND_seed("foobar", 6); }
76 ~KeymasterTest() {}
77
78 template <typename T> void ExpectEmptyResponse(const SupportedResponse<T>& response) {
79 EXPECT_EQ(KM_ERROR_OK, response.error);
80 EXPECT_EQ(0U, response.results_length);
Shawn Willdend0772312014-09-18 12:27:57 -060081 }
82
Brian Carlstromecf2ae92015-01-29 09:56:10 -080083 template <typename T> void ExpectResponseContains(T val, const SupportedResponse<T>& response) {
84 EXPECT_EQ(KM_ERROR_OK, response.error);
85 EXPECT_EQ(1U, response.results_length);
86 EXPECT_EQ(val, response.results[0]);
Shawn Willdend0772312014-09-18 12:27:57 -060087 }
88
Brian Carlstromecf2ae92015-01-29 09:56:10 -080089 GoogleSoftKeymaster device;
Shawn Willden128ffe02014-08-06 12:31:33 -060090};
91
Shawn Willden128ffe02014-08-06 12:31:33 -060092typedef KeymasterTest CheckSupported;
93TEST_F(CheckSupported, SupportedAlgorithms) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -080094 // Shouldn't blow up on NULL.
95 device.SupportedAlgorithms(NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -060096
Brian Carlstromecf2ae92015-01-29 09:56:10 -080097 SupportedResponse<keymaster_algorithm_t> response;
98 device.SupportedAlgorithms(&response);
99 EXPECT_EQ(KM_ERROR_OK, response.error);
100 EXPECT_EQ(4U, response.results_length);
101 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
102 EXPECT_EQ(KM_ALGORITHM_DSA, response.results[1]);
103 EXPECT_EQ(KM_ALGORITHM_ECDSA, response.results[2]);
104 EXPECT_EQ(KM_ALGORITHM_AES, response.results[3]);
Shawn Willden128ffe02014-08-06 12:31:33 -0600105}
106
107TEST_F(CheckSupported, SupportedBlockModes) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800108 // Shouldn't blow up on NULL.
109 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600110
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800111 SupportedResponse<keymaster_block_mode_t> response;
112 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, &response);
113 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600114
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800115 device.SupportedBlockModes(KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT, &response);
116 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden28e41472014-08-18 13:35:22 -0600117
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800118 device.SupportedBlockModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT, &response);
119 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600120
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800121 device.SupportedBlockModes(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, &response);
122 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600123}
124
125TEST_F(CheckSupported, SupportedPaddingModes) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800126 // Shouldn't blow up on NULL.
127 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600128
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800129 SupportedResponse<keymaster_padding_t> response;
130 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
131 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600132
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800133 device.SupportedPaddingModes(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
134 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600135
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800136 device.SupportedPaddingModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
137 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600138
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800139 device.SupportedPaddingModes(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
140 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600141}
142
143TEST_F(CheckSupported, SupportedDigests) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800144 // Shouldn't blow up on NULL.
145 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600146
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800147 SupportedResponse<keymaster_digest_t> response;
148 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
149 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600150
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800151 device.SupportedDigests(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
152 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600153
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800154 device.SupportedDigests(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
155 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600156
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800157 device.SupportedDigests(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
158 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600159}
160
161TEST_F(CheckSupported, SupportedImportFormats) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800162 // Shouldn't blow up on NULL.
163 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600164
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800165 SupportedResponse<keymaster_key_format_t> response;
166 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
167 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600168
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800169 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
170 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600171
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800172 device.SupportedImportFormats(KM_ALGORITHM_ECDSA, &response);
173 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600174
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800175 device.SupportedImportFormats(KM_ALGORITHM_AES, &response);
176 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600177}
178
179TEST_F(CheckSupported, SupportedExportFormats) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800180 // Shouldn't blow up on NULL.
181 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600182
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800183 SupportedResponse<keymaster_key_format_t> response;
184 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
185 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600186
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800187 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
188 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600189
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800190 device.SupportedExportFormats(KM_ALGORITHM_ECDSA, &response);
191 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600192
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800193 device.SupportedExportFormats(KM_ALGORITHM_AES, &response);
194 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600195}
196
Shawn Willdend0772312014-09-18 12:27:57 -0600197keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700198 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
199 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600200 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700201 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600202};
203
204class NewKeyGeneration : public KeymasterTest {
205 protected:
206 NewKeyGeneration() {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800207 req_.key_description.Reinitialize(key_generation_base_params,
208 array_length(key_generation_base_params));
Shawn Willdend0772312014-09-18 12:27:57 -0600209 }
210
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800211 void CheckBaseParams(const GenerateKeyResponse& rsp) {
212 ASSERT_EQ(KM_ERROR_OK, rsp.error);
213 EXPECT_EQ(0U, rsp.enforced.size());
214 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
215 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
216
217 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
218 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
219 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
220 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
221 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600222
223 // Verify that App ID, App data and ROT are NOT included.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800224 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
225 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
226 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600227
228 // Just for giggles, check that some unexpected tags/values are NOT present.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800229 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
230 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
231 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600232
233 // Now check that unspecified, defaulted tags are correct.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800234 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
235 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600236 }
Shawn Willdend0772312014-09-18 12:27:57 -0600237
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800238 GenerateKeyRequest req_;
239 GenerateKeyResponse rsp_;
Shawn Willden2079ae82015-01-22 13:42:31 -0700240};
241
Shawn Willden128ffe02014-08-06 12:31:33 -0600242TEST_F(NewKeyGeneration, Rsa) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800243 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
244 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
245 req_.key_description.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
246 device.GenerateKey(req_, &rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600247
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800248 CheckBaseParams(rsp_);
249
250 // Check specified tags are all present in unenforced characteristics
251 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
252 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
253 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600254}
255
Shawn Willden6bbe6782014-09-18 11:26:15 -0600256TEST_F(NewKeyGeneration, RsaDefaultSize) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800257 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
258 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600259
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800260 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600261
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800262 // Check specified tags are all present in unenforced characteristics
263 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600264
265 // Now check that unspecified, defaulted tags are correct.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800266 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
267 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600268}
269
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600270TEST_F(NewKeyGeneration, Ecdsa) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800271 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
272 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 224));
273 device.GenerateKey(req_, &rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600274
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800275 CheckBaseParams(rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600276
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800277 // Check specified tags are all present in unenforced characteristics
278 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
279 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600280}
281
Shawn Willden6bbe6782014-09-18 11:26:15 -0600282TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800283 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
284 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600285
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800286 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600287
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800288 // Check specified tags are all present in unenforced characteristics
289 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600290
291 // Now check that unspecified, defaulted tags are correct.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800292 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600293}
294
295TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800296 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
297 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 190));
298 device.GenerateKey(req_, &rsp_);
299 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600300}
301
302TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600303 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600304 for (size_t size : valid_sizes) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800305 GenerateKeyResponse rsp;
306 req_.key_description.Reinitialize(key_generation_base_params,
307 array_length(key_generation_base_params));
308 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
309 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
310 device.GenerateKey(req_, &rsp);
311 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600312 }
313}
314
Shawn Willden19fca882015-01-22 16:35:30 -0700315TEST_F(NewKeyGeneration, AesOcb) {
316 keymaster_key_param_t params[] = {
317 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
318 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
319 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
320 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700321 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700322 };
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800323 req_.key_description.Reinitialize(params, array_length(params));
324 device.GenerateKey(req_, &rsp_);
325 EXPECT_EQ(KM_ERROR_OK, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700326}
327
328TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
329 keymaster_key_param_t params[] = {
330 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
331 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
332 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 129),
333 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700334 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700335 };
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800336 req_.key_description.Reinitialize(params, array_length(params));
337 device.GenerateKey(req_, &rsp_);
338 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700339}
340
341TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
342 keymaster_key_param_t params[] = {
343 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
344 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden7efb8782014-12-11 14:07:44 -0700345 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
346 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700347 Authorization(TAG_PADDING, KM_PAD_NONE),
348 };
349
350 size_t valid_sizes[] = {128, 192, 256};
351 for (size_t size : valid_sizes) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800352 GenerateKeyResponse rsp;
353 req_.key_description.Reinitialize(params, array_length(params));
354 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
355 device.GenerateKey(req_, &rsp);
356 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700357 }
358}
359
360TEST_F(NewKeyGeneration, AesOcbNoChunkLength) {
361 keymaster_key_param_t params[] = {
362 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
363 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
364 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
365 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_PADDING, KM_PAD_NONE),
366 };
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800367 req_.key_description.Reinitialize(params, array_length(params));
368 device.GenerateKey(req_, &rsp_);
369 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700370}
371
372TEST_F(NewKeyGeneration, AesEcbUnsupported) {
373 keymaster_key_param_t params[] = {
374 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
375 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
376 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
377 Authorization(TAG_BLOCK_MODE, KM_MODE_ECB), Authorization(TAG_PADDING, KM_PAD_NONE),
378 };
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800379 req_.key_description.Reinitialize(params, array_length(params));
380 device.GenerateKey(req_, &rsp_);
381 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700382}
383
384TEST_F(NewKeyGeneration, AesOcbPaddingUnsupported) {
385 keymaster_key_param_t params[] = {
386 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
387 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
388 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
389 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
390 Authorization(TAG_PADDING, KM_PAD_ZERO),
391 };
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800392 req_.key_description.Reinitialize(params, array_length(params));
393 device.GenerateKey(req_, &rsp_);
394 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700395}
396
Shawn Willden7efb8782014-12-11 14:07:44 -0700397TEST_F(NewKeyGeneration, AesOcbInvalidMacLength) {
398 keymaster_key_param_t params[] = {
399 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
400 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
401 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
402 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
403 Authorization(TAG_MAC_LENGTH, 17), Authorization(TAG_PADDING, KM_PAD_NONE),
404 };
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800405 req_.key_description.Reinitialize(params, array_length(params));
406 device.GenerateKey(req_, &rsp_);
407 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, rsp_.error);
Shawn Willden7efb8782014-12-11 14:07:44 -0700408}
409
Shawn Willden76364712014-08-11 17:48:04 -0600410typedef KeymasterTest GetKeyCharacteristics;
411TEST_F(GetKeyCharacteristics, SimpleRsa) {
412 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700413 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
414 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
415 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
416 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600417 };
418
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800419 GenerateKeyRequest gen_req;
420 gen_req.key_description.Reinitialize(params, array_length(params));
421 GenerateKeyResponse gen_rsp;
Shawn Willden76364712014-08-11 17:48:04 -0600422
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800423 device.GenerateKey(gen_req, &gen_rsp);
424 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
425
426 GetKeyCharacteristicsRequest req;
427 req.SetKeyMaterial(gen_rsp.key_blob);
428 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
429
430 GetKeyCharacteristicsResponse rsp;
431 device.GetKeyCharacteristics(req, &rsp);
432 ASSERT_EQ(KM_ERROR_OK, rsp.error);
433
434 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
435 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
Shawn Willden76364712014-08-11 17:48:04 -0600436}
437
Shawn Willden61644f32014-08-18 13:43:14 -0600438/**
439 * Test class that provides some infrastructure for generating keys and signing messages.
440 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600441class SigningOperationsTest : public KeymasterTest {
442 protected:
Shawn Willden61644f32014-08-18 13:43:14 -0600443 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
444 keymaster_padding_t padding, uint32_t key_size) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800445 keymaster_key_param_t params[] = {
446 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
447 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), Authorization(TAG_ALGORITHM, algorithm),
448 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
449 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
450 Authorization(TAG_AUTH_TIMEOUT, 300),
451 };
452 GenerateKeyRequest generate_request;
453 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600454 if (static_cast<int>(digest) != -1)
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800455 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600456 if (static_cast<int>(padding) != -1)
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800457 generate_request.key_description.push_back(TAG_PADDING, padding);
458 device.GenerateKey(generate_request, &generate_response_);
459 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden61644f32014-08-18 13:43:14 -0600460 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600461
Shawn Willden61644f32014-08-18 13:43:14 -0600462 void SignMessage(const void* message, size_t size) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800463 SignMessage(generate_response_.key_blob, message, size);
Shawn Willden437fbd12014-08-20 11:59:49 -0600464 }
465
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800466 void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
467 BeginOperationRequest begin_request;
468 BeginOperationResponse begin_response;
469 begin_request.SetKeyMaterial(key_blob);
470 begin_request.purpose = KM_PURPOSE_SIGN;
471 AddClientParams(&begin_request.additional_params);
472
473 device.BeginOperation(begin_request, &begin_response);
474 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
475
476 UpdateOperationRequest update_request;
477 UpdateOperationResponse update_response;
478 update_request.op_handle = begin_response.op_handle;
479 update_request.input.Reinitialize(message, size);
480 EXPECT_EQ(size, update_request.input.available_read());
481
482 device.UpdateOperation(update_request, &update_response);
483 ASSERT_EQ(KM_ERROR_OK, update_response.error);
484 EXPECT_EQ(0U, update_response.output.available_read());
485 EXPECT_EQ(size, update_response.input_consumed);
486
487 FinishOperationRequest finish_request;
488 finish_request.op_handle = begin_response.op_handle;
489 device.FinishOperation(finish_request, &finish_response_);
490 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
491 EXPECT_GT(finish_response_.output.available_read(), 0U);
Shawn Willden61644f32014-08-18 13:43:14 -0600492 }
493
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800494 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
495
496 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
497
498 const keymaster_key_blob_t& corrupt_key_blob() {
499 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
500 ++tmp[generate_response_.key_blob.key_material_size / 2];
501 return generate_response_.key_blob;
Shawn Willdenf268d742014-08-19 15:36:26 -0600502 }
503
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800504 Buffer* signature() {
505 if (finish_response_.error == KM_ERROR_OK)
506 return &finish_response_.output;
507 return NULL;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600508 }
509
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800510 GenerateKeyResponse generate_response_;
511 FinishOperationResponse finish_response_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600512};
513
514TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600515 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600516 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600517 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600518}
519
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600520TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600521 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600522 const char message[] = "123456789012345678901234567890123456789012345678";
523 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600524}
525
Shawn Willden1615f2e2014-08-13 10:37:40 -0600526TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600527 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600528
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800529 BeginOperationRequest begin_request;
530 BeginOperationResponse begin_response;
531 begin_request.SetKeyMaterial(key_blob());
532 begin_request.purpose = KM_PURPOSE_SIGN;
533 AddClientParams(&begin_request.additional_params);
534
535 device.BeginOperation(begin_request, &begin_response);
536 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
537
538 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
539
540 // Another abort should fail
541 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600542}
543
544TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600545 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800546
547 BeginOperationRequest begin_request;
548 BeginOperationResponse begin_response;
549 begin_request.purpose = KM_PURPOSE_SIGN;
550 begin_request.SetKeyMaterial(key_blob());
551 AddClientParams(&begin_request.additional_params);
552
553 device.BeginOperation(begin_request, &begin_response);
554 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
555
556 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600557}
558
559TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600560 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800561
562 BeginOperationRequest begin_request;
563 BeginOperationResponse begin_response;
564 begin_request.purpose = KM_PURPOSE_SIGN;
565 begin_request.SetKeyMaterial(key_blob());
566 AddClientParams(&begin_request.additional_params);
567
568 device.BeginOperation(begin_request, &begin_response);
569 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
570
571 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600572}
573
574TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600575 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
576 256 /* key size */);
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800577
578 BeginOperationRequest begin_request;
579 BeginOperationResponse begin_response;
580 begin_request.purpose = KM_PURPOSE_SIGN;
581 begin_request.SetKeyMaterial(key_blob());
582 AddClientParams(&begin_request.additional_params);
583
584 device.BeginOperation(begin_request, &begin_response);
585 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
586
587 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600588}
589
590TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600591 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
592 256 /* key size */);
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800593
594 BeginOperationRequest begin_request;
595 BeginOperationResponse begin_response;
596 begin_request.purpose = KM_PURPOSE_SIGN;
597 begin_request.SetKeyMaterial(key_blob());
598 AddClientParams(&begin_request.additional_params);
599
600 device.BeginOperation(begin_request, &begin_response);
601 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
602
603 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600604}
605
606TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600607 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600608
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800609 BeginOperationRequest begin_request;
610 BeginOperationResponse begin_response;
611 begin_request.SetKeyMaterial(key_blob());
612 begin_request.purpose = KM_PURPOSE_SIGN;
613 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600614
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800615 device.BeginOperation(begin_request, &begin_response);
616 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
617
618 UpdateOperationRequest update_request;
619 UpdateOperationResponse update_response;
620 update_request.op_handle = begin_response.op_handle;
621 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
622 EXPECT_EQ(31U, update_request.input.available_read());
623
624 device.UpdateOperation(update_request, &update_response);
625 ASSERT_EQ(KM_ERROR_OK, update_response.error);
626 EXPECT_EQ(0U, update_response.output.available_read());
627 EXPECT_EQ(31U, update_response.input_consumed);
628
629 FinishOperationRequest finish_request;
630 finish_request.op_handle = begin_response.op_handle;
631 FinishOperationResponse finish_response;
632 device.FinishOperation(finish_request, &finish_response);
633 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, finish_response.error);
634 EXPECT_EQ(0U, finish_response.output.available_read());
635
636 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
Shawn Willden43e999e2014-08-13 13:29:50 -0600637}
638
Shawn Willdend05cba52014-09-26 09:58:12 -0600639class VerificationOperationsTest : public SigningOperationsTest {
640 protected:
641 void VerifyMessage(const void* message, size_t message_len) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800642 VerifyMessage(generate_response_.key_blob, message, message_len);
643 }
Shawn Willdend05cba52014-09-26 09:58:12 -0600644
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800645 void VerifyMessage(const keymaster_key_blob_t& key_blob, const void* message,
646 size_t message_len) {
647 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600648
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800649 BeginOperationRequest begin_request;
650 BeginOperationResponse begin_response;
651 begin_request.SetKeyMaterial(key_blob);
652 begin_request.purpose = KM_PURPOSE_VERIFY;
653 AddClientParams(&begin_request.additional_params);
Shawn Willdend05cba52014-09-26 09:58:12 -0600654
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800655 device.BeginOperation(begin_request, &begin_response);
656 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
657
658 UpdateOperationRequest update_request;
659 UpdateOperationResponse update_response;
660 update_request.op_handle = begin_response.op_handle;
661 update_request.input.Reinitialize(message, message_len);
662 EXPECT_EQ(message_len, update_request.input.available_read());
663
664 device.UpdateOperation(update_request, &update_response);
665 ASSERT_EQ(KM_ERROR_OK, update_response.error);
666 EXPECT_EQ(0U, update_response.output.available_read());
667 EXPECT_EQ(message_len, update_response.input_consumed);
668
669 FinishOperationRequest finish_request;
670 finish_request.op_handle = begin_response.op_handle;
671 finish_request.signature.Reinitialize(*signature());
672 FinishOperationResponse finish_response;
673 device.FinishOperation(finish_request, &finish_response);
674 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
675 EXPECT_EQ(0U, finish_response.output.available_read());
676
677 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE,
678 device.AbortOperation(begin_response.op_handle));
Shawn Willdend05cba52014-09-26 09:58:12 -0600679 }
680};
681
Shawn Willden43e999e2014-08-13 13:29:50 -0600682TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600683 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
684 const char message[] = "12345678901234567890123456789012";
685 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600686 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600687}
688
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600689TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600690 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600691 const char message[] = "123456789012345678901234567890123456789012345678";
692 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600693 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600694}
695
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800696typedef SigningOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600697TEST_F(ExportKeyTest, RsaSuccess) {
698 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600699
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800700 ExportKeyRequest request;
701 ExportKeyResponse response;
702 AddClientParams(&request.additional_params);
703 request.key_format = KM_KEY_FORMAT_X509;
704 request.SetKeyMaterial(key_blob());
705
706 device.ExportKey(request, &response);
707 ASSERT_EQ(KM_ERROR_OK, response.error);
708 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600709
710 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600711}
712
Shawn Willdenf268d742014-08-19 15:36:26 -0600713TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600714 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600715
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800716 ExportKeyRequest request;
717 ExportKeyResponse response;
718 AddClientParams(&request.additional_params);
719 request.key_format = KM_KEY_FORMAT_X509;
720 request.SetKeyMaterial(key_blob());
721
722 device.ExportKey(request, &response);
723 ASSERT_EQ(KM_ERROR_OK, response.error);
724 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600725
726 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600727}
728
729TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
730 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
731
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800732 ExportKeyRequest request;
733 ExportKeyResponse response;
734 AddClientParams(&request.additional_params);
735
736 /* We have no other defined export formats defined. */
737 request.key_format = KM_KEY_FORMAT_PKCS8;
738 request.SetKeyMaterial(key_blob());
739
740 device.ExportKey(request, &response);
741 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, response.error);
742 EXPECT_TRUE(response.key_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600743}
744
745TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
746 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
747
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800748 ExportKeyRequest request;
749 ExportKeyResponse response;
750 AddClientParams(&request.additional_params);
751 request.key_format = KM_KEY_FORMAT_X509;
752 request.SetKeyMaterial(corrupt_key_blob());
753
754 device.ExportKey(request, &response);
755 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, response.error);
756 ASSERT_TRUE(response.key_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600757}
758
Shawn Willden437fbd12014-08-20 11:59:49 -0600759static string read_file(const string& file_name) {
760 ifstream file_stream(file_name, std::ios::binary);
761 istreambuf_iterator<char> file_begin(file_stream);
762 istreambuf_iterator<char> file_end;
763 return string(file_begin, file_end);
764}
765
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800766typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden2079ae82015-01-22 13:42:31 -0700767TEST_F(ImportKeyTest, RsaSuccess) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800768 keymaster_key_param_t params[] = {
769 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
770 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
771 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
772 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
773 };
774
Shawn Willden81effc62014-08-27 10:08:46 -0600775 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600776 ASSERT_EQ(633U, pk8_key.size());
777
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800778 ImportKeyRequest import_request;
779 import_request.key_description.Reinitialize(params, array_length(params));
780 import_request.key_format = KM_KEY_FORMAT_PKCS8;
781 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
782
783 ImportKeyResponse import_response;
784 device.ImportKey(import_request, &import_response);
785 ASSERT_EQ(KM_ERROR_OK, import_response.error);
786 EXPECT_EQ(0U, import_response.enforced.size());
787 EXPECT_GT(import_response.unenforced.size(), 0U);
Shawn Willden437fbd12014-08-20 11:59:49 -0600788
789 // Check values derived from the key.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800790 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
791 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
792 EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600793
794 // And values provided by GoogleKeymaster
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800795 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
796 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600797
798 size_t message_len = 1024 / 8;
799 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
800 std::fill(message.get(), message.get() + message_len, 'a');
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800801 SignMessage(import_response.key_blob, message.get(), message_len);
802 ASSERT_TRUE(signature() != NULL);
803 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600804}
805
Shawn Willden6bbe6782014-09-18 11:26:15 -0600806TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800807 keymaster_key_param_t params[] = {
808 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
809 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
810 Authorization(TAG_KEY_SIZE, 2048), // Doesn't match key
811 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
812 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
813 };
Shawn Willden6bbe6782014-09-18 11:26:15 -0600814
815 string pk8_key = read_file("rsa_privkey_pk8.der");
816 ASSERT_EQ(633U, pk8_key.size());
817
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800818 ImportKeyRequest import_request;
819 import_request.key_description.Reinitialize(params, array_length(params));
820 import_request.key_format = KM_KEY_FORMAT_PKCS8;
821 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
822
823 ImportKeyResponse import_response;
824 device.ImportKey(import_request, &import_response);
825 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600826}
827
828TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800829 keymaster_key_param_t params[] = {
830 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
831 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
832 Authorization(TAG_RSA_PUBLIC_EXPONENT, 3), Authorization(TAG_USER_ID, 7),
833 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
834 Authorization(TAG_AUTH_TIMEOUT, 300),
835 };
Shawn Willden6bbe6782014-09-18 11:26:15 -0600836
837 string pk8_key = read_file("rsa_privkey_pk8.der");
838 ASSERT_EQ(633U, pk8_key.size());
839
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800840 ImportKeyRequest import_request;
841 import_request.key_description.Reinitialize(params, array_length(params));
842 import_request.key_format = KM_KEY_FORMAT_PKCS8;
843 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
844
845 ImportKeyResponse import_response;
846 device.ImportKey(import_request, &import_response);
847 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600848}
849
Shawn Willden81effc62014-08-27 10:08:46 -0600850TEST_F(ImportKeyTest, EcdsaSuccess) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800851 keymaster_key_param_t params[] = {
852 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
853 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
854 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
855 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
856 };
857
Shawn Willden81effc62014-08-27 10:08:46 -0600858 string pk8_key = read_file("ec_privkey_pk8.der");
859 ASSERT_EQ(138U, pk8_key.size());
860
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800861 ImportKeyRequest import_request;
862 import_request.key_description.Reinitialize(params, array_length(params));
863 import_request.key_format = KM_KEY_FORMAT_PKCS8;
864 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
865
866 ImportKeyResponse import_response;
867 device.ImportKey(import_request, &import_response);
868 ASSERT_EQ(KM_ERROR_OK, import_response.error);
869 EXPECT_EQ(0U, import_response.enforced.size());
870 EXPECT_GT(import_response.unenforced.size(), 0U);
Shawn Willden81effc62014-08-27 10:08:46 -0600871
872 // Check values derived from the key.
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800873 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
874 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600875
876 // And values provided by GoogleKeymaster
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800877 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
878 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600879
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800880 size_t message_len = 1024 / 8;
Shawn Willden81effc62014-08-27 10:08:46 -0600881 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
882 std::fill(message.get(), message.get() + message_len, 'a');
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800883 SignMessage(import_response.key_blob, message.get(), message_len);
884 ASSERT_TRUE(signature() != NULL);
885 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600886}
887
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800888TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
889 keymaster_key_param_t params[] = {
890 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
891 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
892 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
893 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
894 Authorization(TAG_KEY_SIZE, 256),
895 };
Shawn Willden6bbe6782014-09-18 11:26:15 -0600896
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800897 string pk8_key = read_file("ec_privkey_pk8.der");
898 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600899
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800900 ImportKeyRequest import_request;
901 import_request.key_description.Reinitialize(params, array_length(params));
902 import_request.key_format = KM_KEY_FORMAT_PKCS8;
903 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
904
905 ImportKeyResponse import_response;
906 device.ImportKey(import_request, &import_response);
907 ASSERT_EQ(KM_ERROR_OK, import_response.error);
908 EXPECT_EQ(0U, import_response.enforced.size());
909 EXPECT_GT(import_response.unenforced.size(), 0U);
910
911 // Check values derived from the key.
912 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
913 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
914
915 // And values provided by GoogleKeymaster
916 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
917 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
918
919 size_t message_len = 1024 / 8;
920 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
921 std::fill(message.get(), message.get() + message_len, 'a');
922 SignMessage(import_response.key_blob, message.get(), message_len);
923 ASSERT_TRUE(signature() != NULL);
924 VerifyMessage(import_response.key_blob, message.get(), message_len);
925}
926
927TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
928 keymaster_key_param_t params[] = {
929 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
930 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
931 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
932 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
933 Authorization(TAG_KEY_SIZE, 224),
934 };
935
936 string pk8_key = read_file("ec_privkey_pk8.der");
937 ASSERT_EQ(138U, pk8_key.size());
938
939 ImportKeyRequest import_request;
940 import_request.key_description.Reinitialize(params, array_length(params));
941 import_request.key_format = KM_KEY_FORMAT_PKCS8;
942 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
943
944 ImportKeyResponse import_response;
945 device.ImportKey(import_request, &import_response);
946 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600947}
948
Shawn Willden2665e862014-11-24 14:46:21 -0700949typedef KeymasterTest VersionTest;
950TEST_F(VersionTest, GetVersion) {
951 GetVersionRequest req;
952 GetVersionResponse rsp;
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800953 device.GetVersion(req, &rsp);
Shawn Willden2665e862014-11-24 14:46:21 -0700954 EXPECT_EQ(KM_ERROR_OK, rsp.error);
955 EXPECT_EQ(1, rsp.major_ver);
956 EXPECT_EQ(0, rsp.minor_ver);
957 EXPECT_EQ(0, rsp.subminor_ver);
958}
959
Shawn Willden4200f212014-12-02 07:01:21 -0700960/**
961 * Test class that provides some infrastructure for generating keys and encrypting messages.
962 */
963class EncryptionOperationsTest : public KeymasterTest {
964 protected:
965 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
966 uint32_t key_size) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800967 keymaster_key_param_t params[] = {
968 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
969 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
970 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
971 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
972 Authorization(TAG_AUTH_TIMEOUT, 300),
973 };
974 GenerateKeyRequest generate_request;
975 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden4200f212014-12-02 07:01:21 -0700976 if (static_cast<int>(padding) != -1)
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800977 generate_request.key_description.push_back(TAG_PADDING, padding);
978 device.GenerateKey(generate_request, &generate_response_);
979 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden4200f212014-12-02 07:01:21 -0700980 }
981
Shawn Willden907c3012014-12-08 15:51:55 -0700982 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
983 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800984 keymaster_key_param_t params[] = {
985 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
986 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
987 Authorization(TAG_BLOCK_MODE, block_mode),
988 Authorization(TAG_CHUNK_LENGTH, chunk_length), Authorization(TAG_KEY_SIZE, key_size),
989 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_USER_ID, 7),
990 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
991 Authorization(TAG_AUTH_TIMEOUT, 300),
992 };
993 GenerateKeyRequest generate_request;
994 generate_request.key_description.Reinitialize(params, array_length(params));
995 device.GenerateKey(generate_request, &generate_response_);
996 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden907c3012014-12-08 15:51:55 -0700997 }
998
Shawn Willden4200f212014-12-02 07:01:21 -0700999 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
1000 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001001 BeginOperationRequest begin_request;
1002 begin_request.SetKeyMaterial(key_blob);
1003 begin_request.purpose = purpose;
1004 AddClientParams(&begin_request.additional_params);
1005
1006 BeginOperationResponse begin_response;
1007 device.BeginOperation(begin_request, &begin_response);
1008 *op_handle = begin_response.op_handle;
1009 return begin_response.error;
Shawn Willden4200f212014-12-02 07:01:21 -07001010 }
1011
1012 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willdenb7361132014-12-08 08:15:14 -07001013 string* output, size_t* input_consumed) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001014 UpdateOperationRequest update_request;
1015 update_request.op_handle = op_handle;
1016 update_request.input.Reinitialize(message, size);
1017
1018 UpdateOperationResponse update_response;
1019 device.UpdateOperation(update_request, &update_response);
1020 if (update_response.error == KM_ERROR_OK)
1021 output->append(reinterpret_cast<const char*>(update_response.output.peek_read()),
1022 update_response.output.available_read());
1023 *input_consumed = update_response.input_consumed;
1024 return update_response.error;
Shawn Willden4200f212014-12-02 07:01:21 -07001025 }
1026
1027 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001028 FinishOperationRequest finish_request;
1029 finish_request.op_handle = op_handle;
1030 FinishOperationResponse finish_response;
1031 device.FinishOperation(finish_request, &finish_response);
1032 if (finish_response.error == KM_ERROR_OK)
1033 output->append(reinterpret_cast<const char*>(finish_response.output.peek_read()),
1034 finish_response.output.available_read());
1035 return finish_response.error;
Shawn Willden4200f212014-12-02 07:01:21 -07001036 }
1037
1038 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1039 const void* message, size_t size) {
1040 uint64_t op_handle;
1041 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1042
1043 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001044 size_t input_consumed;
1045 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result, &input_consumed));
1046 EXPECT_EQ(size, input_consumed);
Shawn Willden4200f212014-12-02 07:01:21 -07001047 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
Shawn Willdenb7361132014-12-08 08:15:14 -07001048
Shawn Willden4200f212014-12-02 07:01:21 -07001049 return result;
1050 }
1051
1052 string EncryptMessage(const void* message, size_t size) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001053 return ProcessMessage(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, message, size);
Shawn Willden4200f212014-12-02 07:01:21 -07001054 }
1055
1056 string DecryptMessage(const void* ciphertext, size_t size) {
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001057 return ProcessMessage(KM_PURPOSE_DECRYPT, generate_response_.key_blob, ciphertext, size);
Shawn Willden4200f212014-12-02 07:01:21 -07001058 }
1059
1060 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1061
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001062 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
1063
1064 const keymaster_key_blob_t& corrupt_key_blob() {
1065 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
1066 ++tmp[generate_response_.key_blob.key_material_size / 2];
1067 return generate_response_.key_blob;
Shawn Willden4200f212014-12-02 07:01:21 -07001068 }
1069
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001070 protected:
1071 GenerateKeyResponse generate_response_;
Shawn Willden4200f212014-12-02 07:01:21 -07001072};
1073
1074TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1075 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1076 const char message[] = "Hello World!";
1077 string ciphertext1 = EncryptMessage(message, strlen(message));
1078 EXPECT_EQ(512 / 8, ciphertext1.size());
1079
1080 string ciphertext2 = EncryptMessage(message, strlen(message));
1081 EXPECT_EQ(512 / 8, ciphertext2.size());
1082
1083 // OAEP randomizes padding so every result should be different.
1084 EXPECT_NE(ciphertext1, ciphertext2);
1085}
1086
1087TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1088 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1089 const char message[] = "Hello World!";
1090 string ciphertext = EncryptMessage(message, strlen(message));
1091 EXPECT_EQ(512 / 8, ciphertext.size());
1092
1093 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1094 EXPECT_EQ(message, plaintext);
1095}
1096
1097TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1098 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1099 const char message[] = "12345678901234567890123";
1100 uint64_t op_handle;
1101 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001102 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001103
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001104 EXPECT_EQ(KM_ERROR_OK,
1105 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001106 EXPECT_EQ(KM_ERROR_OK,
1107 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001108 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1109 EXPECT_EQ(0, result.size());
1110}
1111
1112TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1113 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1114 const char message[] = "Hello World!";
1115 string ciphertext = EncryptMessage(message, strlen(message));
1116 EXPECT_EQ(512 / 8, ciphertext.size());
1117
1118 // Corrupt the ciphertext
1119 ciphertext[512 / 8 / 2]++;
1120
1121 uint64_t op_handle;
1122 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001123 size_t input_consumed;
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001124 EXPECT_EQ(KM_ERROR_OK,
1125 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001126 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1127 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001128 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1129 EXPECT_EQ(0, result.size());
1130}
1131
1132TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1133 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1134 const char message[] = "Hello World!";
1135 string ciphertext1 = EncryptMessage(message, strlen(message));
1136 EXPECT_EQ(512 / 8, ciphertext1.size());
1137
1138 string ciphertext2 = EncryptMessage(message, strlen(message));
1139 EXPECT_EQ(512 / 8, ciphertext2.size());
1140
1141 // PKCS1 v1.5 randomizes padding so every result should be different.
1142 EXPECT_NE(ciphertext1, ciphertext2);
1143}
1144
1145TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1146 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1147 const char message[] = "Hello World!";
1148 string ciphertext = EncryptMessage(message, strlen(message));
1149 EXPECT_EQ(512 / 8, ciphertext.size());
1150
1151 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1152 EXPECT_EQ(message, plaintext);
1153}
1154
1155TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1156 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1157 const char message[] = "1234567890123456789012345678901234567890123456789012";
1158 uint64_t op_handle;
1159 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001160 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001161
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001162 EXPECT_EQ(KM_ERROR_OK,
1163 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001164 EXPECT_EQ(KM_ERROR_OK,
1165 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001166 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1167 EXPECT_EQ(0, result.size());
1168}
1169
1170TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1171 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1172 const char message[] = "Hello World!";
1173 string ciphertext = EncryptMessage(message, strlen(message));
1174 EXPECT_EQ(512 / 8, ciphertext.size());
1175
1176 // Corrupt the ciphertext
1177 ciphertext[512 / 8 / 2]++;
1178
1179 uint64_t op_handle;
1180 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001181 size_t input_consumed;
Brian Carlstromecf2ae92015-01-29 09:56:10 -08001182 EXPECT_EQ(KM_ERROR_OK,
1183 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001184 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1185 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001186 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1187 EXPECT_EQ(0, result.size());
1188}
1189
Shawn Willden907c3012014-12-08 15:51:55 -07001190TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1191 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1192 const char message[] = "Hello World!";
1193 string ciphertext1 = EncryptMessage(message, strlen(message));
1194 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1195
1196 string ciphertext2 = EncryptMessage(message, strlen(message));
1197 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1198
1199 // OCB uses a random nonce, so every output should be different
1200 EXPECT_NE(ciphertext1, ciphertext2);
1201}
1202
Shawn Willden128ffe02014-08-06 12:31:33 -06001203} // namespace test
1204} // namespace keymaster