1 /*
2 * Copyright (C) 2021 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 <android/hardware/keymaster/4.0/IKeymasterDevice.h>
18 #include <keymasterV4_0/attestation_record.h>
19 #include <keymasterV4_0/openssl_utils.h>
20 #include "keymaster4_common.h"
21
22 namespace android::hardware::keymaster::V4_0::fuzzer {
23
24 constexpr size_t kMinBytes = 1;
25 constexpr size_t kMaxBytes = 10;
26
27 class KeyMaster4AttestationFuzzer {
28 public:
29 void process(const uint8_t* data, size_t size);
30
31 private:
32 ErrorCode generateKey(const AuthorizationSet& keyDesc, hidl_vec<uint8_t>* keyBlob,
33 KeyCharacteristics* keyCharacteristics);
34 ErrorCode attestKey(hidl_vec<uint8_t>& keyBlob, const AuthorizationSet& attestParams,
35 hidl_vec<hidl_vec<uint8_t>>* certificateChain);
36 X509_Ptr parseCertificateBlob(const hidl_vec<uint8_t>& blob);
37 ASN1_OCTET_STRING* getAttestationRecord(const X509* certificate);
38 bool verifyAttestationRecord(const hidl_vec<uint8_t>& attestationCert);
39 void invokeAttestationRecord();
40
41 sp<IKeymasterDevice> mKeymaster = nullptr;
42 std::unique_ptr<FuzzedDataProvider> mFdp = nullptr;
43 };
44
generateKey(const AuthorizationSet & key_desc,hidl_vec<uint8_t> * keyBlob,KeyCharacteristics * keyCharacteristics)45 ErrorCode KeyMaster4AttestationFuzzer::generateKey(const AuthorizationSet& key_desc,
46 hidl_vec<uint8_t>* keyBlob,
47 KeyCharacteristics* keyCharacteristics) {
48 ErrorCode error;
49 mKeymaster->generateKey(key_desc.hidl_data(),
50 [&](ErrorCode hidlError, const hidl_vec<uint8_t>& hidlKeyBlob,
51 const KeyCharacteristics& hidlKeyCharacteristics) {
52 error = hidlError;
53 *keyBlob = hidlKeyBlob;
54 *keyCharacteristics = hidlKeyCharacteristics;
55 });
56 return error;
57 }
58
attestKey(hidl_vec<uint8_t> & keyBlob,const AuthorizationSet & attestParams,hidl_vec<hidl_vec<uint8_t>> * certificateChain)59 ErrorCode KeyMaster4AttestationFuzzer::attestKey(hidl_vec<uint8_t>& keyBlob,
60 const AuthorizationSet& attestParams,
61 hidl_vec<hidl_vec<uint8_t>>* certificateChain) {
62 ErrorCode error;
63 auto rc = mKeymaster->attestKey(
64 keyBlob, attestParams.hidl_data(),
65 [&](ErrorCode hidlError, const hidl_vec<hidl_vec<uint8_t>>& hidlCertificateChain) {
66 error = hidlError;
67 *certificateChain = hidlCertificateChain;
68 });
69
70 if (!rc.isOk()) {
71 return ErrorCode::UNKNOWN_ERROR;
72 }
73 return error;
74 }
75
parseCertificateBlob(const hidl_vec<uint8_t> & blob)76 X509_Ptr KeyMaster4AttestationFuzzer::parseCertificateBlob(const hidl_vec<uint8_t>& blob) {
77 const uint8_t* p = blob.data();
78 return X509_Ptr(d2i_X509(nullptr, &p, blob.size()));
79 }
80
81 /**
82 * @brief getAttestationRecord() accepts a 'certificate' pointer and the return value points to the
83 * data owned by 'certificate'. Hence, 'certificate' should not be freed and the return value cannot
84 * outlive 'certificate'
85 */
getAttestationRecord(const X509 * certificate)86 ASN1_OCTET_STRING* KeyMaster4AttestationFuzzer::getAttestationRecord(const X509* certificate) {
87 ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
88 if (!oid.get()) {
89 return nullptr;
90 }
91
92 int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
93 if (location == -1) {
94 return nullptr;
95 }
96
97 X509_EXTENSION* attestRecordExt = X509_get_ext(certificate, location);
98 if (!attestRecordExt) {
99 return nullptr;
100 }
101
102 ASN1_OCTET_STRING* attestRecord = X509_EXTENSION_get_data(attestRecordExt);
103 return attestRecord;
104 }
105
verifyAttestationRecord(const hidl_vec<uint8_t> & attestationCert)106 bool KeyMaster4AttestationFuzzer::verifyAttestationRecord(
107 const hidl_vec<uint8_t>& attestationCert) {
108 X509_Ptr cert(parseCertificateBlob(attestationCert));
109 if (!cert.get()) {
110 return false;
111 }
112
113 ASN1_OCTET_STRING* attestRecord = getAttestationRecord(cert.get());
114 if (!attestRecord) {
115 return false;
116 }
117
118 AuthorizationSet attestationSwEnforced;
119 AuthorizationSet attestationHwEnforced;
120 uint32_t attestationVersion;
121 uint32_t keymasterVersion;
122 SecurityLevel securityLevel;
123 SecurityLevel keymasterSecurityLevel;
124 hidl_vec<uint8_t> attestationChallenge;
125 hidl_vec<uint8_t> attestationUniqueId;
126
127 auto error = parse_attestation_record(
128 attestRecord->data, attestRecord->length, &attestationVersion, &securityLevel,
129 &keymasterVersion, &keymasterSecurityLevel, &attestationChallenge,
130 &attestationSwEnforced, &attestationHwEnforced, &attestationUniqueId);
131 if (error != ErrorCode::OK) {
132 return false;
133 }
134
135 hidl_vec<uint8_t> verifiedBootKey;
136 keymaster_verified_boot_t verifiedBootState;
137 bool device_locked;
138 hidl_vec<uint8_t> verifiedBootHash;
139
140 parse_root_of_trust(attestRecord->data, attestRecord->length, &verifiedBootKey,
141 &verifiedBootState, &device_locked, &verifiedBootHash);
142 return true;
143 }
144
invokeAttestationRecord()145 void KeyMaster4AttestationFuzzer::invokeAttestationRecord() {
146 mKeymaster = IKeymasterDevice::getService();
147 if (!mKeymaster) {
148 return;
149 }
150
151 hidl_vec<uint8_t> keyBlob;
152 KeyCharacteristics keyCharacteristics;
153 generateKey(createAuthorizationSet(mFdp), &keyBlob, &keyCharacteristics);
154
155 hidl_vec<hidl_vec<uint8_t>> certificateChain;
156
157 std::vector<uint8_t> challenge, attestationId;
158 challenge =
159 mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
160 attestationId =
161 mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
162 attestKey(keyBlob,
163 AuthorizationSetBuilder()
164 .Authorization(TAG_ATTESTATION_CHALLENGE, challenge)
165 .Authorization(TAG_ATTESTATION_APPLICATION_ID, attestationId),
166 &certificateChain);
167
168 if (certificateChain.size() > 0) {
169 verifyAttestationRecord(certificateChain[mFdp->ConsumeIntegralInRange<size_t>(
170 0, certificateChain.size() - 1)]);
171 }
172 }
173
process(const uint8_t * data,size_t size)174 void KeyMaster4AttestationFuzzer::process(const uint8_t* data, size_t size) {
175 mFdp = std::make_unique<FuzzedDataProvider>(data, size);
176 invokeAttestationRecord();
177 }
178
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)179 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
180 KeyMaster4AttestationFuzzer km4AttestationFuzzer;
181 km4AttestationFuzzer.process(data, size);
182 return 0;
183 }
184
185 } // namespace android::hardware::keymaster::V4_0::fuzzer
186