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 | |
Seth Moore | 708da93 | 2022-08-18 14:38:05 -0700 | [diff] [blame] | 27 | #include <string> |
| 28 | #include <vector> |
| 29 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 30 | #include "DrmRkpAdapter.h" |
Seth Moore | 708da93 | 2022-08-18 14:38:05 -0700 | [diff] [blame] | 31 | #include "rkp_factory_extraction_lib.h" |
| 32 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 33 | using aidl::android::hardware::drm::IDrmFactory; |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 34 | using aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent; |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 35 | using aidl::android::hardware::security::keymint::remote_prov::jsonEncodeCsrWithBuild; |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 36 | |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 37 | using namespace cppbor; |
| 38 | using namespace cppcose; |
| 39 | |
Seth Moore | 0475678 | 2022-09-13 16:09:15 -0700 | [diff] [blame] | 40 | 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] | 41 | DEFINE_bool(self_test, true, |
| 42 | "If true, this tool performs a self-test, validating the payload for correctness. " |
| 43 | "This checks that the device on the factory line is producing valid output " |
| 44 | "before attempting to upload the output to the device info service."); |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 45 | |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 46 | namespace { |
| 47 | |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 48 | // Various supported --output_format values. |
| 49 | constexpr std::string_view kBinaryCsrOutput = "csr"; // Just the raw csr as binary |
| 50 | constexpr std::string_view kBuildPlusCsr = "build+csr"; // Text-encoded (JSON) build |
| 51 | // fingerprint plus CSR. |
| 52 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 53 | std::string getFullServiceName(const char* descriptor, const char* name) { |
| 54 | return std::string(descriptor) + "/" + name; |
| 55 | } |
| 56 | |
Tommy Chiu | ce82be8 | 2022-03-09 04:23:19 +0000 | [diff] [blame] | 57 | void writeOutput(const std::string instance_name, const Array& csr) { |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 58 | if (FLAGS_output_format == kBinaryCsrOutput) { |
| 59 | auto bytes = csr.encode(); |
| 60 | std::copy(bytes.begin(), bytes.end(), std::ostream_iterator<char>(std::cout)); |
| 61 | } else if (FLAGS_output_format == kBuildPlusCsr) { |
Tommy Chiu | ce82be8 | 2022-03-09 04:23:19 +0000 | [diff] [blame] | 62 | auto [json, error] = jsonEncodeCsrWithBuild(instance_name, csr); |
Seth Moore | e44aad2 | 2021-06-25 17:38:24 -0700 | [diff] [blame] | 63 | if (!error.empty()) { |
| 64 | std::cerr << "Error JSON encoding the output: " << error; |
| 65 | exit(1); |
| 66 | } |
| 67 | std::cout << json << std::endl; |
| 68 | } else { |
| 69 | std::cerr << "Unexpected output_format '" << FLAGS_output_format << "'" << std::endl; |
| 70 | std::cerr << "Valid formats:" << std::endl; |
| 71 | std::cerr << " " << kBinaryCsrOutput << std::endl; |
| 72 | std::cerr << " " << kBuildPlusCsr << std::endl; |
| 73 | exit(1); |
| 74 | } |
| 75 | } |
| 76 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 77 | void getCsrForIRpc(const char* descriptor, const char* name, IRemotelyProvisionedComponent* irpc) { |
| 78 | auto [request, errMsg] = getCsr(name, irpc, FLAGS_self_test); |
| 79 | auto fullName = getFullServiceName(descriptor, name); |
| 80 | if (!request) { |
| 81 | std::cerr << "Unable to build CSR for '" << fullName << ": " << errMsg << std::endl; |
| 82 | exit(-1); |
| 83 | } |
| 84 | |
| 85 | writeOutput(std::string(name), *request); |
| 86 | } |
| 87 | |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 88 | // Callback for AServiceManager_forEachDeclaredInstance that writes out a CSR |
| 89 | // for every IRemotelyProvisionedComponent. |
| 90 | void getCsrForInstance(const char* name, void* /*context*/) { |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 91 | auto fullName = getFullServiceName(IRemotelyProvisionedComponent::descriptor, name); |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 92 | AIBinder* rkpAiBinder = AServiceManager_getService(fullName.c_str()); |
| 93 | ::ndk::SpAIBinder rkp_binder(rkpAiBinder); |
| 94 | auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder); |
| 95 | if (!rkp_service) { |
| 96 | std::cerr << "Unable to get binder object for '" << fullName << "', skipping."; |
Keith Mok | b9462c1 | 2021-11-11 19:34:26 +0000 | [diff] [blame] | 97 | exit(-1); |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 98 | } |
| 99 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 100 | getCsrForIRpc(IRemotelyProvisionedComponent::descriptor, name, rkp_service.get()); |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 101 | } |
| 102 | |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 103 | } // namespace |
| 104 | |
Seth Moore | 0168856 | 2021-06-22 12:59:32 -0700 | [diff] [blame] | 105 | int main(int argc, char** argv) { |
| 106 | gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags=*/true); |
| 107 | |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 108 | AServiceManager_forEachDeclaredInstance(IRemotelyProvisionedComponent::descriptor, |
| 109 | /*context=*/nullptr, getCsrForInstance); |
Seth Moore | 0168856 | 2021-06-22 12:59:32 -0700 | [diff] [blame] | 110 | |
Robert Shih | d3c1f7c | 2023-07-10 13:07:35 -0700 | [diff] [blame^] | 111 | // Append drm csr's |
| 112 | for (auto const& e : android::mediadrm::getDrmRemotelyProvisionedComponents()) { |
| 113 | getCsrForIRpc(IDrmFactory::descriptor, e.first.c_str(), e.second.get()); |
| 114 | } |
| 115 | |
Seth Moore | 5914625 | 2021-07-02 08:59:23 -0700 | [diff] [blame] | 116 | return 0; |
Max Bires | f60987e | 2021-04-16 13:35:20 -0700 | [diff] [blame] | 117 | } |