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 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 17 | #include <aidl/android/hardware/drm/IDrmFactory.h> |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 18 | #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h> |
| 19 | #include <android/binder_manager.h> |
| 20 | #include <cppbor.h> |
Seth Moore | 0168856 | 2021-06-22 12:59:32 -0700 | [diff] [blame] | 21 | #include <gflags/gflags.h> |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 22 | #include <keymaster/cppcose/cppcose.h> |
Seth Moore | 9a4bc97 | 2021-07-22 16:46:07 -0700 | [diff] [blame] | 23 | #include <openssl/base64.h> |
Seth Moore | 6dfb02a | 2021-06-18 15:43:09 -0700 | [diff] [blame] | 24 | #include <remote_prov/remote_prov_utils.h> |
Seth Moore | 5a40fa7 | 2021-06-22 13:48:59 -0700 | [diff] [blame] | 25 | #include <sys/random.h> |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 26 | |
Alice Wang | c1b568a | 2024-05-13 09:15:20 +0000 | [diff] [blame] | 27 | #include <future> |
Seth Moore | 708da93 | 2022-08-18 14:38:05 -0700 | [diff] [blame] | 28 | #include <string> |
| 29 | #include <vector> |
| 30 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 31 | #include "DrmRkpAdapter.h" |
Seth Moore | 708da93 | 2022-08-18 14:38:05 -0700 | [diff] [blame] | 32 | #include "rkp_factory_extraction_lib.h" |
| 33 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 34 | using aidl::android::hardware::drm::IDrmFactory; |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 35 | using aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent; |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 36 | using aidl::android::hardware::security::keymint::remote_prov::jsonEncodeCsrWithBuild; |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 37 | |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 38 | using namespace cppbor; |
| 39 | using namespace cppcose; |
| 40 | |
Seth Moore | 0475678 | 2022-09-13 16:09:15 -0700 | [diff] [blame] | 41 | DEFINE_string(output_format, "build+csr", "How to format the output. Defaults to 'build+csr'."); |
Seth Moore | dff09d0 | 2023-05-31 09:38:47 -0700 | [diff] [blame] | 42 | DEFINE_bool(self_test, true, |
| 43 | "If true, this tool performs a self-test, validating the payload for correctness. " |
| 44 | "This checks that the device on the factory line is producing valid output " |
| 45 | "before attempting to upload the output to the device info service."); |
chuanchuan.gao | 8ef6d1a | 2023-12-07 16:47:51 +0800 | [diff] [blame] | 46 | DEFINE_string(serialno_prop, "ro.serialno", |
| 47 | "The property of getting serial number. Defaults to 'ro.serialno'."); |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 48 | |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 49 | namespace { |
| 50 | |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 51 | // Various supported --output_format values. |
| 52 | constexpr std::string_view kBinaryCsrOutput = "csr"; // Just the raw csr as binary |
| 53 | constexpr std::string_view kBuildPlusCsr = "build+csr"; // Text-encoded (JSON) build |
| 54 | // fingerprint plus CSR. |
| 55 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 56 | std::string getFullServiceName(const char* descriptor, const char* name) { |
| 57 | return std::string(descriptor) + "/" + name; |
| 58 | } |
| 59 | |
Tommy Chiu | ce82be8 | 2022-03-09 04:23:19 +0000 | [diff] [blame] | 60 | void writeOutput(const std::string instance_name, const Array& csr) { |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 61 | if (FLAGS_output_format == kBinaryCsrOutput) { |
| 62 | auto bytes = csr.encode(); |
| 63 | std::copy(bytes.begin(), bytes.end(), std::ostream_iterator<char>(std::cout)); |
| 64 | } else if (FLAGS_output_format == kBuildPlusCsr) { |
chuanchuan.gao | 8ef6d1a | 2023-12-07 16:47:51 +0800 | [diff] [blame] | 65 | auto [json, error] = jsonEncodeCsrWithBuild(instance_name, csr, FLAGS_serialno_prop); |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 66 | if (!error.empty()) { |
| 67 | std::cerr << "Error JSON encoding the output: " << error; |
| 68 | exit(1); |
| 69 | } |
| 70 | std::cout << json << std::endl; |
| 71 | } else { |
| 72 | std::cerr << "Unexpected output_format '" << FLAGS_output_format << "'" << std::endl; |
| 73 | std::cerr << "Valid formats:" << std::endl; |
| 74 | std::cerr << " " << kBinaryCsrOutput << std::endl; |
| 75 | std::cerr << " " << kBuildPlusCsr << std::endl; |
| 76 | exit(1); |
| 77 | } |
| 78 | } |
| 79 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 80 | void getCsrForIRpc(const char* descriptor, const char* name, IRemotelyProvisionedComponent* irpc) { |
Alice Wang | 16e3442 | 2024-06-07 12:41:22 +0000 | [diff] [blame] | 81 | // AVF RKP HAL is not always supported, so we need to check if it is supported before |
| 82 | // generating the CSR. |
| 83 | if (std::string(name) == "avf" && !isRemoteProvisioningSupported(irpc)) { |
| 84 | return; |
| 85 | } |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 86 | auto [request, errMsg] = getCsr(name, irpc, FLAGS_self_test); |
| 87 | auto fullName = getFullServiceName(descriptor, name); |
| 88 | if (!request) { |
| 89 | std::cerr << "Unable to build CSR for '" << fullName << ": " << errMsg << std::endl; |
| 90 | exit(-1); |
| 91 | } |
| 92 | |
| 93 | writeOutput(std::string(name), *request); |
| 94 | } |
| 95 | |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 96 | // Callback for AServiceManager_forEachDeclaredInstance that writes out a CSR |
| 97 | // for every IRemotelyProvisionedComponent. |
| 98 | void getCsrForInstance(const char* name, void* /*context*/) { |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 99 | auto fullName = getFullServiceName(IRemotelyProvisionedComponent::descriptor, name); |
Alice Wang | c1b568a | 2024-05-13 09:15:20 +0000 | [diff] [blame] | 100 | std::future<AIBinder*> wait_for_service_func = |
| 101 | std::async(std::launch::async, AServiceManager_waitForService, fullName.c_str()); |
| 102 | if (wait_for_service_func.wait_for(std::chrono::seconds(10)) == std::future_status::timeout) { |
| 103 | std::cerr << "Wait for service timed out after 10 seconds: " << fullName; |
| 104 | exit(-1); |
| 105 | } |
| 106 | AIBinder* rkpAiBinder = wait_for_service_func.get(); |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 107 | ::ndk::SpAIBinder rkp_binder(rkpAiBinder); |
| 108 | auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder); |
| 109 | if (!rkp_service) { |
| 110 | std::cerr << "Unable to get binder object for '" << fullName << "', skipping."; |
Keith Mok | b9462c1 | 2021-11-11 19:34:26 +0000 | [diff] [blame] | 111 | exit(-1); |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 112 | } |
| 113 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 114 | getCsrForIRpc(IRemotelyProvisionedComponent::descriptor, name, rkp_service.get()); |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 115 | } |
| 116 | |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 117 | } // namespace |
| 118 | |
Seth Moore | 0168856 | 2021-06-22 12:59:32 -0700 | [diff] [blame] | 119 | int main(int argc, char** argv) { |
| 120 | gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags=*/true); |
| 121 | |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 122 | AServiceManager_forEachDeclaredInstance(IRemotelyProvisionedComponent::descriptor, |
| 123 | /*context=*/nullptr, getCsrForInstance); |
Seth Moore | 0168856 | 2021-06-22 12:59:32 -0700 | [diff] [blame] | 124 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame] | 125 | // Append drm csr's |
| 126 | for (auto const& e : android::mediadrm::getDrmRemotelyProvisionedComponents()) { |
| 127 | getCsrForIRpc(IDrmFactory::descriptor, e.first.c_str(), e.second.get()); |
| 128 | } |
| 129 | |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 130 | return 0; |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 131 | } |