1 /*
2 * Copyright (C) 2024 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
18 #include <aidl/android/hardware/security/keymint/AttestationKey.h>
19 #include <aidl/android/hardware/security/keymint/KeyCreationResult.h>
20 #include <android/binder_manager.h>
21 #include <keymint_common.h>
22 #include <keymint_support/attestation_record.h>
23 #include <keymint_support/openssl_utils.h>
24 #include <utils/Log.h>
25
26 namespace android::hardware::security::keymint_support::fuzzer {
27 using namespace android;
28 using AStatus = ::ndk::ScopedAStatus;
29 std::shared_ptr<IKeyMintDevice> gKeyMint = nullptr;
30
31 constexpr size_t kMaxBytes = 256;
32 const std::string kServiceName = "android.hardware.security.keymint.IKeyMintDevice/default";
33
34 class KeyMintAttestationFuzzer {
35 public:
KeyMintAttestationFuzzer(const uint8_t * data,size_t size)36 KeyMintAttestationFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
37 void process();
38
39 private:
40 KeyCreationResult generateKey(const AuthorizationSet& keyDesc,
41 const std::optional<AttestationKey>& attestKey,
42 vector<uint8_t>* keyBlob,
43 vector<KeyCharacteristics>* keyCharacteristics,
44 vector<Certificate>* certChain);
45 X509_Ptr parseCertificateBlob(const vector<uint8_t>& blob);
46 ASN1_OCTET_STRING* getAttestationRecord(const X509* certificate);
47 bool verifyAttestationRecord(const vector<uint8_t>& attestationCert);
48 FuzzedDataProvider mFdp;
49 };
50
generateKey(const AuthorizationSet & keyDesc,const std::optional<AttestationKey> & attestKey,vector<uint8_t> * keyBlob,vector<KeyCharacteristics> * keyCharacteristics,vector<Certificate> * certChain)51 KeyCreationResult KeyMintAttestationFuzzer::generateKey(
52 const AuthorizationSet& keyDesc, const std::optional<AttestationKey>& attestKey,
53 vector<uint8_t>* keyBlob, vector<KeyCharacteristics>* keyCharacteristics,
54 vector<Certificate>* certChain) {
55 KeyCreationResult creationResult;
56 AStatus result = gKeyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
57 if (result.isOk() && creationResult.keyBlob.size() > 0) {
58 *keyBlob = std::move(creationResult.keyBlob);
59 *keyCharacteristics = std::move(creationResult.keyCharacteristics);
60 *certChain = std::move(creationResult.certificateChain);
61 }
62 return creationResult;
63 }
64
parseCertificateBlob(const vector<uint8_t> & blob)65 X509_Ptr KeyMintAttestationFuzzer::parseCertificateBlob(const vector<uint8_t>& blob) {
66 const uint8_t* data = blob.data();
67 return X509_Ptr(d2i_X509(nullptr, &data, blob.size()));
68 }
69
getAttestationRecord(const X509 * certificate)70 ASN1_OCTET_STRING* KeyMintAttestationFuzzer::getAttestationRecord(const X509* certificate) {
71 ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
72 if (!oid.get()) {
73 return nullptr;
74 }
75
76 int32_t location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
77 if (location == -1) {
78 return nullptr;
79 }
80
81 X509_EXTENSION* attestRecordExt = X509_get_ext(certificate, location);
82 if (!attestRecordExt) {
83 return nullptr;
84 }
85
86 ASN1_OCTET_STRING* attestRecord = X509_EXTENSION_get_data(attestRecordExt);
87 return attestRecord;
88 }
89
verifyAttestationRecord(const vector<uint8_t> & attestationCert)90 bool KeyMintAttestationFuzzer::verifyAttestationRecord(const vector<uint8_t>& attestationCert) {
91 X509_Ptr cert(parseCertificateBlob(attestationCert));
92 if (!cert.get()) {
93 return false;
94 }
95
96 ASN1_OCTET_STRING* attestRecord = getAttestationRecord(cert.get());
97 if (!attestRecord) {
98 return false;
99 }
100
101 AuthorizationSet attestationSwEnforced;
102 AuthorizationSet attestationHwEnforced;
103 SecurityLevel attestationSecurityLevel;
104 SecurityLevel keymintSecurityLevel;
105 vector<uint8_t> attestationChallenge;
106 vector<uint8_t> attestationUniqueId;
107 uint32_t attestationVersion;
108 uint32_t keymintVersion;
109
110 auto error = parse_attestation_record(attestRecord->data, attestRecord->length,
111 &attestationVersion, &attestationSecurityLevel,
112 &keymintVersion, &keymintSecurityLevel,
113 &attestationChallenge, &attestationSwEnforced,
114 &attestationHwEnforced, &attestationUniqueId);
115 if (error != ErrorCode::OK) {
116 return false;
117 }
118
119 VerifiedBoot verifiedBootState;
120 vector<uint8_t> verifiedBootKey;
121 vector<uint8_t> verifiedBootHash;
122 bool device_locked;
123
124 error = parse_root_of_trust(attestRecord->data, attestRecord->length, &verifiedBootKey,
125 &verifiedBootState, &device_locked, &verifiedBootHash);
126 if (error != ErrorCode::OK) {
127 return false;
128 }
129 return true;
130 }
131
process()132 void KeyMintAttestationFuzzer::process() {
133 AttestationKey attestKey;
134 vector<Certificate> attestKeyCertChain;
135 vector<KeyCharacteristics> attestKeyCharacteristics;
136 generateKey(createAuthSetForAttestKey(&mFdp), {}, &attestKey.keyBlob, &attestKeyCharacteristics,
137 &attestKeyCertChain);
138
139 vector<Certificate> attestedKeyCertChain;
140 vector<KeyCharacteristics> attestedKeyCharacteristics;
141 vector<uint8_t> attestedKeyBlob;
142 attestKey.issuerSubjectName = mFdp.ConsumeBytes<uint8_t>(kMaxBytes);
143 generateKey(createAuthorizationSet(&mFdp), attestKey, &attestedKeyBlob,
144 &attestedKeyCharacteristics, &attestedKeyCertChain);
145
146 if (attestedKeyCertChain.size() > 0) {
147 size_t leafCert = attestedKeyCertChain.size() - 1;
148 verifyAttestationRecord(attestedKeyCertChain[leafCert].encodedCertificate);
149 }
150 }
151
LLVMFuzzerInitialize(int,char)152 extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
153 ::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str()));
154 gKeyMint = std::move(IKeyMintDevice::fromBinder(binder));
155 LOG_ALWAYS_FATAL_IF(!gKeyMint, "Failed to get IKeyMintDevice instance.");
156 return 0;
157 }
158
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)159 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
160 KeyMintAttestationFuzzer kmAttestationFuzzer(data, size);
161 kmAttestationFuzzer.process();
162 return 0;
163 }
164
165 } // namespace android::hardware::security::keymint_support::fuzzer
166