| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 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 <string> | 
|  | 18 | #include <vector> | 
|  | 19 |  | 
|  | 20 | #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h> | 
|  | 21 | #include <android/binder_manager.h> | 
|  | 22 | #include <cppbor.h> | 
|  | 23 | #include <keymaster/cppcose/cppcose.h> | 
|  | 24 | #include <log/log.h> | 
| Seth Moore | 6dfb02a | 2021-06-18 15:43:09 -0700 | [diff] [blame^] | 25 | #include <remote_prov/remote_prov_utils.h> | 
| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 26 | #include <vintf/VintfObject.h> | 
|  | 27 |  | 
|  | 28 | using std::set; | 
|  | 29 | using std::string; | 
|  | 30 | using std::vector; | 
|  | 31 |  | 
|  | 32 | using aidl::android::hardware::security::keymint::DeviceInfo; | 
|  | 33 | using aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent; | 
|  | 34 | using aidl::android::hardware::security::keymint::MacedPublicKey; | 
|  | 35 | using aidl::android::hardware::security::keymint::ProtectedData; | 
| Seth Moore | 6dfb02a | 2021-06-18 15:43:09 -0700 | [diff] [blame^] | 36 | using aidl::android::hardware::security::keymint::remote_prov::generateEekChain; | 
| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 37 |  | 
|  | 38 | using android::vintf::HalManifest; | 
|  | 39 | using android::vintf::VintfObject; | 
|  | 40 |  | 
|  | 41 | using namespace cppbor; | 
|  | 42 | using namespace cppcose; | 
|  | 43 |  | 
|  | 44 | namespace { | 
|  | 45 |  | 
|  | 46 | const string kPackage = "android.hardware.security.keymint"; | 
|  | 47 | const string kInterface = "IRemotelyProvisionedComponent"; | 
|  | 48 | const string kFormattedName = kPackage + "." + kInterface + "/"; | 
|  | 49 |  | 
| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 50 | std::vector<uint8_t> getChallenge() { | 
|  | 51 | return std::vector<uint8_t>(0); | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | std::vector<uint8_t> composeCertificateRequest(ProtectedData&& protectedData, | 
|  | 55 | DeviceInfo&& deviceInfo) { | 
|  | 56 | Array emptyMacedKeysToSign; | 
|  | 57 | emptyMacedKeysToSign | 
|  | 58 | .add(std::vector<uint8_t>(0))   // empty protected headers as bstr | 
|  | 59 | .add(Map())                     // empty unprotected headers | 
|  | 60 | .add(Null())                    // nil for the payload | 
|  | 61 | .add(std::vector<uint8_t>(0));  // empty tag as bstr | 
|  | 62 | Array certificateRequest; | 
|  | 63 | certificateRequest.add(EncodedItem(std::move(deviceInfo.deviceInfo))) | 
|  | 64 | .add(getChallenge())  // fake challenge | 
|  | 65 | .add(EncodedItem(std::move(protectedData.protectedData))) | 
|  | 66 | .add(std::move(emptyMacedKeysToSign)); | 
|  | 67 | return certificateRequest.encode(); | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | int32_t errorMsg(string name) { | 
|  | 71 | std::cerr << "Failed for rkp instance: " << name; | 
|  | 72 | return -1; | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | }  // namespace | 
|  | 76 |  | 
|  | 77 | int main() { | 
|  | 78 | std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest(); | 
|  | 79 | set<string> rkpNames = manifest->getAidlInstances(kPackage, kInterface); | 
|  | 80 | for (auto name : rkpNames) { | 
|  | 81 | string fullName = kFormattedName + name; | 
|  | 82 | if (!AServiceManager_isDeclared(fullName.c_str())) { | 
|  | 83 | ALOGE("Could not find the following instance declared in the manifest: %s\n", | 
|  | 84 | fullName.c_str()); | 
|  | 85 | return errorMsg(name); | 
|  | 86 | } | 
|  | 87 | AIBinder* rkpAiBinder = AServiceManager_getService(fullName.c_str()); | 
|  | 88 | ::ndk::SpAIBinder rkp_binder(rkpAiBinder); | 
|  | 89 | auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder); | 
|  | 90 | std::vector<uint8_t> keysToSignMac; | 
|  | 91 | std::vector<MacedPublicKey> emptyKeys; | 
|  | 92 |  | 
|  | 93 | // Replace this eek chain generation with the actual production GEEK | 
| Seth Moore | 6dfb02a | 2021-06-18 15:43:09 -0700 | [diff] [blame^] | 94 | const std::vector<uint8_t> kFakeEekId = {'f', 'a', 'k', 'e', 0}; | 
|  | 95 | auto eekOrErr = generateEekChain(3 /* chainlength */, kFakeEekId); | 
| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 96 | if (!eekOrErr) { | 
|  | 97 | ALOGE("Failed to generate test EEK somehow: %s", eekOrErr.message().c_str()); | 
|  | 98 | return errorMsg(name); | 
|  | 99 | } | 
|  | 100 |  | 
| Seth Moore | 6dfb02a | 2021-06-18 15:43:09 -0700 | [diff] [blame^] | 101 | auto [eek, pubkey, privkey] = eekOrErr.moveValue(); | 
| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 102 | DeviceInfo deviceInfo; | 
|  | 103 | ProtectedData protectedData; | 
|  | 104 | if (rkp_service) { | 
|  | 105 | ALOGE("extracting bundle"); | 
|  | 106 | ::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest( | 
|  | 107 | true /* testMode */, emptyKeys, eek, getChallenge(), &deviceInfo, &protectedData, | 
|  | 108 | &keysToSignMac); | 
|  | 109 | if (!status.isOk()) { | 
|  | 110 | ALOGE("Bundle extraction failed. Error code: %d", status.getServiceSpecificError()); | 
|  | 111 | return errorMsg(name); | 
|  | 112 | } | 
| Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 113 | std::vector<uint8_t> certificateRequest = | 
|  | 114 | composeCertificateRequest(std::move(protectedData), std::move(deviceInfo)); | 
|  | 115 | std::copy(certificateRequest.begin(), certificateRequest.end(), | 
|  | 116 | std::ostream_iterator<char>(std::cout)); | 
|  | 117 | } | 
|  | 118 | } | 
|  | 119 | } |