blob: 47dd7a4afbbf31405be0bac43e030dadbfab2dac [file] [log] [blame]
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +00001#include "ffi_test_utils.hpp"
2
3#include <iostream>
4
Rajesh Nyamagoud28abde62023-04-01 01:32:32 +00005#include <android-base/logging.h>
6
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +00007#include <KeyMintAidlTestBase.h>
8#include <aidl/android/hardware/security/keymint/ErrorCode.h>
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +00009#include <keymaster/UniquePtr.h>
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +000010
11#include <vector>
12
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +000013#include <hardware/keymaster_defs.h>
14#include <keymaster/android_keymaster_utils.h>
15#include <keymaster/keymaster_tags.h>
16
17#include <keymaster/km_openssl/attestation_record.h>
18#include <keymaster/km_openssl/openssl_err.h>
19#include <keymaster/km_openssl/openssl_utils.h>
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +000020
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +000021using aidl::android::hardware::security::keymint::ErrorCode;
22
23#define TAG_SEQUENCE 0x30
24#define LENGTH_MASK 0x80
25#define LENGTH_VALUE_MASK 0x7F
26
Rajesh Nyamagoud28abde62023-04-01 01:32:32 +000027/* EVP_PKEY_from_keystore is from system/security/keystore-engine. */
28extern "C" EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id);
29
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +000030/**
31 * ASN.1 structure for `KeyDescription` Schema.
32 * See `IKeyMintDevice.aidl` for documentation of the `KeyDescription` schema.
33 * KeyDescription ::= SEQUENCE(
34 * keyFormat INTEGER, # Values from KeyFormat enum.
35 * keyParams AuthorizationList,
36 * )
37 */
38typedef struct key_description {
39 ASN1_INTEGER* key_format;
40 keymaster::KM_AUTH_LIST* key_params;
41} TEST_KEY_DESCRIPTION;
42
43ASN1_SEQUENCE(TEST_KEY_DESCRIPTION) = {
44 ASN1_SIMPLE(TEST_KEY_DESCRIPTION, key_format, ASN1_INTEGER),
45 ASN1_SIMPLE(TEST_KEY_DESCRIPTION, key_params, keymaster::KM_AUTH_LIST),
46} ASN1_SEQUENCE_END(TEST_KEY_DESCRIPTION);
47DECLARE_ASN1_FUNCTIONS(TEST_KEY_DESCRIPTION);
48
49/**
50 * ASN.1 structure for `SecureKeyWrapper` Schema.
51 * See `IKeyMintDevice.aidl` for documentation of the `SecureKeyWrapper` schema.
52 * SecureKeyWrapper ::= SEQUENCE(
53 * version INTEGER, # Contains value 0
54 * encryptedTransportKey OCTET_STRING,
55 * initializationVector OCTET_STRING,
56 * keyDescription KeyDescription,
57 * encryptedKey OCTET_STRING,
58 * tag OCTET_STRING
59 * )
60 */
61typedef struct secure_key_wrapper {
62 ASN1_INTEGER* version;
63 ASN1_OCTET_STRING* encrypted_transport_key;
64 ASN1_OCTET_STRING* initialization_vector;
65 TEST_KEY_DESCRIPTION* key_desc;
66 ASN1_OCTET_STRING* encrypted_key;
67 ASN1_OCTET_STRING* tag;
68} TEST_SECURE_KEY_WRAPPER;
69
70ASN1_SEQUENCE(TEST_SECURE_KEY_WRAPPER) = {
71 ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, version, ASN1_INTEGER),
72 ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, encrypted_transport_key, ASN1_OCTET_STRING),
73 ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, initialization_vector, ASN1_OCTET_STRING),
74 ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, key_desc, TEST_KEY_DESCRIPTION),
75 ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, encrypted_key, ASN1_OCTET_STRING),
76 ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, tag, ASN1_OCTET_STRING),
77} ASN1_SEQUENCE_END(TEST_SECURE_KEY_WRAPPER);
78DECLARE_ASN1_FUNCTIONS(TEST_SECURE_KEY_WRAPPER);
79
80IMPLEMENT_ASN1_FUNCTIONS(TEST_SECURE_KEY_WRAPPER);
81IMPLEMENT_ASN1_FUNCTIONS(TEST_KEY_DESCRIPTION);
82
83struct TEST_KEY_DESCRIPTION_Delete {
84 void operator()(TEST_KEY_DESCRIPTION* p) { TEST_KEY_DESCRIPTION_free(p); }
85};
86struct TEST_SECURE_KEY_WRAPPER_Delete {
87 void operator()(TEST_SECURE_KEY_WRAPPER* p) { TEST_SECURE_KEY_WRAPPER_free(p); }
88};
89
Rajesh Nyamagoud28abde62023-04-01 01:32:32 +000090const std::string keystore2_grant_id_prefix("ks2_keystore-engine_grant_id:");
91
Rajesh Nyamagoud4d483372022-02-09 01:38:23 +000092/* This function extracts a certificate from the certs_chain_buffer at the given
93 * offset. Each DER encoded certificate starts with TAG_SEQUENCE followed by the
94 * total length of the certificate. The length of the certificate is determined
95 * as per ASN.1 encoding rules for the length octets.
96 *
97 * @param certs_chain_buffer: buffer containing DER encoded X.509 certificates
98 * arranged sequentially.
99 * @data_size: Length of the DER encoded X.509 certificates buffer.
100 * @index: DER encoded X.509 certificates buffer offset.
101 * @cert: Encoded certificate to be extracted from buffer as outcome.
102 * @return: ErrorCode::OK on success, otherwise ErrorCode::UNKNOWN_ERROR.
103 */
104ErrorCode
105extractCertFromCertChainBuffer(uint8_t* certs_chain_buffer, int certs_chain_buffer_size, int& index,
106 aidl::android::hardware::security::keymint::Certificate& cert) {
107 if (index >= certs_chain_buffer_size) {
108 return ErrorCode::UNKNOWN_ERROR;
109 }
110
111 uint32_t length = 0;
112 std::vector<uint8_t> cert_bytes;
113 if (certs_chain_buffer[index] == TAG_SEQUENCE) {
114 // Short form. One octet. Bit 8 has value "0" and bits 7-1 give the length.
115 if (0 == (certs_chain_buffer[index + 1] & LENGTH_MASK)) {
116 length = (uint32_t)certs_chain_buffer[index];
117 // Add SEQ and Length fields
118 length += 2;
119 } else {
120 // Long form. Two to 127 octets. Bit 8 of first octet has value "1" and
121 // bits 7-1 give the number of additional length octets. Second and following
122 // octets give the actual length.
123 int additionalBytes = certs_chain_buffer[index + 1] & LENGTH_VALUE_MASK;
124 if (additionalBytes == 0x01) {
125 length = certs_chain_buffer[index + 2];
126 // Add SEQ and Length fields
127 length += 3;
128 } else if (additionalBytes == 0x02) {
129 length = (certs_chain_buffer[index + 2] << 8 | certs_chain_buffer[index + 3]);
130 // Add SEQ and Length fields
131 length += 4;
132 } else if (additionalBytes == 0x04) {
133 length = certs_chain_buffer[index + 2] << 24;
134 length |= certs_chain_buffer[index + 3] << 16;
135 length |= certs_chain_buffer[index + 4] << 8;
136 length |= certs_chain_buffer[index + 5];
137 // Add SEQ and Length fields
138 length += 6;
139 } else {
140 // Length is larger than uint32_t max limit.
141 return ErrorCode::UNKNOWN_ERROR;
142 }
143 }
144 cert_bytes.insert(cert_bytes.end(), (certs_chain_buffer + index),
145 (certs_chain_buffer + index + length));
146 index += length;
147
148 for (int i = 0; i < cert_bytes.size(); i++) {
149 cert.encodedCertificate = std::move(cert_bytes);
150 }
151 } else {
152 // SEQUENCE TAG MISSING.
153 return ErrorCode::UNKNOWN_ERROR;
154 }
155
156 return ErrorCode::OK;
157}
158
159ErrorCode getCertificateChain(
160 rust::Vec<rust::u8>& chainBuffer,
161 std::vector<aidl::android::hardware::security::keymint::Certificate>& certChain) {
162 uint8_t* data = chainBuffer.data();
163 int index = 0;
164 int data_size = chainBuffer.size();
165
166 while (index < data_size) {
167 aidl::android::hardware::security::keymint::Certificate cert =
168 aidl::android::hardware::security::keymint::Certificate();
169 if (extractCertFromCertChainBuffer(data, data_size, index, cert) != ErrorCode::OK) {
170 return ErrorCode::UNKNOWN_ERROR;
171 }
172 certChain.push_back(std::move(cert));
173 }
174 return ErrorCode::OK;
175}
176
177bool validateCertChain(rust::Vec<rust::u8> cert_buf, uint32_t cert_len, bool strict_issuer_check) {
178 std::vector<aidl::android::hardware::security::keymint::Certificate> cert_chain =
179 std::vector<aidl::android::hardware::security::keymint::Certificate>();
180 if (cert_len <= 0) {
181 return false;
182 }
183 if (getCertificateChain(cert_buf, cert_chain) != ErrorCode::OK) {
184 return false;
185 }
186
187 for (int i = 0; i < cert_chain.size(); i++) {
188 std::cout << cert_chain[i].toString() << "\n";
189 }
190 auto result = aidl::android::hardware::security::keymint::test::ChainSignaturesAreValid(
191 cert_chain, strict_issuer_check);
192
193 if (result == testing::AssertionSuccess()) return true;
194
195 return false;
196}
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +0000197
198/**
199 * Below mentioned key parameters are used to create authorization list of
200 * secure key.
201 * Algorithm: AES-256
202 * Padding: PKCS7
203 * Blockmode: ECB
204 * Purpose: Encrypt, Decrypt
205 */
206keymaster::AuthorizationSet build_wrapped_key_auth_list() {
207 return keymaster::AuthorizationSet(keymaster::AuthorizationSetBuilder()
208 .AesEncryptionKey(256)
209 .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_ECB)
210 .Authorization(keymaster::TAG_PADDING, KM_PAD_PKCS7)
211 .Authorization(keymaster::TAG_NO_AUTH_REQUIRED));
212}
213
214/**
215 * Creates ASN.1 DER-encoded data corresponding to `KeyDescription` schema as
216 * AAD. See `IKeyMintDevice.aidl` for documentation of the `KeyDescription` schema.
217 */
218CxxResult buildAsn1DerEncodedWrappedKeyDescription() {
219 CxxResult cxx_result{};
220 keymaster_error_t error;
221 cxx_result.error = KM_ERROR_OK;
222
223 keymaster::UniquePtr<TEST_KEY_DESCRIPTION, TEST_KEY_DESCRIPTION_Delete> key_description(
224 TEST_KEY_DESCRIPTION_new());
225 if (!key_description.get()) {
226 cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
227 return cxx_result;
228 }
229
230 // Fill secure key authorizations.
231 keymaster::AuthorizationSet auth_list = build_wrapped_key_auth_list();
232 error = build_auth_list(auth_list, key_description->key_params);
233 if (error != KM_ERROR_OK) {
234 cxx_result.error = error;
235 return cxx_result;
236 }
237
238 // Fill secure key format.
239 if (!ASN1_INTEGER_set(key_description->key_format, KM_KEY_FORMAT_RAW)) {
240 cxx_result.error = keymaster::TranslateLastOpenSslError();
241 return cxx_result;
242 }
243
244 // Perform ASN.1 DER encoding of KeyDescription.
Rajesh Nyamagoudcebd79d2023-01-12 16:22:00 +0000245 int asn1_data_len = i2d_TEST_KEY_DESCRIPTION(key_description.get(), nullptr);
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +0000246 if (asn1_data_len < 0) {
247 cxx_result.error = keymaster::TranslateLastOpenSslError();
248 return cxx_result;
249 }
250 std::vector<uint8_t> asn1_data(asn1_data_len, 0);
251
252 if (!asn1_data.data()) {
253 cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
254 return cxx_result;
255 }
256
257 uint8_t* p = asn1_data.data();
258 asn1_data_len = i2d_TEST_KEY_DESCRIPTION(key_description.get(), &p);
259 if (asn1_data_len < 0) {
260 cxx_result.error = keymaster::TranslateLastOpenSslError();
261 return cxx_result;
262 }
263
264 std::move(asn1_data.begin(), asn1_data.end(), std::back_inserter(cxx_result.data));
265
266 return cxx_result;
267}
268
269/**
270 * Creates wrapped key material to import in ASN.1 DER-encoded data corresponding to
271 * `SecureKeyWrapper` schema. See `IKeyMintDevice.aidl` for documentation of the `SecureKeyWrapper`
272 * schema.
273 */
274CxxResult createWrappedKey(rust::Vec<rust::u8> encrypted_secure_key,
275 rust::Vec<rust::u8> encrypted_transport_key, rust::Vec<rust::u8> iv,
276 rust::Vec<rust::u8> tag) {
277 CxxResult cxx_result{};
278 keymaster_error_t error;
279 cxx_result.error = KM_ERROR_OK;
280
281 uint8_t* enc_secure_key_data = encrypted_secure_key.data();
282 int enc_secure_key_size = encrypted_secure_key.size();
283
284 uint8_t* iv_data = iv.data();
285 int iv_size = iv.size();
286
287 uint8_t* tag_data = tag.data();
288 int tag_size = tag.size();
289
290 uint8_t* enc_transport_key_data = encrypted_transport_key.data();
291 int enc_transport_key_size = encrypted_transport_key.size();
292
293 keymaster::UniquePtr<TEST_SECURE_KEY_WRAPPER, TEST_SECURE_KEY_WRAPPER_Delete> sec_key_wrapper(
294 TEST_SECURE_KEY_WRAPPER_new());
295 if (!sec_key_wrapper.get()) {
296 cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
297 return cxx_result;
298 }
299
300 // Fill version = 0
301 if (!ASN1_INTEGER_set(sec_key_wrapper->version, 0)) {
302 cxx_result.error = keymaster::TranslateLastOpenSslError();
303 return cxx_result;
304 }
305
306 // Fill encrypted transport key.
307 if (enc_transport_key_size &&
308 !ASN1_OCTET_STRING_set(sec_key_wrapper->encrypted_transport_key, enc_transport_key_data,
309 enc_transport_key_size)) {
310 cxx_result.error = keymaster::TranslateLastOpenSslError();
311 return cxx_result;
312 }
313
314 // Fill encrypted secure key.
315 if (enc_secure_key_size && !ASN1_OCTET_STRING_set(sec_key_wrapper->encrypted_key,
316 enc_secure_key_data, enc_secure_key_size)) {
317 cxx_result.error = keymaster::TranslateLastOpenSslError();
318 return cxx_result;
319 }
320
321 // Fill secure key authorization list.
322 keymaster::AuthorizationSet auth_list = build_wrapped_key_auth_list();
323 error = build_auth_list(auth_list, sec_key_wrapper->key_desc->key_params);
324 if (error != KM_ERROR_OK) {
325 cxx_result.error = error;
326 return cxx_result;
327 }
328
329 // Fill secure key format.
330 if (!ASN1_INTEGER_set(sec_key_wrapper->key_desc->key_format, KM_KEY_FORMAT_RAW)) {
331 cxx_result.error = keymaster::TranslateLastOpenSslError();
332 return cxx_result;
333 }
334
335 // Fill initialization vector used for encrypting secure key.
336 if (iv_size &&
337 !ASN1_OCTET_STRING_set(sec_key_wrapper->initialization_vector, iv_data, iv_size)) {
338 cxx_result.error = keymaster::TranslateLastOpenSslError();
339 return cxx_result;
340 }
341
342 // Fill GCM-tag, extracted during secure key encryption.
343 if (tag_size && !ASN1_OCTET_STRING_set(sec_key_wrapper->tag, tag_data, tag_size)) {
344 cxx_result.error = keymaster::TranslateLastOpenSslError();
345 return cxx_result;
346 }
347
348 // ASN.1 DER-encoding of secure key wrapper.
Rajesh Nyamagoudcebd79d2023-01-12 16:22:00 +0000349 int asn1_data_len = i2d_TEST_SECURE_KEY_WRAPPER(sec_key_wrapper.get(), nullptr);
Rajesh Nyamagoudc946cc42022-04-12 22:49:11 +0000350 if (asn1_data_len < 0) {
351 cxx_result.error = keymaster::TranslateLastOpenSslError();
352 return cxx_result;
353 }
354 std::vector<uint8_t> asn1_data(asn1_data_len, 0);
355
356 if (!asn1_data.data()) {
357 cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
358 return cxx_result;
359 }
360
361 uint8_t* p = asn1_data.data();
362 asn1_data_len = i2d_TEST_SECURE_KEY_WRAPPER(sec_key_wrapper.get(), &p);
363 if (asn1_data_len < 0) {
364 cxx_result.error = keymaster::TranslateLastOpenSslError();
365 return cxx_result;
366 }
367
368 std::move(asn1_data.begin(), asn1_data.end(), std::back_inserter(cxx_result.data));
369
370 return cxx_result;
371}
Rajesh Nyamagoud28abde62023-04-01 01:32:32 +0000372
373/**
374 * Perform EC/RSA sign operation using `EVP_PKEY`.
375 */
376bool performSignData(const char* data, size_t data_len, EVP_PKEY* pkey, unsigned char** signature,
377 size_t* signature_len) {
378 // Create the signing context
379 EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
380 if (md_ctx == NULL) {
381 LOG(ERROR) << "Failed to create signing context";
382 return false;
383 }
384
385 // Initialize the signing operation
386 if (EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
387 LOG(ERROR) << "Failed to initialize signing operation";
388 EVP_MD_CTX_free(md_ctx);
389 return false;
390 }
391
392 // Sign the data
393 if (EVP_DigestSignUpdate(md_ctx, data, data_len) != 1) {
394 LOG(ERROR) << "Failed to sign data";
395 EVP_MD_CTX_free(md_ctx);
396 return false;
397 }
398
399 // Determine the length of the signature
400 if (EVP_DigestSignFinal(md_ctx, NULL, signature_len) != 1) {
401 LOG(ERROR) << "Failed to determine signature length";
402 EVP_MD_CTX_free(md_ctx);
403 return false;
404 }
405
406 // Allocate memory for the signature
407 *signature = (unsigned char*)malloc(*signature_len);
408 if (*signature == NULL) {
409 LOG(ERROR) << "Failed to allocate memory for the signature";
410 EVP_MD_CTX_free(md_ctx);
411 return false;
412 }
413
414 // Perform the final signing operation
415 if (EVP_DigestSignFinal(md_ctx, *signature, signature_len) != 1) {
416 LOG(ERROR) << "Failed to perform signing operation";
417 free(*signature);
418 EVP_MD_CTX_free(md_ctx);
419 return false;
420 }
421
422 EVP_MD_CTX_free(md_ctx);
423 return true;
424}
425
426/**
427 * Perform EC/RSA verify operation using `EVP_PKEY`.
428 */
429int performVerifySignature(const char* data, size_t data_len, EVP_PKEY* pkey,
430 const unsigned char* signature, size_t signature_len) {
431 // Create the verification context
432 EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
433 if (md_ctx == NULL) {
434 LOG(ERROR) << "Failed to create verification context";
435 return false;
436 }
437
438 // Initialize the verification operation
439 if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
440 LOG(ERROR) << "Failed to initialize verification operation";
441 EVP_MD_CTX_free(md_ctx);
442 return false;
443 }
444
445 // Verify the data
446 if (EVP_DigestVerifyUpdate(md_ctx, data, data_len) != 1) {
447 LOG(ERROR) << "Failed to verify data";
448 EVP_MD_CTX_free(md_ctx);
449 return false;
450 }
451
452 // Perform the verification operation
453 int ret = EVP_DigestVerifyFinal(md_ctx, signature, signature_len);
454 EVP_MD_CTX_free(md_ctx);
455
456 return ret == 1;
457}
458
459/**
460 * Extract the `EVP_PKEY` for the given KeyMint Key and perform Sign/Verify operations
461 * using extracted `EVP_PKEY`.
462 */
463bool performCryptoOpUsingKeystoreEngine(int64_t grant_id) {
464 const int KEY_ID_LEN = 20;
465 char key_id[KEY_ID_LEN] = "";
466 snprintf(key_id, KEY_ID_LEN, "%" PRIx64, grant_id);
467 std::string str_key = std::string(keystore2_grant_id_prefix) + key_id;
468 bool result = false;
469
470#if defined(OPENSSL_IS_BORINGSSL)
471 EVP_PKEY* evp = EVP_PKEY_from_keystore(str_key.c_str());
472 if (!evp) {
473 LOG(ERROR) << "Error while loading a key from keystore-engine";
474 return false;
475 }
476
477 int algo_type = EVP_PKEY_id(evp);
478 if (algo_type != EVP_PKEY_RSA && algo_type != EVP_PKEY_EC) {
479 LOG(ERROR) << "Unsupported Algorithm. Only RSA and EC are allowed.";
480 EVP_PKEY_free(evp);
481 return false;
482 }
483
484 unsigned char* signature = NULL;
485 size_t signature_len = 0;
486 const char* INPUT_DATA = "MY MESSAGE FOR SIGN";
487 size_t data_len = strlen(INPUT_DATA);
488 if (!performSignData(INPUT_DATA, data_len, evp, &signature, &signature_len)) {
489 LOG(ERROR) << "Failed to sign data";
490 EVP_PKEY_free(evp);
491 return false;
492 }
493
494 result = performVerifySignature(INPUT_DATA, data_len, evp, signature, signature_len);
495 if (!result) {
496 LOG(ERROR) << "Signature verification failed";
497 } else {
498 LOG(INFO) << "Signature verification success";
499 }
500
501 free(signature);
502 EVP_PKEY_free(evp);
503#endif
504 return result;
505}