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