android_keymaster_messages_test.cpp revision 2665e868b1153cb89ad7cd906ae160cb417d4438
1/* 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 <UniquePtr.h> 18 19#include <gtest/gtest.h> 20 21#include <keymaster/keymaster_tags.h> 22#include <keymaster/google_keymaster_utils.h> 23 24#include "google_keymaster_test_utils.h" 25#include "google_softkeymaster.h" 26 27int main(int argc, char** argv) { 28 ::testing::InitGoogleTest(&argc, argv); 29 int result = RUN_ALL_TESTS(); 30 return result; 31} 32 33namespace keymaster { 34namespace test { 35 36/** 37 * Serialize and deserialize a message. 38 */ 39template <typename Message> 40Message* round_trip(int32_t ver, const Message& message, size_t expected_size) { 41 size_t size = message.SerializedSize(); 42 EXPECT_EQ(expected_size, size); 43 if (size == 0) 44 return NULL; 45 46 UniquePtr<uint8_t[]> buf(new uint8_t[size]); 47 EXPECT_EQ(buf.get() + size, message.Serialize(buf.get(), buf.get() + size)); 48 49 Message* deserialized = new Message(ver); 50 const uint8_t* p = buf.get(); 51 EXPECT_TRUE(deserialized->Deserialize(&p, p + size)); 52 EXPECT_EQ((ptrdiff_t)size, p - buf.get()); 53 return deserialized; 54} 55 56struct EmptyKeymasterResponse : public KeymasterResponse { 57 EmptyKeymasterResponse(int32_t ver) : KeymasterResponse(ver) {} 58 size_t NonErrorSerializedSize() const { return 1; } 59 uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* /* end */) const { 60 *buf++ = 0; 61 return buf; 62 } 63 bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) { 64 if (*buf_ptr >= end) 65 return false; 66 EXPECT_EQ(0, **buf_ptr); 67 (*buf_ptr)++; 68 return true; 69 } 70}; 71 72TEST(RoundTrip, EmptyKeymasterResponse) { 73 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 74 EmptyKeymasterResponse msg(ver); 75 msg.error = KM_ERROR_OK; 76 77 UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(ver, msg, 5)); 78 } 79} 80 81TEST(RoundTrip, EmptyKeymasterResponseError) { 82 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 83 EmptyKeymasterResponse msg(ver); 84 msg.error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 85 86 UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(ver, msg, 4)); 87 } 88} 89 90TEST(RoundTrip, SupportedAlgorithmsResponse) { 91 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 92 SupportedAlgorithmsResponse rsp(ver); 93 keymaster_algorithm_t algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, 94 KM_ALGORITHM_ECDSA}; 95 rsp.error = KM_ERROR_OK; 96 rsp.algorithms = dup_array(algorithms); 97 rsp.algorithms_length = array_length(algorithms); 98 99 UniquePtr<SupportedAlgorithmsResponse> deserialized(round_trip(ver, rsp, 20)); 100 EXPECT_EQ(array_length(algorithms), deserialized->algorithms_length); 101 EXPECT_EQ(0, memcmp(deserialized->algorithms, algorithms, array_size(algorithms))); 102 } 103} 104 105TEST(RoundTrip, SupportedResponse) { 106 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 107 SupportedResponse<keymaster_digest_t> rsp(ver); 108 keymaster_digest_t digests[] = {KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1}; 109 rsp.error = KM_ERROR_OK; 110 rsp.SetResults(digests); 111 112 UniquePtr<SupportedResponse<keymaster_digest_t>> deserialized(round_trip(ver, rsp, 20)); 113 EXPECT_EQ(array_length(digests), deserialized->results_length); 114 EXPECT_EQ(0, memcmp(deserialized->results, digests, array_size(digests))); 115 } 116} 117 118static keymaster_key_param_t params[] = { 119 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), 120 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_USER_ID, 7), 121 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6), 122 Authorization(TAG_AUTH_TIMEOUT, 300), 123}; 124uint8_t TEST_DATA[] = "a key blob"; 125 126TEST(RoundTrip, GenerateKeyRequest) { 127 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 128 GenerateKeyRequest req(ver); 129 req.key_description.Reinitialize(params, array_length(params)); 130 UniquePtr<GenerateKeyRequest> deserialized(round_trip(ver, req, 78)); 131 EXPECT_EQ(deserialized->key_description, req.key_description); 132 } 133} 134 135TEST(RoundTrip, GenerateKeyResponse) { 136 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 137 GenerateKeyResponse rsp(ver); 138 rsp.error = KM_ERROR_OK; 139 rsp.key_blob.key_material = dup_array(TEST_DATA); 140 rsp.key_blob.key_material_size = array_length(TEST_DATA); 141 rsp.enforced.Reinitialize(params, array_length(params)); 142 143 UniquePtr<GenerateKeyResponse> deserialized(round_trip(ver, rsp, 109)); 144 EXPECT_EQ(KM_ERROR_OK, deserialized->error); 145 EXPECT_EQ(deserialized->enforced, rsp.enforced); 146 EXPECT_EQ(deserialized->unenforced, rsp.unenforced); 147 } 148} 149 150TEST(RoundTrip, GenerateKeyResponseTestError) { 151 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 152 GenerateKeyResponse rsp(ver); 153 rsp.error = KM_ERROR_UNSUPPORTED_ALGORITHM; 154 rsp.key_blob.key_material = dup_array(TEST_DATA); 155 rsp.key_blob.key_material_size = array_length(TEST_DATA); 156 rsp.enforced.Reinitialize(params, array_length(params)); 157 158 UniquePtr<GenerateKeyResponse> deserialized(round_trip(ver, rsp, 4)); 159 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, deserialized->error); 160 EXPECT_EQ(0U, deserialized->enforced.size()); 161 EXPECT_EQ(0U, deserialized->unenforced.size()); 162 EXPECT_EQ(0U, deserialized->key_blob.key_material_size); 163 } 164} 165 166TEST(RoundTrip, GetKeyCharacteristicsRequest) { 167 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 168 GetKeyCharacteristicsRequest req(ver); 169 req.additional_params.Reinitialize(params, array_length(params)); 170 req.SetKeyMaterial("foo", 3); 171 172 UniquePtr<GetKeyCharacteristicsRequest> deserialized(round_trip(ver, req, 85)); 173 EXPECT_EQ(7U, deserialized->additional_params.size()); 174 EXPECT_EQ(3U, deserialized->key_blob.key_material_size); 175 EXPECT_EQ(0, memcmp(deserialized->key_blob.key_material, "foo", 3)); 176 } 177} 178 179TEST(RoundTrip, GetKeyCharacteristicsResponse) { 180 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 181 GetKeyCharacteristicsResponse msg(ver); 182 msg.error = KM_ERROR_OK; 183 msg.enforced.Reinitialize(params, array_length(params)); 184 msg.unenforced.Reinitialize(params, array_length(params)); 185 186 UniquePtr<GetKeyCharacteristicsResponse> deserialized(round_trip(ver, msg, 160)); 187 EXPECT_EQ(msg.enforced, deserialized->enforced); 188 EXPECT_EQ(msg.unenforced, deserialized->unenforced); 189 } 190} 191 192TEST(RoundTrip, BeginOperationRequest) { 193 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 194 BeginOperationRequest msg(ver); 195 msg.purpose = KM_PURPOSE_SIGN; 196 msg.SetKeyMaterial("foo", 3); 197 msg.additional_params.Reinitialize(params, array_length(params)); 198 199 UniquePtr<BeginOperationRequest> deserialized(round_trip(ver, msg, 89)); 200 EXPECT_EQ(KM_PURPOSE_SIGN, deserialized->purpose); 201 EXPECT_EQ(3U, deserialized->key_blob.key_material_size); 202 EXPECT_EQ(0, memcmp(deserialized->key_blob.key_material, "foo", 3)); 203 EXPECT_EQ(msg.additional_params, deserialized->additional_params); 204 } 205} 206 207TEST(RoundTrip, BeginOperationResponse) { 208 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 209 BeginOperationResponse msg(ver); 210 msg.error = KM_ERROR_OK; 211 msg.op_handle = 0xDEADBEEF; 212 213 UniquePtr<BeginOperationResponse> deserialized(round_trip(ver, msg, 12)); 214 EXPECT_EQ(KM_ERROR_OK, deserialized->error); 215 EXPECT_EQ(0xDEADBEEF, deserialized->op_handle); 216 } 217} 218 219TEST(RoundTrip, BeginOperationResponseError) { 220 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 221 BeginOperationResponse msg(ver); 222 msg.error = KM_ERROR_INVALID_OPERATION_HANDLE; 223 msg.op_handle = 0xDEADBEEF; 224 225 UniquePtr<BeginOperationResponse> deserialized(round_trip(ver, msg, 4)); 226 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, deserialized->error); 227 } 228} 229 230TEST(RoundTrip, UpdateOperationRequest) { 231 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 232 UpdateOperationRequest msg(ver); 233 msg.op_handle = 0xDEADBEEF; 234 msg.input.Reinitialize("foo", 3); 235 236 UniquePtr<UpdateOperationRequest> deserialized(round_trip(ver, msg, 15)); 237 EXPECT_EQ(3U, deserialized->input.available_read()); 238 EXPECT_EQ(0, memcmp(deserialized->input.peek_read(), "foo", 3)); 239 } 240} 241 242TEST(RoundTrip, UpdateOperationResponse) { 243 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 244 UpdateOperationResponse msg(ver); 245 msg.error = KM_ERROR_OK; 246 msg.output.Reinitialize("foo", 3); 247 248 UniquePtr<UpdateOperationResponse> deserialized(round_trip(ver, msg, 11)); 249 EXPECT_EQ(KM_ERROR_OK, deserialized->error); 250 EXPECT_EQ(3U, deserialized->output.available_read()); 251 EXPECT_EQ(0, memcmp(deserialized->output.peek_read(), "foo", 3)); 252 } 253} 254 255TEST(RoundTrip, FinishOperationRequest) { 256 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 257 FinishOperationRequest msg(ver); 258 msg.op_handle = 0xDEADBEEF; 259 msg.signature.Reinitialize("bar", 3); 260 261 UniquePtr<FinishOperationRequest> deserialized(round_trip(ver, msg, 15)); 262 EXPECT_EQ(0xDEADBEEF, deserialized->op_handle); 263 EXPECT_EQ(3U, deserialized->signature.available_read()); 264 EXPECT_EQ(0, memcmp(deserialized->signature.peek_read(), "bar", 3)); 265 } 266} 267 268TEST(Round_Trip, FinishOperationResponse) { 269 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 270 FinishOperationResponse msg(ver); 271 msg.error = KM_ERROR_OK; 272 msg.output.Reinitialize("foo", 3); 273 274 UniquePtr<FinishOperationResponse> deserialized(round_trip(ver, msg, 11)); 275 EXPECT_EQ(msg.error, deserialized->error); 276 EXPECT_EQ(msg.output.available_read(), deserialized->output.available_read()); 277 EXPECT_EQ(0, memcmp(msg.output.peek_read(), deserialized->output.peek_read(), 278 msg.output.available_read())); 279 } 280} 281 282TEST(RoundTrip, ImportKeyRequest) { 283 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 284 ImportKeyRequest msg(ver); 285 msg.key_description.Reinitialize(params, array_length(params)); 286 msg.key_format = KM_KEY_FORMAT_X509; 287 msg.SetKeyMaterial("foo", 3); 288 289 UniquePtr<ImportKeyRequest> deserialized(round_trip(ver, msg, 89)); 290 EXPECT_EQ(msg.key_description, deserialized->key_description); 291 EXPECT_EQ(msg.key_format, deserialized->key_format); 292 EXPECT_EQ(msg.key_data_length, deserialized->key_data_length); 293 EXPECT_EQ(0, memcmp(msg.key_data, deserialized->key_data, msg.key_data_length)); 294 } 295} 296 297TEST(RoundTrip, ImportKeyResponse) { 298 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 299 ImportKeyResponse msg(ver); 300 msg.error = KM_ERROR_OK; 301 msg.SetKeyMaterial("foo", 3); 302 msg.enforced.Reinitialize(params, array_length(params)); 303 msg.unenforced.Reinitialize(params, array_length(params)); 304 305 UniquePtr<ImportKeyResponse> deserialized(round_trip(ver, msg, 167)); 306 EXPECT_EQ(msg.error, deserialized->error); 307 EXPECT_EQ(msg.key_blob.key_material_size, deserialized->key_blob.key_material_size); 308 EXPECT_EQ(0, memcmp(msg.key_blob.key_material, deserialized->key_blob.key_material, 309 msg.key_blob.key_material_size)); 310 EXPECT_EQ(msg.enforced, deserialized->enforced); 311 EXPECT_EQ(msg.unenforced, deserialized->unenforced); 312 } 313} 314 315TEST(RoundTrip, ExportKeyRequest) { 316 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 317 ExportKeyRequest msg(ver); 318 msg.additional_params.Reinitialize(params, array_length(params)); 319 msg.key_format = KM_KEY_FORMAT_X509; 320 msg.SetKeyMaterial("foo", 3); 321 322 UniquePtr<ExportKeyRequest> deserialized(round_trip(ver, msg, 89)); 323 EXPECT_EQ(msg.additional_params, deserialized->additional_params); 324 EXPECT_EQ(msg.key_format, deserialized->key_format); 325 EXPECT_EQ(3U, deserialized->key_blob.key_material_size); 326 EXPECT_EQ(0, memcmp("foo", deserialized->key_blob.key_material, 3)); 327 } 328} 329 330TEST(RoundTrip, ExportKeyResponse) { 331 for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 332 ExportKeyResponse msg(ver); 333 msg.error = KM_ERROR_OK; 334 msg.SetKeyMaterial("foo", 3); 335 336 UniquePtr<ExportKeyResponse> deserialized(round_trip(ver, msg, 11)); 337 EXPECT_EQ(3U, deserialized->key_data_length); 338 EXPECT_EQ(0, memcmp("foo", deserialized->key_data, 3)); 339 } 340} 341 342TEST(RoundTrip, GetVersionRequest) { 343 GetVersionRequest msg; 344 345 size_t size = msg.SerializedSize(); 346 ASSERT_EQ(0, size); 347 348 UniquePtr<uint8_t[]> buf(new uint8_t[size]); 349 EXPECT_EQ(buf.get() + size, msg.Serialize(buf.get(), buf.get() + size)); 350 351 GetVersionRequest deserialized; 352 const uint8_t* p = buf.get(); 353 EXPECT_TRUE(deserialized.Deserialize(&p, p + size)); 354 EXPECT_EQ((ptrdiff_t)size, p - buf.get()); 355} 356 357TEST(RoundTrip, GetVersionResponse) { 358 GetVersionResponse msg; 359 msg.error = KM_ERROR_OK; 360 msg.major_ver = 9; 361 msg.minor_ver = 98; 362 msg.subminor_ver = 38; 363 364 size_t size = msg.SerializedSize(); 365 ASSERT_EQ(7, size); 366 367 UniquePtr<uint8_t[]> buf(new uint8_t[size]); 368 EXPECT_EQ(buf.get() + size, msg.Serialize(buf.get(), buf.get() + size)); 369 370 GetVersionResponse deserialized; 371 const uint8_t* p = buf.get(); 372 EXPECT_TRUE(deserialized.Deserialize(&p, p + size)); 373 EXPECT_EQ((ptrdiff_t)size, p - buf.get()); 374 EXPECT_EQ(9, msg.major_ver); 375 EXPECT_EQ(98, msg.minor_ver); 376 EXPECT_EQ(38, msg.subminor_ver); 377} 378 379uint8_t msgbuf[] = { 380 220, 88, 183, 255, 71, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 381 0, 173, 0, 0, 0, 228, 174, 98, 187, 191, 135, 253, 200, 51, 230, 114, 247, 151, 109, 382 237, 79, 87, 32, 94, 5, 204, 46, 154, 30, 91, 6, 103, 148, 254, 129, 65, 171, 228, 383 167, 224, 163, 9, 15, 206, 90, 58, 11, 205, 55, 211, 33, 87, 178, 149, 91, 28, 236, 384 218, 112, 231, 34, 82, 82, 134, 103, 137, 115, 27, 156, 102, 159, 220, 226, 89, 42, 25, 385 37, 9, 84, 239, 76, 161, 198, 72, 167, 163, 39, 91, 148, 191, 17, 191, 87, 169, 179, 386 136, 10, 194, 154, 4, 40, 107, 109, 61, 161, 20, 176, 247, 13, 214, 106, 229, 45, 17, 387 5, 60, 189, 64, 39, 166, 208, 14, 57, 25, 140, 148, 25, 177, 246, 189, 43, 181, 88, 388 204, 29, 126, 224, 100, 143, 93, 60, 57, 249, 55, 0, 87, 83, 227, 224, 166, 59, 214, 389 81, 144, 129, 58, 6, 57, 46, 254, 232, 41, 220, 209, 230, 167, 138, 158, 94, 180, 125, 390 247, 26, 162, 116, 238, 202, 187, 100, 65, 13, 180, 44, 245, 159, 83, 161, 176, 58, 72, 391 236, 109, 105, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 392 0, 11, 0, 0, 0, 98, 0, 0, 0, 1, 0, 0, 32, 2, 0, 0, 0, 1, 0, 393 0, 32, 3, 0, 0, 0, 2, 0, 0, 16, 1, 0, 0, 0, 3, 0, 0, 48, 0, 394 1, 0, 0, 200, 0, 0, 80, 3, 0, 0, 0, 0, 0, 0, 0, 244, 1, 0, 112, 395 1, 246, 1, 0, 112, 1, 189, 2, 0, 96, 144, 178, 236, 250, 255, 255, 255, 255, 145, 396 1, 0, 96, 144, 226, 33, 60, 222, 2, 0, 0, 189, 2, 0, 96, 0, 0, 0, 0, 397 0, 0, 0, 0, 190, 2, 0, 16, 1, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 398 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 11, 0, 399 0, 0, 98, 0, 0, 0, 1, 0, 0, 32, 2, 0, 0, 0, 1, 0, 0, 32, 3, 400 0, 0, 0, 2, 0, 0, 16, 1, 0, 0, 0, 3, 0, 0, 48, 0, 1, 0, 0, 401 200, 0, 0, 80, 3, 0, 0, 0, 0, 0, 0, 0, 244, 1, 0, 112, 1, 246, 1, 402 0, 112, 1, 189, 2, 0, 96, 144, 178, 236, 250, 255, 255, 255, 255, 145, 1, 0, 96, 403 144, 226, 33, 60, 222, 2, 0, 0, 189, 2, 0, 96, 0, 0, 0, 0, 0, 0, 0, 404 0, 190, 2, 0, 16, 1, 0, 0, 0, 405}; 406 407/* 408 * These tests don't have any assertions or expectations. They just try to parse garbage, to see if 409 * the result will be a crash. This is especially informative when run under Valgrind memcheck. 410 */ 411 412template <typename Message> void parse_garbage() { 413 for (int32_t ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { 414 Message msg(ver); 415 const uint8_t* end = msgbuf + array_length(msgbuf); 416 for (size_t i = 0; i < array_length(msgbuf); ++i) { 417 const uint8_t* begin = msgbuf + i; 418 const uint8_t* p = begin; 419 msg.Deserialize(&p, end); 420 } 421 } 422} 423 424#define GARBAGE_TEST(Message) \ 425 TEST(GarbageTest, Message) { parse_garbage<Message>(); } 426 427GARBAGE_TEST(SupportedAlgorithmsResponse) 428GARBAGE_TEST(GenerateKeyRequest); 429GARBAGE_TEST(GenerateKeyResponse); 430GARBAGE_TEST(GetKeyCharacteristicsRequest); 431GARBAGE_TEST(GetKeyCharacteristicsResponse); 432GARBAGE_TEST(BeginOperationRequest); 433GARBAGE_TEST(BeginOperationResponse); 434GARBAGE_TEST(UpdateOperationRequest); 435GARBAGE_TEST(UpdateOperationResponse); 436GARBAGE_TEST(FinishOperationRequest); 437GARBAGE_TEST(FinishOperationResponse); 438// GARBAGE_TEST(AddEntropyRequest); 439GARBAGE_TEST(ImportKeyRequest); 440GARBAGE_TEST(ImportKeyResponse); 441GARBAGE_TEST(ExportKeyRequest); 442GARBAGE_TEST(ExportKeyResponse); 443// GARBAGE_TEST(RescopeRequest); 444// GARBAGE_TEST(RescopeResponse); 445 446// The macro doesn't work on this one. 447TEST(GarbageTest, SupportedResponse) { 448 parse_garbage<SupportedResponse<keymaster_digest_t>>(); 449} 450 451} // namespace test 452 453} // namespace keymaster 454