#include "ffi_test_utils.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include using aidl::android::hardware::security::keymint::ErrorCode; #define TAG_SEQUENCE 0x30 #define LENGTH_MASK 0x80 #define LENGTH_VALUE_MASK 0x7F /** * ASN.1 structure for `KeyDescription` Schema. * See `IKeyMintDevice.aidl` for documentation of the `KeyDescription` schema. * KeyDescription ::= SEQUENCE( * keyFormat INTEGER, # Values from KeyFormat enum. * keyParams AuthorizationList, * ) */ typedef struct key_description { ASN1_INTEGER* key_format; keymaster::KM_AUTH_LIST* key_params; } TEST_KEY_DESCRIPTION; ASN1_SEQUENCE(TEST_KEY_DESCRIPTION) = { ASN1_SIMPLE(TEST_KEY_DESCRIPTION, key_format, ASN1_INTEGER), ASN1_SIMPLE(TEST_KEY_DESCRIPTION, key_params, keymaster::KM_AUTH_LIST), } ASN1_SEQUENCE_END(TEST_KEY_DESCRIPTION); DECLARE_ASN1_FUNCTIONS(TEST_KEY_DESCRIPTION); /** * ASN.1 structure for `SecureKeyWrapper` Schema. * See `IKeyMintDevice.aidl` for documentation of the `SecureKeyWrapper` schema. * SecureKeyWrapper ::= SEQUENCE( * version INTEGER, # Contains value 0 * encryptedTransportKey OCTET_STRING, * initializationVector OCTET_STRING, * keyDescription KeyDescription, * encryptedKey OCTET_STRING, * tag OCTET_STRING * ) */ typedef struct secure_key_wrapper { ASN1_INTEGER* version; ASN1_OCTET_STRING* encrypted_transport_key; ASN1_OCTET_STRING* initialization_vector; TEST_KEY_DESCRIPTION* key_desc; ASN1_OCTET_STRING* encrypted_key; ASN1_OCTET_STRING* tag; } TEST_SECURE_KEY_WRAPPER; ASN1_SEQUENCE(TEST_SECURE_KEY_WRAPPER) = { ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, version, ASN1_INTEGER), ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, encrypted_transport_key, ASN1_OCTET_STRING), ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, initialization_vector, ASN1_OCTET_STRING), ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, key_desc, TEST_KEY_DESCRIPTION), ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, encrypted_key, ASN1_OCTET_STRING), ASN1_SIMPLE(TEST_SECURE_KEY_WRAPPER, tag, ASN1_OCTET_STRING), } ASN1_SEQUENCE_END(TEST_SECURE_KEY_WRAPPER); DECLARE_ASN1_FUNCTIONS(TEST_SECURE_KEY_WRAPPER); IMPLEMENT_ASN1_FUNCTIONS(TEST_SECURE_KEY_WRAPPER); IMPLEMENT_ASN1_FUNCTIONS(TEST_KEY_DESCRIPTION); struct TEST_KEY_DESCRIPTION_Delete { void operator()(TEST_KEY_DESCRIPTION* p) { TEST_KEY_DESCRIPTION_free(p); } }; struct TEST_SECURE_KEY_WRAPPER_Delete { void operator()(TEST_SECURE_KEY_WRAPPER* p) { TEST_SECURE_KEY_WRAPPER_free(p); } }; /* This function extracts a certificate from the certs_chain_buffer at the given * offset. Each DER encoded certificate starts with TAG_SEQUENCE followed by the * total length of the certificate. The length of the certificate is determined * as per ASN.1 encoding rules for the length octets. * * @param certs_chain_buffer: buffer containing DER encoded X.509 certificates * arranged sequentially. * @data_size: Length of the DER encoded X.509 certificates buffer. * @index: DER encoded X.509 certificates buffer offset. * @cert: Encoded certificate to be extracted from buffer as outcome. * @return: ErrorCode::OK on success, otherwise ErrorCode::UNKNOWN_ERROR. */ ErrorCode extractCertFromCertChainBuffer(uint8_t* certs_chain_buffer, int certs_chain_buffer_size, int& index, aidl::android::hardware::security::keymint::Certificate& cert) { if (index >= certs_chain_buffer_size) { return ErrorCode::UNKNOWN_ERROR; } uint32_t length = 0; std::vector cert_bytes; if (certs_chain_buffer[index] == TAG_SEQUENCE) { // Short form. One octet. Bit 8 has value "0" and bits 7-1 give the length. if (0 == (certs_chain_buffer[index + 1] & LENGTH_MASK)) { length = (uint32_t)certs_chain_buffer[index]; // Add SEQ and Length fields length += 2; } else { // Long form. Two to 127 octets. Bit 8 of first octet has value "1" and // bits 7-1 give the number of additional length octets. Second and following // octets give the actual length. int additionalBytes = certs_chain_buffer[index + 1] & LENGTH_VALUE_MASK; if (additionalBytes == 0x01) { length = certs_chain_buffer[index + 2]; // Add SEQ and Length fields length += 3; } else if (additionalBytes == 0x02) { length = (certs_chain_buffer[index + 2] << 8 | certs_chain_buffer[index + 3]); // Add SEQ and Length fields length += 4; } else if (additionalBytes == 0x04) { length = certs_chain_buffer[index + 2] << 24; length |= certs_chain_buffer[index + 3] << 16; length |= certs_chain_buffer[index + 4] << 8; length |= certs_chain_buffer[index + 5]; // Add SEQ and Length fields length += 6; } else { // Length is larger than uint32_t max limit. return ErrorCode::UNKNOWN_ERROR; } } cert_bytes.insert(cert_bytes.end(), (certs_chain_buffer + index), (certs_chain_buffer + index + length)); index += length; for (int i = 0; i < cert_bytes.size(); i++) { cert.encodedCertificate = std::move(cert_bytes); } } else { // SEQUENCE TAG MISSING. return ErrorCode::UNKNOWN_ERROR; } return ErrorCode::OK; } ErrorCode getCertificateChain( rust::Vec& chainBuffer, std::vector& certChain) { uint8_t* data = chainBuffer.data(); int index = 0; int data_size = chainBuffer.size(); while (index < data_size) { aidl::android::hardware::security::keymint::Certificate cert = aidl::android::hardware::security::keymint::Certificate(); if (extractCertFromCertChainBuffer(data, data_size, index, cert) != ErrorCode::OK) { return ErrorCode::UNKNOWN_ERROR; } certChain.push_back(std::move(cert)); } return ErrorCode::OK; } bool validateCertChain(rust::Vec cert_buf, uint32_t cert_len, bool strict_issuer_check) { std::vector cert_chain = std::vector(); if (cert_len <= 0) { return false; } if (getCertificateChain(cert_buf, cert_chain) != ErrorCode::OK) { return false; } for (int i = 0; i < cert_chain.size(); i++) { std::cout << cert_chain[i].toString() << "\n"; } auto result = aidl::android::hardware::security::keymint::test::ChainSignaturesAreValid( cert_chain, strict_issuer_check); if (result == testing::AssertionSuccess()) return true; return false; } /** * Below mentioned key parameters are used to create authorization list of * secure key. * Algorithm: AES-256 * Padding: PKCS7 * Blockmode: ECB * Purpose: Encrypt, Decrypt */ keymaster::AuthorizationSet build_wrapped_key_auth_list() { return keymaster::AuthorizationSet(keymaster::AuthorizationSetBuilder() .AesEncryptionKey(256) .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_ECB) .Authorization(keymaster::TAG_PADDING, KM_PAD_PKCS7) .Authorization(keymaster::TAG_NO_AUTH_REQUIRED)); } /** * Creates ASN.1 DER-encoded data corresponding to `KeyDescription` schema as * AAD. See `IKeyMintDevice.aidl` for documentation of the `KeyDescription` schema. */ CxxResult buildAsn1DerEncodedWrappedKeyDescription() { CxxResult cxx_result{}; keymaster_error_t error; cxx_result.error = KM_ERROR_OK; keymaster::UniquePtr key_description( TEST_KEY_DESCRIPTION_new()); if (!key_description.get()) { cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED; return cxx_result; } // Fill secure key authorizations. keymaster::AuthorizationSet auth_list = build_wrapped_key_auth_list(); error = build_auth_list(auth_list, key_description->key_params); if (error != KM_ERROR_OK) { cxx_result.error = error; return cxx_result; } // Fill secure key format. if (!ASN1_INTEGER_set(key_description->key_format, KM_KEY_FORMAT_RAW)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // Perform ASN.1 DER encoding of KeyDescription. int asn1_data_len = i2d_TEST_KEY_DESCRIPTION(key_description.get(), nullptr); if (asn1_data_len < 0) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } std::vector asn1_data(asn1_data_len, 0); if (!asn1_data.data()) { cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED; return cxx_result; } uint8_t* p = asn1_data.data(); asn1_data_len = i2d_TEST_KEY_DESCRIPTION(key_description.get(), &p); if (asn1_data_len < 0) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } std::move(asn1_data.begin(), asn1_data.end(), std::back_inserter(cxx_result.data)); return cxx_result; } /** * Creates wrapped key material to import in ASN.1 DER-encoded data corresponding to * `SecureKeyWrapper` schema. See `IKeyMintDevice.aidl` for documentation of the `SecureKeyWrapper` * schema. */ CxxResult createWrappedKey(rust::Vec encrypted_secure_key, rust::Vec encrypted_transport_key, rust::Vec iv, rust::Vec tag) { CxxResult cxx_result{}; keymaster_error_t error; cxx_result.error = KM_ERROR_OK; uint8_t* enc_secure_key_data = encrypted_secure_key.data(); int enc_secure_key_size = encrypted_secure_key.size(); uint8_t* iv_data = iv.data(); int iv_size = iv.size(); uint8_t* tag_data = tag.data(); int tag_size = tag.size(); uint8_t* enc_transport_key_data = encrypted_transport_key.data(); int enc_transport_key_size = encrypted_transport_key.size(); keymaster::UniquePtr sec_key_wrapper( TEST_SECURE_KEY_WRAPPER_new()); if (!sec_key_wrapper.get()) { cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED; return cxx_result; } // Fill version = 0 if (!ASN1_INTEGER_set(sec_key_wrapper->version, 0)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // Fill encrypted transport key. if (enc_transport_key_size && !ASN1_OCTET_STRING_set(sec_key_wrapper->encrypted_transport_key, enc_transport_key_data, enc_transport_key_size)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // Fill encrypted secure key. if (enc_secure_key_size && !ASN1_OCTET_STRING_set(sec_key_wrapper->encrypted_key, enc_secure_key_data, enc_secure_key_size)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // Fill secure key authorization list. keymaster::AuthorizationSet auth_list = build_wrapped_key_auth_list(); error = build_auth_list(auth_list, sec_key_wrapper->key_desc->key_params); if (error != KM_ERROR_OK) { cxx_result.error = error; return cxx_result; } // Fill secure key format. if (!ASN1_INTEGER_set(sec_key_wrapper->key_desc->key_format, KM_KEY_FORMAT_RAW)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // Fill initialization vector used for encrypting secure key. if (iv_size && !ASN1_OCTET_STRING_set(sec_key_wrapper->initialization_vector, iv_data, iv_size)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // Fill GCM-tag, extracted during secure key encryption. if (tag_size && !ASN1_OCTET_STRING_set(sec_key_wrapper->tag, tag_data, tag_size)) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } // ASN.1 DER-encoding of secure key wrapper. int asn1_data_len = i2d_TEST_SECURE_KEY_WRAPPER(sec_key_wrapper.get(), nullptr); if (asn1_data_len < 0) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } std::vector asn1_data(asn1_data_len, 0); if (!asn1_data.data()) { cxx_result.error = KM_ERROR_MEMORY_ALLOCATION_FAILED; return cxx_result; } uint8_t* p = asn1_data.data(); asn1_data_len = i2d_TEST_SECURE_KEY_WRAPPER(sec_key_wrapper.get(), &p); if (asn1_data_len < 0) { cxx_result.error = keymaster::TranslateLastOpenSslError(); return cxx_result; } std::move(asn1_data.begin(), asn1_data.end(), std::back_inserter(cxx_result.data)); return cxx_result; }