1*789431f2SAndroid Build Coastguard Worker /*
2*789431f2SAndroid Build Coastguard Worker * Copyright 2015 The Android Open Source Project
3*789431f2SAndroid Build Coastguard Worker *
4*789431f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*789431f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*789431f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*789431f2SAndroid Build Coastguard Worker *
8*789431f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*789431f2SAndroid Build Coastguard Worker *
10*789431f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*789431f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*789431f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*789431f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*789431f2SAndroid Build Coastguard Worker * limitations under the License.
15*789431f2SAndroid Build Coastguard Worker */
16*789431f2SAndroid Build Coastguard Worker
17*789431f2SAndroid Build Coastguard Worker #include <keymaster/soft_keymaster_device.h>
18*789431f2SAndroid Build Coastguard Worker
19*789431f2SAndroid Build Coastguard Worker #include <assert.h>
20*789431f2SAndroid Build Coastguard Worker #include <stddef.h>
21*789431f2SAndroid Build Coastguard Worker #include <stdio.h>
22*789431f2SAndroid Build Coastguard Worker #include <stdlib.h>
23*789431f2SAndroid Build Coastguard Worker #include <string.h>
24*789431f2SAndroid Build Coastguard Worker #include <time.h>
25*789431f2SAndroid Build Coastguard Worker
26*789431f2SAndroid Build Coastguard Worker #include <algorithm>
27*789431f2SAndroid Build Coastguard Worker #include <vector>
28*789431f2SAndroid Build Coastguard Worker
29*789431f2SAndroid Build Coastguard Worker #include <type_traits>
30*789431f2SAndroid Build Coastguard Worker
31*789431f2SAndroid Build Coastguard Worker #include <openssl/x509.h>
32*789431f2SAndroid Build Coastguard Worker
33*789431f2SAndroid Build Coastguard Worker #include <hardware/keymaster1.h>
34*789431f2SAndroid Build Coastguard Worker #define LOG_TAG "SoftKeymasterDevice"
35*789431f2SAndroid Build Coastguard Worker #include <log/log.h>
36*789431f2SAndroid Build Coastguard Worker
37*789431f2SAndroid Build Coastguard Worker #include <keymaster/android_keymaster.h>
38*789431f2SAndroid Build Coastguard Worker #include <keymaster/android_keymaster_messages.h>
39*789431f2SAndroid Build Coastguard Worker #include <keymaster/android_keymaster_utils.h>
40*789431f2SAndroid Build Coastguard Worker #include <keymaster/authorization_set.h>
41*789431f2SAndroid Build Coastguard Worker #include <keymaster/contexts/soft_keymaster_context.h>
42*789431f2SAndroid Build Coastguard Worker #include <keymaster/key.h>
43*789431f2SAndroid Build Coastguard Worker #include <keymaster/km_openssl/openssl_utils.h>
44*789431f2SAndroid Build Coastguard Worker #include <keymaster/soft_keymaster_logger.h>
45*789431f2SAndroid Build Coastguard Worker
46*789431f2SAndroid Build Coastguard Worker struct keystore_module soft_keymaster1_device_module = {
47*789431f2SAndroid Build Coastguard Worker .common =
48*789431f2SAndroid Build Coastguard Worker {
49*789431f2SAndroid Build Coastguard Worker .tag = HARDWARE_MODULE_TAG,
50*789431f2SAndroid Build Coastguard Worker .module_api_version = KEYMASTER_MODULE_API_VERSION_1_0,
51*789431f2SAndroid Build Coastguard Worker .hal_api_version = HARDWARE_HAL_API_VERSION,
52*789431f2SAndroid Build Coastguard Worker .id = KEYSTORE_HARDWARE_MODULE_ID,
53*789431f2SAndroid Build Coastguard Worker .name = "OpenSSL-based SoftKeymaster HAL",
54*789431f2SAndroid Build Coastguard Worker .author = "The Android Open Source Project",
55*789431f2SAndroid Build Coastguard Worker .methods = nullptr,
56*789431f2SAndroid Build Coastguard Worker .dso = nullptr,
57*789431f2SAndroid Build Coastguard Worker .reserved = {},
58*789431f2SAndroid Build Coastguard Worker },
59*789431f2SAndroid Build Coastguard Worker };
60*789431f2SAndroid Build Coastguard Worker
61*789431f2SAndroid Build Coastguard Worker struct keystore_module soft_keymaster2_device_module = {
62*789431f2SAndroid Build Coastguard Worker .common =
63*789431f2SAndroid Build Coastguard Worker {
64*789431f2SAndroid Build Coastguard Worker .tag = HARDWARE_MODULE_TAG,
65*789431f2SAndroid Build Coastguard Worker .module_api_version = KEYMASTER_MODULE_API_VERSION_2_0,
66*789431f2SAndroid Build Coastguard Worker .hal_api_version = HARDWARE_HAL_API_VERSION,
67*789431f2SAndroid Build Coastguard Worker .id = KEYSTORE_HARDWARE_MODULE_ID,
68*789431f2SAndroid Build Coastguard Worker .name = "OpenSSL-based SoftKeymaster HAL",
69*789431f2SAndroid Build Coastguard Worker .author = "The Android Open Source Project",
70*789431f2SAndroid Build Coastguard Worker .methods = nullptr,
71*789431f2SAndroid Build Coastguard Worker .dso = nullptr,
72*789431f2SAndroid Build Coastguard Worker .reserved = {},
73*789431f2SAndroid Build Coastguard Worker },
74*789431f2SAndroid Build Coastguard Worker };
75*789431f2SAndroid Build Coastguard Worker
76*789431f2SAndroid Build Coastguard Worker namespace keymaster {
77*789431f2SAndroid Build Coastguard Worker
78*789431f2SAndroid Build Coastguard Worker const size_t kMaximumAttestationChallengeLength = 128;
79*789431f2SAndroid Build Coastguard Worker const size_t kOperationTableSize = 16;
80*789431f2SAndroid Build Coastguard Worker
make_vector(const T * array,size_t len)81*789431f2SAndroid Build Coastguard Worker template <typename T> std::vector<T> make_vector(const T* array, size_t len) {
82*789431f2SAndroid Build Coastguard Worker return std::vector<T>(array, array + len);
83*789431f2SAndroid Build Coastguard Worker }
84*789431f2SAndroid Build Coastguard Worker
85*789431f2SAndroid Build Coastguard Worker // This helper class implements just enough of the C++ standard collection interface to be able to
86*789431f2SAndroid Build Coastguard Worker // accept push_back calls, and it does nothing but count them. It's useful when you want to count
87*789431f2SAndroid Build Coastguard Worker // insertions but not actually store anything. It's used in digest_set_is_full below to count the
88*789431f2SAndroid Build Coastguard Worker // size of a set intersection.
89*789431f2SAndroid Build Coastguard Worker struct PushbackCounter {
90*789431f2SAndroid Build Coastguard Worker struct value_type {
91*789431f2SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor)
value_typekeymaster::PushbackCounter::value_type92*789431f2SAndroid Build Coastguard Worker template <typename T> value_type(const T&) {}
93*789431f2SAndroid Build Coastguard Worker };
push_backkeymaster::PushbackCounter94*789431f2SAndroid Build Coastguard Worker void push_back(const value_type&) { ++count; }
95*789431f2SAndroid Build Coastguard Worker size_t count = 0;
96*789431f2SAndroid Build Coastguard Worker };
97*789431f2SAndroid Build Coastguard Worker
98*789431f2SAndroid Build Coastguard Worker static std::vector<keymaster_digest_t> full_digest_list = {
99*789431f2SAndroid Build Coastguard Worker KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
100*789431f2SAndroid Build Coastguard Worker KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
101*789431f2SAndroid Build Coastguard Worker
digest_set_is_full(Iter begin,Iter end)102*789431f2SAndroid Build Coastguard Worker template <typename Iter> static bool digest_set_is_full(Iter begin, Iter end) {
103*789431f2SAndroid Build Coastguard Worker PushbackCounter counter;
104*789431f2SAndroid Build Coastguard Worker std::set_intersection(begin, end, full_digest_list.begin(), full_digest_list.end(),
105*789431f2SAndroid Build Coastguard Worker std::back_inserter(counter));
106*789431f2SAndroid Build Coastguard Worker return counter.count == full_digest_list.size();
107*789431f2SAndroid Build Coastguard Worker }
108*789431f2SAndroid Build Coastguard Worker
add_digests(keymaster1_device_t * dev,keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,SoftKeymasterDevice::DigestMap * map,bool * supports_all)109*789431f2SAndroid Build Coastguard Worker static keymaster_error_t add_digests(keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
110*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
111*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice::DigestMap* map, bool* supports_all) {
112*789431f2SAndroid Build Coastguard Worker auto key = std::make_pair(algorithm, purpose);
113*789431f2SAndroid Build Coastguard Worker
114*789431f2SAndroid Build Coastguard Worker keymaster_digest_t* digests;
115*789431f2SAndroid Build Coastguard Worker size_t digests_length;
116*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
117*789431f2SAndroid Build Coastguard Worker dev->get_supported_digests(dev, algorithm, purpose, &digests, &digests_length);
118*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) {
119*789431f2SAndroid Build Coastguard Worker LOG_E("Error %d getting supported digests from keymaster1 device", error);
120*789431f2SAndroid Build Coastguard Worker return error;
121*789431f2SAndroid Build Coastguard Worker }
122*789431f2SAndroid Build Coastguard Worker std::unique_ptr<keymaster_digest_t, Malloc_Delete> digests_deleter(digests);
123*789431f2SAndroid Build Coastguard Worker
124*789431f2SAndroid Build Coastguard Worker auto digest_vec = make_vector(digests, digests_length);
125*789431f2SAndroid Build Coastguard Worker *supports_all = digest_set_is_full(digest_vec.begin(), digest_vec.end());
126*789431f2SAndroid Build Coastguard Worker (*map)[key] = std::move(digest_vec);
127*789431f2SAndroid Build Coastguard Worker return error;
128*789431f2SAndroid Build Coastguard Worker }
129*789431f2SAndroid Build Coastguard Worker
map_digests(keymaster1_device_t * dev,SoftKeymasterDevice::DigestMap * map,bool * supports_all)130*789431f2SAndroid Build Coastguard Worker static keymaster_error_t map_digests(keymaster1_device_t* dev, SoftKeymasterDevice::DigestMap* map,
131*789431f2SAndroid Build Coastguard Worker bool* supports_all) {
132*789431f2SAndroid Build Coastguard Worker map->clear();
133*789431f2SAndroid Build Coastguard Worker *supports_all = true;
134*789431f2SAndroid Build Coastguard Worker
135*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t sig_algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_EC, KM_ALGORITHM_HMAC};
136*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t sig_purposes[] = {KM_PURPOSE_SIGN, KM_PURPOSE_VERIFY};
137*789431f2SAndroid Build Coastguard Worker for (auto algorithm : sig_algorithms)
138*789431f2SAndroid Build Coastguard Worker for (auto purpose : sig_purposes) {
139*789431f2SAndroid Build Coastguard Worker bool alg_purpose_supports_all;
140*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
141*789431f2SAndroid Build Coastguard Worker add_digests(dev, algorithm, purpose, map, &alg_purpose_supports_all);
142*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
143*789431f2SAndroid Build Coastguard Worker *supports_all &= alg_purpose_supports_all;
144*789431f2SAndroid Build Coastguard Worker }
145*789431f2SAndroid Build Coastguard Worker
146*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t crypt_algorithms[] = {KM_ALGORITHM_RSA};
147*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t crypt_purposes[] = {KM_PURPOSE_ENCRYPT, KM_PURPOSE_DECRYPT};
148*789431f2SAndroid Build Coastguard Worker for (auto algorithm : crypt_algorithms)
149*789431f2SAndroid Build Coastguard Worker for (auto purpose : crypt_purposes) {
150*789431f2SAndroid Build Coastguard Worker bool alg_purpose_supports_all;
151*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
152*789431f2SAndroid Build Coastguard Worker add_digests(dev, algorithm, purpose, map, &alg_purpose_supports_all);
153*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
154*789431f2SAndroid Build Coastguard Worker *supports_all &= alg_purpose_supports_all;
155*789431f2SAndroid Build Coastguard Worker }
156*789431f2SAndroid Build Coastguard Worker
157*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
158*789431f2SAndroid Build Coastguard Worker }
159*789431f2SAndroid Build Coastguard Worker
SoftKeymasterDevice(KmVersion version)160*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice::SoftKeymasterDevice(KmVersion version)
161*789431f2SAndroid Build Coastguard Worker : wrapped_km1_device_(nullptr), context_(new (std::nothrow) SoftKeymasterContext(version)),
162*789431f2SAndroid Build Coastguard Worker impl_(new (std::nothrow) AndroidKeymaster(context_, kOperationTableSize)),
163*789431f2SAndroid Build Coastguard Worker configured_(false) {
164*789431f2SAndroid Build Coastguard Worker LOG_I("Creating device");
165*789431f2SAndroid Build Coastguard Worker LOG_D("Device address: %p", this);
166*789431f2SAndroid Build Coastguard Worker
167*789431f2SAndroid Build Coastguard Worker initialize_device_struct(KEYMASTER_SOFTWARE_ONLY | KEYMASTER_BLOBS_ARE_STANDALONE |
168*789431f2SAndroid Build Coastguard Worker KEYMASTER_SUPPORTS_EC);
169*789431f2SAndroid Build Coastguard Worker }
170*789431f2SAndroid Build Coastguard Worker
SoftKeymasterDevice(SoftKeymasterContext * context)171*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice::SoftKeymasterDevice(SoftKeymasterContext* context)
172*789431f2SAndroid Build Coastguard Worker : wrapped_km1_device_(nullptr), context_(context),
173*789431f2SAndroid Build Coastguard Worker impl_(new (std::nothrow) AndroidKeymaster(context_, kOperationTableSize)),
174*789431f2SAndroid Build Coastguard Worker configured_(false) {
175*789431f2SAndroid Build Coastguard Worker LOG_I("Creating test device");
176*789431f2SAndroid Build Coastguard Worker LOG_D("Device address: %p", this);
177*789431f2SAndroid Build Coastguard Worker
178*789431f2SAndroid Build Coastguard Worker initialize_device_struct(KEYMASTER_SOFTWARE_ONLY | KEYMASTER_BLOBS_ARE_STANDALONE |
179*789431f2SAndroid Build Coastguard Worker KEYMASTER_SUPPORTS_EC);
180*789431f2SAndroid Build Coastguard Worker }
181*789431f2SAndroid Build Coastguard Worker
SetHardwareDevice(keymaster1_device_t * keymaster1_device)182*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::SetHardwareDevice(keymaster1_device_t* keymaster1_device) {
183*789431f2SAndroid Build Coastguard Worker assert(keymaster1_device);
184*789431f2SAndroid Build Coastguard Worker LOG_D("Reinitializing SoftKeymasterDevice to use HW keymaster1");
185*789431f2SAndroid Build Coastguard Worker
186*789431f2SAndroid Build Coastguard Worker if (!context_) return KM_ERROR_UNEXPECTED_NULL_POINTER;
187*789431f2SAndroid Build Coastguard Worker
188*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
189*789431f2SAndroid Build Coastguard Worker map_digests(keymaster1_device, &km1_device_digests_, &supports_all_digests_);
190*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
191*789431f2SAndroid Build Coastguard Worker
192*789431f2SAndroid Build Coastguard Worker error = context_->SetHardwareDevice(keymaster1_device);
193*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
194*789431f2SAndroid Build Coastguard Worker
195*789431f2SAndroid Build Coastguard Worker initialize_device_struct(keymaster1_device->flags);
196*789431f2SAndroid Build Coastguard Worker
197*789431f2SAndroid Build Coastguard Worker module_name_ = km1_device_.common.module->name;
198*789431f2SAndroid Build Coastguard Worker module_name_.append(" (Wrapping ");
199*789431f2SAndroid Build Coastguard Worker module_name_.append(keymaster1_device->common.module->name);
200*789431f2SAndroid Build Coastguard Worker module_name_.append(")");
201*789431f2SAndroid Build Coastguard Worker
202*789431f2SAndroid Build Coastguard Worker updated_module_ = *km1_device_.common.module;
203*789431f2SAndroid Build Coastguard Worker updated_module_.name = module_name_.c_str();
204*789431f2SAndroid Build Coastguard Worker
205*789431f2SAndroid Build Coastguard Worker km1_device_.common.module = &updated_module_;
206*789431f2SAndroid Build Coastguard Worker
207*789431f2SAndroid Build Coastguard Worker wrapped_km1_device_ = keymaster1_device;
208*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
209*789431f2SAndroid Build Coastguard Worker }
210*789431f2SAndroid Build Coastguard Worker
Keymaster1DeviceIsGood()211*789431f2SAndroid Build Coastguard Worker bool SoftKeymasterDevice::Keymaster1DeviceIsGood() {
212*789431f2SAndroid Build Coastguard Worker std::vector<keymaster_digest_t> expected_rsa_digests = {
213*789431f2SAndroid Build Coastguard Worker KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
214*789431f2SAndroid Build Coastguard Worker KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
215*789431f2SAndroid Build Coastguard Worker std::vector<keymaster_digest_t> expected_ec_digests = {
216*789431f2SAndroid Build Coastguard Worker KM_DIGEST_NONE, KM_DIGEST_SHA1, KM_DIGEST_SHA_2_224,
217*789431f2SAndroid Build Coastguard Worker KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384, KM_DIGEST_SHA_2_512};
218*789431f2SAndroid Build Coastguard Worker
219*789431f2SAndroid Build Coastguard Worker for (auto& entry : km1_device_digests_) {
220*789431f2SAndroid Build Coastguard Worker if (entry.first.first == KM_ALGORITHM_RSA)
221*789431f2SAndroid Build Coastguard Worker if (!std::is_permutation(entry.second.begin(), entry.second.end(),
222*789431f2SAndroid Build Coastguard Worker expected_rsa_digests.begin()))
223*789431f2SAndroid Build Coastguard Worker return false;
224*789431f2SAndroid Build Coastguard Worker if (entry.first.first == KM_ALGORITHM_EC)
225*789431f2SAndroid Build Coastguard Worker if (!std::is_permutation(entry.second.begin(), entry.second.end(),
226*789431f2SAndroid Build Coastguard Worker expected_ec_digests.begin()))
227*789431f2SAndroid Build Coastguard Worker return false;
228*789431f2SAndroid Build Coastguard Worker }
229*789431f2SAndroid Build Coastguard Worker return true;
230*789431f2SAndroid Build Coastguard Worker }
231*789431f2SAndroid Build Coastguard Worker
initialize_device_struct(uint32_t flags)232*789431f2SAndroid Build Coastguard Worker void SoftKeymasterDevice::initialize_device_struct(uint32_t flags) {
233*789431f2SAndroid Build Coastguard Worker memset(&km1_device_, 0, sizeof(km1_device_));
234*789431f2SAndroid Build Coastguard Worker
235*789431f2SAndroid Build Coastguard Worker km1_device_.common.tag = HARDWARE_DEVICE_TAG;
236*789431f2SAndroid Build Coastguard Worker km1_device_.common.version = 1;
237*789431f2SAndroid Build Coastguard Worker km1_device_.common.module = reinterpret_cast<hw_module_t*>(&soft_keymaster1_device_module);
238*789431f2SAndroid Build Coastguard Worker km1_device_.common.close = &close_device;
239*789431f2SAndroid Build Coastguard Worker
240*789431f2SAndroid Build Coastguard Worker km1_device_.flags = flags;
241*789431f2SAndroid Build Coastguard Worker
242*789431f2SAndroid Build Coastguard Worker km1_device_.context = this;
243*789431f2SAndroid Build Coastguard Worker
244*789431f2SAndroid Build Coastguard Worker // keymaster0 APIs
245*789431f2SAndroid Build Coastguard Worker km1_device_.generate_keypair = nullptr;
246*789431f2SAndroid Build Coastguard Worker km1_device_.import_keypair = nullptr;
247*789431f2SAndroid Build Coastguard Worker km1_device_.get_keypair_public = nullptr;
248*789431f2SAndroid Build Coastguard Worker km1_device_.delete_keypair = nullptr;
249*789431f2SAndroid Build Coastguard Worker km1_device_.delete_all = nullptr;
250*789431f2SAndroid Build Coastguard Worker km1_device_.sign_data = nullptr;
251*789431f2SAndroid Build Coastguard Worker km1_device_.verify_data = nullptr;
252*789431f2SAndroid Build Coastguard Worker
253*789431f2SAndroid Build Coastguard Worker // keymaster1 APIs
254*789431f2SAndroid Build Coastguard Worker km1_device_.get_supported_algorithms = get_supported_algorithms;
255*789431f2SAndroid Build Coastguard Worker km1_device_.get_supported_block_modes = get_supported_block_modes;
256*789431f2SAndroid Build Coastguard Worker km1_device_.get_supported_padding_modes = get_supported_padding_modes;
257*789431f2SAndroid Build Coastguard Worker km1_device_.get_supported_digests = get_supported_digests;
258*789431f2SAndroid Build Coastguard Worker km1_device_.get_supported_import_formats = get_supported_import_formats;
259*789431f2SAndroid Build Coastguard Worker km1_device_.get_supported_export_formats = get_supported_export_formats;
260*789431f2SAndroid Build Coastguard Worker km1_device_.add_rng_entropy = add_rng_entropy;
261*789431f2SAndroid Build Coastguard Worker km1_device_.generate_key = generate_key;
262*789431f2SAndroid Build Coastguard Worker km1_device_.get_key_characteristics = get_key_characteristics;
263*789431f2SAndroid Build Coastguard Worker km1_device_.import_key = import_key;
264*789431f2SAndroid Build Coastguard Worker km1_device_.export_key = export_key;
265*789431f2SAndroid Build Coastguard Worker km1_device_.delete_key = delete_key;
266*789431f2SAndroid Build Coastguard Worker km1_device_.delete_all_keys = delete_all_keys;
267*789431f2SAndroid Build Coastguard Worker km1_device_.begin = begin;
268*789431f2SAndroid Build Coastguard Worker km1_device_.update = update;
269*789431f2SAndroid Build Coastguard Worker km1_device_.finish = finish;
270*789431f2SAndroid Build Coastguard Worker km1_device_.abort = abort;
271*789431f2SAndroid Build Coastguard Worker
272*789431f2SAndroid Build Coastguard Worker // keymaster2 APIs
273*789431f2SAndroid Build Coastguard Worker memset(&km2_device_, 0, sizeof(km2_device_));
274*789431f2SAndroid Build Coastguard Worker
275*789431f2SAndroid Build Coastguard Worker km2_device_.flags = flags;
276*789431f2SAndroid Build Coastguard Worker km2_device_.context = this;
277*789431f2SAndroid Build Coastguard Worker
278*789431f2SAndroid Build Coastguard Worker km2_device_.common.tag = HARDWARE_DEVICE_TAG;
279*789431f2SAndroid Build Coastguard Worker km2_device_.common.version = 1;
280*789431f2SAndroid Build Coastguard Worker km2_device_.common.module = reinterpret_cast<hw_module_t*>(&soft_keymaster2_device_module);
281*789431f2SAndroid Build Coastguard Worker km2_device_.common.close = &close_device;
282*789431f2SAndroid Build Coastguard Worker
283*789431f2SAndroid Build Coastguard Worker km2_device_.configure = configure;
284*789431f2SAndroid Build Coastguard Worker km2_device_.add_rng_entropy = add_rng_entropy;
285*789431f2SAndroid Build Coastguard Worker km2_device_.generate_key = generate_key;
286*789431f2SAndroid Build Coastguard Worker km2_device_.get_key_characteristics = get_key_characteristics;
287*789431f2SAndroid Build Coastguard Worker km2_device_.import_key = import_key;
288*789431f2SAndroid Build Coastguard Worker km2_device_.export_key = export_key;
289*789431f2SAndroid Build Coastguard Worker km2_device_.attest_key = attest_key;
290*789431f2SAndroid Build Coastguard Worker km2_device_.upgrade_key = upgrade_key;
291*789431f2SAndroid Build Coastguard Worker km2_device_.delete_key = delete_key;
292*789431f2SAndroid Build Coastguard Worker km2_device_.delete_all_keys = delete_all_keys;
293*789431f2SAndroid Build Coastguard Worker km2_device_.begin = begin;
294*789431f2SAndroid Build Coastguard Worker km2_device_.update = update;
295*789431f2SAndroid Build Coastguard Worker km2_device_.finish = finish;
296*789431f2SAndroid Build Coastguard Worker km2_device_.abort = abort;
297*789431f2SAndroid Build Coastguard Worker }
298*789431f2SAndroid Build Coastguard Worker
hw_device()299*789431f2SAndroid Build Coastguard Worker hw_device_t* SoftKeymasterDevice::hw_device() {
300*789431f2SAndroid Build Coastguard Worker return &km1_device_.common;
301*789431f2SAndroid Build Coastguard Worker }
302*789431f2SAndroid Build Coastguard Worker
keymaster_device()303*789431f2SAndroid Build Coastguard Worker keymaster1_device_t* SoftKeymasterDevice::keymaster_device() {
304*789431f2SAndroid Build Coastguard Worker return &km1_device_;
305*789431f2SAndroid Build Coastguard Worker }
306*789431f2SAndroid Build Coastguard Worker
keymaster2_device()307*789431f2SAndroid Build Coastguard Worker keymaster2_device_t* SoftKeymasterDevice::keymaster2_device() {
308*789431f2SAndroid Build Coastguard Worker return &km2_device_;
309*789431f2SAndroid Build Coastguard Worker }
310*789431f2SAndroid Build Coastguard Worker
311*789431f2SAndroid Build Coastguard Worker namespace {
312*789431f2SAndroid Build Coastguard Worker
BuildCharacteristics(const AuthorizationSet & hw_enforced,const AuthorizationSet & sw_enforced)313*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t* BuildCharacteristics(const AuthorizationSet& hw_enforced,
314*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& sw_enforced) {
315*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t* characteristics =
316*789431f2SAndroid Build Coastguard Worker reinterpret_cast<keymaster_key_characteristics_t*>(
317*789431f2SAndroid Build Coastguard Worker malloc(sizeof(keymaster_key_characteristics_t)));
318*789431f2SAndroid Build Coastguard Worker if (characteristics) {
319*789431f2SAndroid Build Coastguard Worker hw_enforced.CopyToParamSet(&characteristics->hw_enforced);
320*789431f2SAndroid Build Coastguard Worker sw_enforced.CopyToParamSet(&characteristics->sw_enforced);
321*789431f2SAndroid Build Coastguard Worker }
322*789431f2SAndroid Build Coastguard Worker return characteristics;
323*789431f2SAndroid Build Coastguard Worker }
324*789431f2SAndroid Build Coastguard Worker
325*789431f2SAndroid Build Coastguard Worker template <typename RequestType>
AddClientAndAppData(const keymaster_blob_t * client_id,const keymaster_blob_t * app_data,RequestType * request)326*789431f2SAndroid Build Coastguard Worker void AddClientAndAppData(const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
327*789431f2SAndroid Build Coastguard Worker RequestType* request) {
328*789431f2SAndroid Build Coastguard Worker request->additional_params.Clear();
329*789431f2SAndroid Build Coastguard Worker if (client_id) request->additional_params.push_back(TAG_APPLICATION_ID, *client_id);
330*789431f2SAndroid Build Coastguard Worker if (app_data) request->additional_params.push_back(TAG_APPLICATION_DATA, *app_data);
331*789431f2SAndroid Build Coastguard Worker }
332*789431f2SAndroid Build Coastguard Worker
convert_device(const T * dev)333*789431f2SAndroid Build Coastguard Worker template <typename T> SoftKeymasterDevice* convert_device(const T* dev) {
334*789431f2SAndroid Build Coastguard Worker static_assert((std::is_same<T, keymaster1_device_t>::value ||
335*789431f2SAndroid Build Coastguard Worker std::is_same<T, keymaster2_device_t>::value),
336*789431f2SAndroid Build Coastguard Worker "convert_device should only be applied to keymaster devices");
337*789431f2SAndroid Build Coastguard Worker return reinterpret_cast<SoftKeymasterDevice*>(dev->context);
338*789431f2SAndroid Build Coastguard Worker }
339*789431f2SAndroid Build Coastguard Worker
340*789431f2SAndroid Build Coastguard Worker template <keymaster_tag_t Tag, keymaster_tag_type_t Type, typename KeymasterEnum>
FindTagValue(const keymaster_key_param_set_t & params,TypedEnumTag<Type,Tag,KeymasterEnum> tag,KeymasterEnum * value)341*789431f2SAndroid Build Coastguard Worker bool FindTagValue(const keymaster_key_param_set_t& params,
342*789431f2SAndroid Build Coastguard Worker TypedEnumTag<Type, Tag, KeymasterEnum> tag, KeymasterEnum* value) {
343*789431f2SAndroid Build Coastguard Worker for (size_t i = 0; i < params.length; ++i)
344*789431f2SAndroid Build Coastguard Worker if (params.params[i].tag == tag) {
345*789431f2SAndroid Build Coastguard Worker *value = static_cast<KeymasterEnum>(params.params[i].enumerated);
346*789431f2SAndroid Build Coastguard Worker return true;
347*789431f2SAndroid Build Coastguard Worker }
348*789431f2SAndroid Build Coastguard Worker return false;
349*789431f2SAndroid Build Coastguard Worker }
350*789431f2SAndroid Build Coastguard Worker
351*789431f2SAndroid Build Coastguard Worker } // namespace
352*789431f2SAndroid Build Coastguard Worker
353*789431f2SAndroid Build Coastguard Worker /* static */
close_device(hw_device_t * dev)354*789431f2SAndroid Build Coastguard Worker int SoftKeymasterDevice::close_device(hw_device_t* dev) {
355*789431f2SAndroid Build Coastguard Worker switch (dev->module->module_api_version) {
356*789431f2SAndroid Build Coastguard Worker case KEYMASTER_MODULE_API_VERSION_2_0: {
357*789431f2SAndroid Build Coastguard Worker delete convert_device(reinterpret_cast<keymaster2_device_t*>(dev));
358*789431f2SAndroid Build Coastguard Worker break;
359*789431f2SAndroid Build Coastguard Worker }
360*789431f2SAndroid Build Coastguard Worker
361*789431f2SAndroid Build Coastguard Worker case KEYMASTER_MODULE_API_VERSION_1_0: {
362*789431f2SAndroid Build Coastguard Worker delete convert_device(reinterpret_cast<keymaster1_device_t*>(dev));
363*789431f2SAndroid Build Coastguard Worker break;
364*789431f2SAndroid Build Coastguard Worker }
365*789431f2SAndroid Build Coastguard Worker
366*789431f2SAndroid Build Coastguard Worker default:
367*789431f2SAndroid Build Coastguard Worker return -1;
368*789431f2SAndroid Build Coastguard Worker }
369*789431f2SAndroid Build Coastguard Worker
370*789431f2SAndroid Build Coastguard Worker return 0;
371*789431f2SAndroid Build Coastguard Worker }
372*789431f2SAndroid Build Coastguard Worker
373*789431f2SAndroid Build Coastguard Worker /* static */
get_supported_algorithms(const keymaster1_device_t * dev,keymaster_algorithm_t ** algorithms,size_t * algorithms_length)374*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_supported_algorithms(const keymaster1_device_t* dev,
375*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t** algorithms,
376*789431f2SAndroid Build Coastguard Worker size_t* algorithms_length) {
377*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
378*789431f2SAndroid Build Coastguard Worker
379*789431f2SAndroid Build Coastguard Worker if (!algorithms || !algorithms_length) return KM_ERROR_OUTPUT_PARAMETER_NULL;
380*789431f2SAndroid Build Coastguard Worker
381*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
382*789431f2SAndroid Build Coastguard Worker if (km1_dev) return km1_dev->get_supported_algorithms(km1_dev, algorithms, algorithms_length);
383*789431f2SAndroid Build Coastguard Worker
384*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
385*789431f2SAndroid Build Coastguard Worker SupportedAlgorithmsRequest request(impl_->message_version());
386*789431f2SAndroid Build Coastguard Worker SupportedAlgorithmsResponse response(impl_->message_version());
387*789431f2SAndroid Build Coastguard Worker impl_->SupportedAlgorithms(request, &response);
388*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
389*789431f2SAndroid Build Coastguard Worker LOG_E("get_supported_algorithms failed with %d", response.error);
390*789431f2SAndroid Build Coastguard Worker
391*789431f2SAndroid Build Coastguard Worker return response.error;
392*789431f2SAndroid Build Coastguard Worker }
393*789431f2SAndroid Build Coastguard Worker
394*789431f2SAndroid Build Coastguard Worker *algorithms_length = response.results_length;
395*789431f2SAndroid Build Coastguard Worker *algorithms =
396*789431f2SAndroid Build Coastguard Worker reinterpret_cast<keymaster_algorithm_t*>(malloc(*algorithms_length * sizeof(**algorithms)));
397*789431f2SAndroid Build Coastguard Worker if (!*algorithms) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
398*789431f2SAndroid Build Coastguard Worker std::copy(response.results, response.results + response.results_length, *algorithms);
399*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
400*789431f2SAndroid Build Coastguard Worker }
401*789431f2SAndroid Build Coastguard Worker
402*789431f2SAndroid Build Coastguard Worker /* static */
get_supported_block_modes(const keymaster1_device_t * dev,keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,keymaster_block_mode_t ** modes,size_t * modes_length)403*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_supported_block_modes(const keymaster1_device_t* dev,
404*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t algorithm,
405*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
406*789431f2SAndroid Build Coastguard Worker keymaster_block_mode_t** modes,
407*789431f2SAndroid Build Coastguard Worker size_t* modes_length) {
408*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
409*789431f2SAndroid Build Coastguard Worker
410*789431f2SAndroid Build Coastguard Worker if (!modes || !modes_length) return KM_ERROR_OUTPUT_PARAMETER_NULL;
411*789431f2SAndroid Build Coastguard Worker
412*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
413*789431f2SAndroid Build Coastguard Worker if (km1_dev)
414*789431f2SAndroid Build Coastguard Worker return km1_dev->get_supported_block_modes(km1_dev, algorithm, purpose, modes, modes_length);
415*789431f2SAndroid Build Coastguard Worker
416*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
417*789431f2SAndroid Build Coastguard Worker SupportedBlockModesRequest request(impl_->message_version());
418*789431f2SAndroid Build Coastguard Worker request.algorithm = algorithm;
419*789431f2SAndroid Build Coastguard Worker request.purpose = purpose;
420*789431f2SAndroid Build Coastguard Worker SupportedBlockModesResponse response(impl_->message_version());
421*789431f2SAndroid Build Coastguard Worker impl_->SupportedBlockModes(request, &response);
422*789431f2SAndroid Build Coastguard Worker
423*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
424*789431f2SAndroid Build Coastguard Worker LOG_E("get_supported_block_modes failed with %d", response.error);
425*789431f2SAndroid Build Coastguard Worker
426*789431f2SAndroid Build Coastguard Worker return response.error;
427*789431f2SAndroid Build Coastguard Worker }
428*789431f2SAndroid Build Coastguard Worker
429*789431f2SAndroid Build Coastguard Worker *modes_length = response.results_length;
430*789431f2SAndroid Build Coastguard Worker *modes = reinterpret_cast<keymaster_block_mode_t*>(malloc(*modes_length * sizeof(**modes)));
431*789431f2SAndroid Build Coastguard Worker if (!*modes) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
432*789431f2SAndroid Build Coastguard Worker std::copy(response.results, response.results + response.results_length, *modes);
433*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
434*789431f2SAndroid Build Coastguard Worker }
435*789431f2SAndroid Build Coastguard Worker
436*789431f2SAndroid Build Coastguard Worker /* static */
get_supported_padding_modes(const keymaster1_device_t * dev,keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,keymaster_padding_t ** modes,size_t * modes_length)437*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_supported_padding_modes(const keymaster1_device_t* dev,
438*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t algorithm,
439*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
440*789431f2SAndroid Build Coastguard Worker keymaster_padding_t** modes,
441*789431f2SAndroid Build Coastguard Worker size_t* modes_length) {
442*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
443*789431f2SAndroid Build Coastguard Worker
444*789431f2SAndroid Build Coastguard Worker if (!modes || !modes_length) return KM_ERROR_OUTPUT_PARAMETER_NULL;
445*789431f2SAndroid Build Coastguard Worker
446*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
447*789431f2SAndroid Build Coastguard Worker if (km1_dev)
448*789431f2SAndroid Build Coastguard Worker return km1_dev->get_supported_padding_modes(km1_dev, algorithm, purpose, modes,
449*789431f2SAndroid Build Coastguard Worker modes_length);
450*789431f2SAndroid Build Coastguard Worker
451*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
452*789431f2SAndroid Build Coastguard Worker SupportedPaddingModesRequest request(impl_->message_version());
453*789431f2SAndroid Build Coastguard Worker request.algorithm = algorithm;
454*789431f2SAndroid Build Coastguard Worker request.purpose = purpose;
455*789431f2SAndroid Build Coastguard Worker SupportedPaddingModesResponse response(impl_->message_version());
456*789431f2SAndroid Build Coastguard Worker convert_device(dev)->impl_->SupportedPaddingModes(request, &response);
457*789431f2SAndroid Build Coastguard Worker
458*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
459*789431f2SAndroid Build Coastguard Worker LOG_E("get_supported_padding_modes failed with %d", response.error);
460*789431f2SAndroid Build Coastguard Worker return response.error;
461*789431f2SAndroid Build Coastguard Worker }
462*789431f2SAndroid Build Coastguard Worker
463*789431f2SAndroid Build Coastguard Worker *modes_length = response.results_length;
464*789431f2SAndroid Build Coastguard Worker *modes = reinterpret_cast<keymaster_padding_t*>(malloc(*modes_length * sizeof(**modes)));
465*789431f2SAndroid Build Coastguard Worker if (!*modes) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
466*789431f2SAndroid Build Coastguard Worker std::copy(response.results, response.results + response.results_length, *modes);
467*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
468*789431f2SAndroid Build Coastguard Worker }
469*789431f2SAndroid Build Coastguard Worker
470*789431f2SAndroid Build Coastguard Worker /* static */
get_supported_digests(const keymaster1_device_t * dev,keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,keymaster_digest_t ** digests,size_t * digests_length)471*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_supported_digests(const keymaster1_device_t* dev,
472*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t algorithm,
473*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
474*789431f2SAndroid Build Coastguard Worker keymaster_digest_t** digests,
475*789431f2SAndroid Build Coastguard Worker size_t* digests_length) {
476*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
477*789431f2SAndroid Build Coastguard Worker
478*789431f2SAndroid Build Coastguard Worker if (!digests || !digests_length) return KM_ERROR_OUTPUT_PARAMETER_NULL;
479*789431f2SAndroid Build Coastguard Worker
480*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
481*789431f2SAndroid Build Coastguard Worker if (km1_dev)
482*789431f2SAndroid Build Coastguard Worker return km1_dev->get_supported_digests(km1_dev, algorithm, purpose, digests, digests_length);
483*789431f2SAndroid Build Coastguard Worker
484*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
485*789431f2SAndroid Build Coastguard Worker SupportedDigestsRequest request(impl_->message_version());
486*789431f2SAndroid Build Coastguard Worker request.algorithm = algorithm;
487*789431f2SAndroid Build Coastguard Worker request.purpose = purpose;
488*789431f2SAndroid Build Coastguard Worker SupportedDigestsResponse response(impl_->message_version());
489*789431f2SAndroid Build Coastguard Worker impl_->SupportedDigests(request, &response);
490*789431f2SAndroid Build Coastguard Worker
491*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
492*789431f2SAndroid Build Coastguard Worker LOG_E("get_supported_digests failed with %d", response.error);
493*789431f2SAndroid Build Coastguard Worker return response.error;
494*789431f2SAndroid Build Coastguard Worker }
495*789431f2SAndroid Build Coastguard Worker
496*789431f2SAndroid Build Coastguard Worker *digests_length = response.results_length;
497*789431f2SAndroid Build Coastguard Worker *digests = reinterpret_cast<keymaster_digest_t*>(malloc(*digests_length * sizeof(**digests)));
498*789431f2SAndroid Build Coastguard Worker if (!*digests) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
499*789431f2SAndroid Build Coastguard Worker std::copy(response.results, response.results + response.results_length, *digests);
500*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
501*789431f2SAndroid Build Coastguard Worker }
502*789431f2SAndroid Build Coastguard Worker
503*789431f2SAndroid Build Coastguard Worker /* static */
get_supported_import_formats(const keymaster1_device_t * dev,keymaster_algorithm_t algorithm,keymaster_key_format_t ** formats,size_t * formats_length)504*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_supported_import_formats(
505*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
506*789431f2SAndroid Build Coastguard Worker keymaster_key_format_t** formats, size_t* formats_length) {
507*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
508*789431f2SAndroid Build Coastguard Worker
509*789431f2SAndroid Build Coastguard Worker if (!formats || !formats_length) return KM_ERROR_OUTPUT_PARAMETER_NULL;
510*789431f2SAndroid Build Coastguard Worker
511*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
512*789431f2SAndroid Build Coastguard Worker if (km1_dev)
513*789431f2SAndroid Build Coastguard Worker return km1_dev->get_supported_import_formats(km1_dev, algorithm, formats, formats_length);
514*789431f2SAndroid Build Coastguard Worker
515*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
516*789431f2SAndroid Build Coastguard Worker SupportedImportFormatsRequest request(impl_->message_version());
517*789431f2SAndroid Build Coastguard Worker request.algorithm = algorithm;
518*789431f2SAndroid Build Coastguard Worker SupportedImportFormatsResponse response(impl_->message_version());
519*789431f2SAndroid Build Coastguard Worker impl_->SupportedImportFormats(request, &response);
520*789431f2SAndroid Build Coastguard Worker
521*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
522*789431f2SAndroid Build Coastguard Worker LOG_E("get_supported_import_formats failed with %d", response.error);
523*789431f2SAndroid Build Coastguard Worker return response.error;
524*789431f2SAndroid Build Coastguard Worker }
525*789431f2SAndroid Build Coastguard Worker
526*789431f2SAndroid Build Coastguard Worker *formats_length = response.results_length;
527*789431f2SAndroid Build Coastguard Worker *formats =
528*789431f2SAndroid Build Coastguard Worker reinterpret_cast<keymaster_key_format_t*>(malloc(*formats_length * sizeof(**formats)));
529*789431f2SAndroid Build Coastguard Worker if (!*formats) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
530*789431f2SAndroid Build Coastguard Worker std::copy(response.results, response.results + response.results_length, *formats);
531*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
532*789431f2SAndroid Build Coastguard Worker }
533*789431f2SAndroid Build Coastguard Worker
534*789431f2SAndroid Build Coastguard Worker /* static */
get_supported_export_formats(const keymaster1_device_t * dev,keymaster_algorithm_t algorithm,keymaster_key_format_t ** formats,size_t * formats_length)535*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_supported_export_formats(
536*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* dev, keymaster_algorithm_t algorithm,
537*789431f2SAndroid Build Coastguard Worker keymaster_key_format_t** formats, size_t* formats_length) {
538*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
539*789431f2SAndroid Build Coastguard Worker
540*789431f2SAndroid Build Coastguard Worker if (!formats || !formats_length) return KM_ERROR_OUTPUT_PARAMETER_NULL;
541*789431f2SAndroid Build Coastguard Worker
542*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
543*789431f2SAndroid Build Coastguard Worker if (km1_dev)
544*789431f2SAndroid Build Coastguard Worker return km1_dev->get_supported_export_formats(km1_dev, algorithm, formats, formats_length);
545*789431f2SAndroid Build Coastguard Worker
546*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
547*789431f2SAndroid Build Coastguard Worker SupportedExportFormatsRequest request(impl_->message_version());
548*789431f2SAndroid Build Coastguard Worker request.algorithm = algorithm;
549*789431f2SAndroid Build Coastguard Worker SupportedExportFormatsResponse response(impl_->message_version());
550*789431f2SAndroid Build Coastguard Worker impl_->SupportedExportFormats(request, &response);
551*789431f2SAndroid Build Coastguard Worker
552*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) {
553*789431f2SAndroid Build Coastguard Worker LOG_E("get_supported_export_formats failed with %d", response.error);
554*789431f2SAndroid Build Coastguard Worker return response.error;
555*789431f2SAndroid Build Coastguard Worker }
556*789431f2SAndroid Build Coastguard Worker
557*789431f2SAndroid Build Coastguard Worker *formats_length = response.results_length;
558*789431f2SAndroid Build Coastguard Worker *formats =
559*789431f2SAndroid Build Coastguard Worker reinterpret_cast<keymaster_key_format_t*>(malloc(*formats_length * sizeof(**formats)));
560*789431f2SAndroid Build Coastguard Worker if (!*formats) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
561*789431f2SAndroid Build Coastguard Worker std::copy(response.results, response.results + *formats_length, *formats);
562*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
563*789431f2SAndroid Build Coastguard Worker }
564*789431f2SAndroid Build Coastguard Worker
565*789431f2SAndroid Build Coastguard Worker /* static */
configure(const keymaster2_device_t * dev,const keymaster_key_param_set_t * params)566*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::configure(const keymaster2_device_t* dev,
567*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* params) {
568*789431f2SAndroid Build Coastguard Worker AuthorizationSet params_copy(*params);
569*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
570*789431f2SAndroid Build Coastguard Worker ConfigureRequest request(impl_->message_version());
571*789431f2SAndroid Build Coastguard Worker if (!params_copy.GetTagValue(TAG_OS_VERSION, &request.os_version) ||
572*789431f2SAndroid Build Coastguard Worker !params_copy.GetTagValue(TAG_OS_PATCHLEVEL, &request.os_patchlevel)) {
573*789431f2SAndroid Build Coastguard Worker LOG_E("Configuration parameters must contain OS version and patch level");
574*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
575*789431f2SAndroid Build Coastguard Worker }
576*789431f2SAndroid Build Coastguard Worker ConfigureResponse response(impl_->message_version());
577*789431f2SAndroid Build Coastguard Worker impl_->Configure(request, &response);
578*789431f2SAndroid Build Coastguard Worker if (response.error == KM_ERROR_OK) convert_device(dev)->configured_ = true;
579*789431f2SAndroid Build Coastguard Worker return response.error;
580*789431f2SAndroid Build Coastguard Worker }
581*789431f2SAndroid Build Coastguard Worker
582*789431f2SAndroid Build Coastguard Worker /* static */
add_rng_entropy(const keymaster1_device_t * dev,const uint8_t * data,size_t data_length)583*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::add_rng_entropy(const keymaster1_device_t* dev,
584*789431f2SAndroid Build Coastguard Worker const uint8_t* data, size_t data_length) {
585*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
586*789431f2SAndroid Build Coastguard Worker
587*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
588*789431f2SAndroid Build Coastguard Worker if (km1_dev) return km1_dev->add_rng_entropy(km1_dev, data, data_length);
589*789431f2SAndroid Build Coastguard Worker
590*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
591*789431f2SAndroid Build Coastguard Worker AddEntropyRequest request(impl_->message_version());
592*789431f2SAndroid Build Coastguard Worker request.random_data.Reinitialize(data, data_length);
593*789431f2SAndroid Build Coastguard Worker AddEntropyResponse response(impl_->message_version());
594*789431f2SAndroid Build Coastguard Worker impl_->AddRngEntropy(request, &response);
595*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) LOG_E("add_rng_entropy failed with %d", response.error);
596*789431f2SAndroid Build Coastguard Worker return response.error;
597*789431f2SAndroid Build Coastguard Worker }
598*789431f2SAndroid Build Coastguard Worker
599*789431f2SAndroid Build Coastguard Worker /* static */
add_rng_entropy(const keymaster2_device_t * dev,const uint8_t * data,size_t data_length)600*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::add_rng_entropy(const keymaster2_device_t* dev,
601*789431f2SAndroid Build Coastguard Worker const uint8_t* data, size_t data_length) {
602*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
603*789431f2SAndroid Build Coastguard Worker
604*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
605*789431f2SAndroid Build Coastguard Worker
606*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
607*789431f2SAndroid Build Coastguard Worker return add_rng_entropy(&sk_dev->km1_device_, data, data_length);
608*789431f2SAndroid Build Coastguard Worker }
609*789431f2SAndroid Build Coastguard Worker
contains(const Collection & c,const Value & v)610*789431f2SAndroid Build Coastguard Worker template <typename Collection, typename Value> bool contains(const Collection& c, const Value& v) {
611*789431f2SAndroid Build Coastguard Worker return std::find(c.begin(), c.end(), v) != c.end();
612*789431f2SAndroid Build Coastguard Worker }
613*789431f2SAndroid Build Coastguard Worker
FindUnsupportedDigest(keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,const AuthorizationSet & params,keymaster_digest_t * unsupported) const614*789431f2SAndroid Build Coastguard Worker bool SoftKeymasterDevice::FindUnsupportedDigest(keymaster_algorithm_t algorithm,
615*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
616*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& params,
617*789431f2SAndroid Build Coastguard Worker keymaster_digest_t* unsupported) const {
618*789431f2SAndroid Build Coastguard Worker assert(wrapped_km1_device_);
619*789431f2SAndroid Build Coastguard Worker
620*789431f2SAndroid Build Coastguard Worker auto supported_digests = km1_device_digests_.find(std::make_pair(algorithm, purpose));
621*789431f2SAndroid Build Coastguard Worker if (supported_digests == km1_device_digests_.end())
622*789431f2SAndroid Build Coastguard Worker // Invalid algorith/purpose pair (e.g. EC encrypt). Let the error be handled by HW module.
623*789431f2SAndroid Build Coastguard Worker return false;
624*789431f2SAndroid Build Coastguard Worker
625*789431f2SAndroid Build Coastguard Worker for (auto& entry : params)
626*789431f2SAndroid Build Coastguard Worker if (entry.tag == TAG_DIGEST)
627*789431f2SAndroid Build Coastguard Worker if (!contains(supported_digests->second, entry.enumerated)) {
628*789431f2SAndroid Build Coastguard Worker LOG_I("Digest %d requested but not supported by module %s", entry.enumerated,
629*789431f2SAndroid Build Coastguard Worker wrapped_km1_device_->common.module->name);
630*789431f2SAndroid Build Coastguard Worker *unsupported = static_cast<keymaster_digest_t>(entry.enumerated);
631*789431f2SAndroid Build Coastguard Worker return true;
632*789431f2SAndroid Build Coastguard Worker }
633*789431f2SAndroid Build Coastguard Worker return false;
634*789431f2SAndroid Build Coastguard Worker }
635*789431f2SAndroid Build Coastguard Worker
RequiresSoftwareDigesting(keymaster_algorithm_t algorithm,keymaster_purpose_t purpose,const AuthorizationSet & params) const636*789431f2SAndroid Build Coastguard Worker bool SoftKeymasterDevice::RequiresSoftwareDigesting(keymaster_algorithm_t algorithm,
637*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
638*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& params) const {
639*789431f2SAndroid Build Coastguard Worker assert(wrapped_km1_device_);
640*789431f2SAndroid Build Coastguard Worker if (!wrapped_km1_device_) return true;
641*789431f2SAndroid Build Coastguard Worker
642*789431f2SAndroid Build Coastguard Worker switch (algorithm) {
643*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_AES:
644*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_TRIPLE_DES:
645*789431f2SAndroid Build Coastguard Worker LOG_D("Not performing software digesting for algorithm %d", algorithm);
646*789431f2SAndroid Build Coastguard Worker return false;
647*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_HMAC:
648*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_RSA:
649*789431f2SAndroid Build Coastguard Worker case KM_ALGORITHM_EC:
650*789431f2SAndroid Build Coastguard Worker break;
651*789431f2SAndroid Build Coastguard Worker }
652*789431f2SAndroid Build Coastguard Worker
653*789431f2SAndroid Build Coastguard Worker keymaster_digest_t unsupported;
654*789431f2SAndroid Build Coastguard Worker if (!FindUnsupportedDigest(algorithm, purpose, params, &unsupported)) {
655*789431f2SAndroid Build Coastguard Worker LOG_D("Requested digest(s) supported for algorithm %d and purpose %d", algorithm, purpose);
656*789431f2SAndroid Build Coastguard Worker return false;
657*789431f2SAndroid Build Coastguard Worker }
658*789431f2SAndroid Build Coastguard Worker
659*789431f2SAndroid Build Coastguard Worker return true;
660*789431f2SAndroid Build Coastguard Worker }
661*789431f2SAndroid Build Coastguard Worker
KeyRequiresSoftwareDigesting(const AuthorizationSet & key_description) const662*789431f2SAndroid Build Coastguard Worker bool SoftKeymasterDevice::KeyRequiresSoftwareDigesting(
663*789431f2SAndroid Build Coastguard Worker const AuthorizationSet& key_description) const {
664*789431f2SAndroid Build Coastguard Worker assert(wrapped_km1_device_);
665*789431f2SAndroid Build Coastguard Worker if (!wrapped_km1_device_) return true;
666*789431f2SAndroid Build Coastguard Worker
667*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t algorithm;
668*789431f2SAndroid Build Coastguard Worker if (!key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) {
669*789431f2SAndroid Build Coastguard Worker // The hardware module will return an error during keygen.
670*789431f2SAndroid Build Coastguard Worker return false;
671*789431f2SAndroid Build Coastguard Worker }
672*789431f2SAndroid Build Coastguard Worker
673*789431f2SAndroid Build Coastguard Worker for (auto& entry : key_description)
674*789431f2SAndroid Build Coastguard Worker if (entry.tag == TAG_PURPOSE) {
675*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(entry.enumerated);
676*789431f2SAndroid Build Coastguard Worker if (RequiresSoftwareDigesting(algorithm, purpose, key_description)) return true;
677*789431f2SAndroid Build Coastguard Worker }
678*789431f2SAndroid Build Coastguard Worker
679*789431f2SAndroid Build Coastguard Worker return false;
680*789431f2SAndroid Build Coastguard Worker }
681*789431f2SAndroid Build Coastguard Worker
682*789431f2SAndroid Build Coastguard Worker /* static */
generate_key(const keymaster1_device_t * dev,const keymaster_key_param_set_t * params,keymaster_key_blob_t * key_blob,keymaster_key_characteristics_t ** characteristics)683*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::generate_key(
684*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
685*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
686*789431f2SAndroid Build Coastguard Worker if (!dev || !params) return KM_ERROR_UNEXPECTED_NULL_POINTER;
687*789431f2SAndroid Build Coastguard Worker
688*789431f2SAndroid Build Coastguard Worker if (!key_blob) return KM_ERROR_OUTPUT_PARAMETER_NULL;
689*789431f2SAndroid Build Coastguard Worker
690*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
691*789431f2SAndroid Build Coastguard Worker
692*789431f2SAndroid Build Coastguard Worker auto& impl_ = sk_dev->impl_;
693*789431f2SAndroid Build Coastguard Worker GenerateKeyRequest request(impl_->message_version());
694*789431f2SAndroid Build Coastguard Worker request.key_description.Reinitialize(*params);
695*789431f2SAndroid Build Coastguard Worker
696*789431f2SAndroid Build Coastguard Worker keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
697*789431f2SAndroid Build Coastguard Worker if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description))
698*789431f2SAndroid Build Coastguard Worker return km1_dev->generate_key(km1_dev, params, key_blob, characteristics);
699*789431f2SAndroid Build Coastguard Worker
700*789431f2SAndroid Build Coastguard Worker GenerateKeyResponse response(impl_->message_version());
701*789431f2SAndroid Build Coastguard Worker impl_->GenerateKey(request, &response);
702*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
703*789431f2SAndroid Build Coastguard Worker
704*789431f2SAndroid Build Coastguard Worker key_blob->key_material_size = response.key_blob.key_material_size;
705*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
706*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
707*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.key_blob.key_material, response.key_blob.key_material_size);
708*789431f2SAndroid Build Coastguard Worker key_blob->key_material = tmp;
709*789431f2SAndroid Build Coastguard Worker
710*789431f2SAndroid Build Coastguard Worker if (characteristics) {
711*789431f2SAndroid Build Coastguard Worker // This is a keymaster1 method, and keymaster1 doesn't include version info, so remove it.
712*789431f2SAndroid Build Coastguard Worker response.enforced.erase(response.enforced.find(TAG_OS_VERSION));
713*789431f2SAndroid Build Coastguard Worker response.enforced.erase(response.enforced.find(TAG_OS_PATCHLEVEL));
714*789431f2SAndroid Build Coastguard Worker response.unenforced.erase(response.unenforced.find(TAG_OS_VERSION));
715*789431f2SAndroid Build Coastguard Worker response.unenforced.erase(response.unenforced.find(TAG_OS_PATCHLEVEL));
716*789431f2SAndroid Build Coastguard Worker
717*789431f2SAndroid Build Coastguard Worker *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
718*789431f2SAndroid Build Coastguard Worker if (!*characteristics) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
719*789431f2SAndroid Build Coastguard Worker }
720*789431f2SAndroid Build Coastguard Worker
721*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
722*789431f2SAndroid Build Coastguard Worker }
723*789431f2SAndroid Build Coastguard Worker
724*789431f2SAndroid Build Coastguard Worker keymaster_error_t
generate_key(const keymaster2_device_t * dev,const keymaster_key_param_set_t * params,keymaster_key_blob_t * key_blob,keymaster_key_characteristics_t * characteristics)725*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice::generate_key(const keymaster2_device_t* dev, //
726*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* params,
727*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t* key_blob,
728*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t* characteristics) {
729*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
730*789431f2SAndroid Build Coastguard Worker
731*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
732*789431f2SAndroid Build Coastguard Worker
733*789431f2SAndroid Build Coastguard Worker if (!key_blob) return KM_ERROR_OUTPUT_PARAMETER_NULL;
734*789431f2SAndroid Build Coastguard Worker
735*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
736*789431f2SAndroid Build Coastguard Worker
737*789431f2SAndroid Build Coastguard Worker auto& impl_ = sk_dev->impl_;
738*789431f2SAndroid Build Coastguard Worker GenerateKeyRequest request(impl_->message_version());
739*789431f2SAndroid Build Coastguard Worker request.key_description.Reinitialize(*params);
740*789431f2SAndroid Build Coastguard Worker
741*789431f2SAndroid Build Coastguard Worker keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
742*789431f2SAndroid Build Coastguard Worker if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description)) {
743*789431f2SAndroid Build Coastguard Worker keymaster_ec_curve_t curve;
744*789431f2SAndroid Build Coastguard Worker if (request.key_description.Contains(TAG_ALGORITHM, KM_ALGORITHM_EC) &&
745*789431f2SAndroid Build Coastguard Worker request.key_description.GetTagValue(TAG_EC_CURVE, &curve)) {
746*789431f2SAndroid Build Coastguard Worker // Keymaster1 doesn't know about EC curves. We need to translate to key size.
747*789431f2SAndroid Build Coastguard Worker uint32_t key_size_from_curve;
748*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = EcCurveToKeySize(curve, &key_size_from_curve);
749*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) {
750*789431f2SAndroid Build Coastguard Worker return error;
751*789431f2SAndroid Build Coastguard Worker }
752*789431f2SAndroid Build Coastguard Worker
753*789431f2SAndroid Build Coastguard Worker uint32_t key_size_from_desc;
754*789431f2SAndroid Build Coastguard Worker if (request.key_description.GetTagValue(TAG_KEY_SIZE, &key_size_from_desc)) {
755*789431f2SAndroid Build Coastguard Worker if (key_size_from_desc != key_size_from_curve) {
756*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_ARGUMENT;
757*789431f2SAndroid Build Coastguard Worker }
758*789431f2SAndroid Build Coastguard Worker } else {
759*789431f2SAndroid Build Coastguard Worker request.key_description.push_back(TAG_KEY_SIZE, key_size_from_curve);
760*789431f2SAndroid Build Coastguard Worker }
761*789431f2SAndroid Build Coastguard Worker }
762*789431f2SAndroid Build Coastguard Worker
763*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t* chars_ptr;
764*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = km1_dev->generate_key(km1_dev, &request.key_description, key_blob,
765*789431f2SAndroid Build Coastguard Worker characteristics ? &chars_ptr : nullptr);
766*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) return error;
767*789431f2SAndroid Build Coastguard Worker
768*789431f2SAndroid Build Coastguard Worker if (characteristics) {
769*789431f2SAndroid Build Coastguard Worker *characteristics = *chars_ptr;
770*789431f2SAndroid Build Coastguard Worker free(chars_ptr);
771*789431f2SAndroid Build Coastguard Worker }
772*789431f2SAndroid Build Coastguard Worker
773*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
774*789431f2SAndroid Build Coastguard Worker }
775*789431f2SAndroid Build Coastguard Worker
776*789431f2SAndroid Build Coastguard Worker GenerateKeyResponse response(impl_->message_version());
777*789431f2SAndroid Build Coastguard Worker impl_->GenerateKey(request, &response);
778*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
779*789431f2SAndroid Build Coastguard Worker
780*789431f2SAndroid Build Coastguard Worker key_blob->key_material_size = response.key_blob.key_material_size;
781*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
782*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
783*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.key_blob.key_material, response.key_blob.key_material_size);
784*789431f2SAndroid Build Coastguard Worker key_blob->key_material = tmp;
785*789431f2SAndroid Build Coastguard Worker
786*789431f2SAndroid Build Coastguard Worker if (characteristics) {
787*789431f2SAndroid Build Coastguard Worker response.enforced.CopyToParamSet(&characteristics->hw_enforced);
788*789431f2SAndroid Build Coastguard Worker response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
789*789431f2SAndroid Build Coastguard Worker }
790*789431f2SAndroid Build Coastguard Worker
791*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
792*789431f2SAndroid Build Coastguard Worker }
793*789431f2SAndroid Build Coastguard Worker
794*789431f2SAndroid Build Coastguard Worker /* static */
get_key_characteristics(const keymaster1_device_t * dev,const keymaster_key_blob_t * key_blob,const keymaster_blob_t * client_id,const keymaster_blob_t * app_data,keymaster_key_characteristics_t ** characteristics)795*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_key_characteristics(
796*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* dev, const keymaster_key_blob_t* key_blob,
797*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
798*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t** characteristics) {
799*789431f2SAndroid Build Coastguard Worker if (!dev || !key_blob || !key_blob->key_material) return KM_ERROR_UNEXPECTED_NULL_POINTER;
800*789431f2SAndroid Build Coastguard Worker
801*789431f2SAndroid Build Coastguard Worker if (!characteristics) return KM_ERROR_OUTPUT_PARAMETER_NULL;
802*789431f2SAndroid Build Coastguard Worker
803*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
804*789431f2SAndroid Build Coastguard Worker if (km1_dev) {
805*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = km1_dev->get_key_characteristics(km1_dev, key_blob, client_id,
806*789431f2SAndroid Build Coastguard Worker app_data, characteristics);
807*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_INVALID_KEY_BLOB) {
808*789431f2SAndroid Build Coastguard Worker return error;
809*789431f2SAndroid Build Coastguard Worker }
810*789431f2SAndroid Build Coastguard Worker // If we got "invalid blob", continue to try with the software device. This might be a
811*789431f2SAndroid Build Coastguard Worker // software key blob.
812*789431f2SAndroid Build Coastguard Worker }
813*789431f2SAndroid Build Coastguard Worker
814*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
815*789431f2SAndroid Build Coastguard Worker GetKeyCharacteristicsRequest request(impl_->message_version());
816*789431f2SAndroid Build Coastguard Worker request.SetKeyMaterial(*key_blob);
817*789431f2SAndroid Build Coastguard Worker AddClientAndAppData(client_id, app_data, &request);
818*789431f2SAndroid Build Coastguard Worker
819*789431f2SAndroid Build Coastguard Worker GetKeyCharacteristicsResponse response(impl_->message_version());
820*789431f2SAndroid Build Coastguard Worker impl_->GetKeyCharacteristics(request, &response);
821*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
822*789431f2SAndroid Build Coastguard Worker
823*789431f2SAndroid Build Coastguard Worker // This is a keymaster1 method, and keymaster1 doesn't include version info, so remove it.
824*789431f2SAndroid Build Coastguard Worker response.enforced.erase(response.enforced.find(TAG_OS_VERSION));
825*789431f2SAndroid Build Coastguard Worker response.enforced.erase(response.enforced.find(TAG_OS_PATCHLEVEL));
826*789431f2SAndroid Build Coastguard Worker response.unenforced.erase(response.unenforced.find(TAG_OS_VERSION));
827*789431f2SAndroid Build Coastguard Worker response.unenforced.erase(response.unenforced.find(TAG_OS_PATCHLEVEL));
828*789431f2SAndroid Build Coastguard Worker
829*789431f2SAndroid Build Coastguard Worker *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
830*789431f2SAndroid Build Coastguard Worker if (!*characteristics) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
831*789431f2SAndroid Build Coastguard Worker
832*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
833*789431f2SAndroid Build Coastguard Worker }
834*789431f2SAndroid Build Coastguard Worker
835*789431f2SAndroid Build Coastguard Worker /* static */
get_key_characteristics(const keymaster2_device_t * dev,const keymaster_key_blob_t * key_blob,const keymaster_blob_t * client_id,const keymaster_blob_t * app_data,keymaster_key_characteristics_t * characteristics)836*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::get_key_characteristics(
837*789431f2SAndroid Build Coastguard Worker const keymaster2_device_t* dev, const keymaster_key_blob_t* key_blob,
838*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* client_id, const keymaster_blob_t* app_data,
839*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t* characteristics) {
840*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
841*789431f2SAndroid Build Coastguard Worker
842*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
843*789431f2SAndroid Build Coastguard Worker
844*789431f2SAndroid Build Coastguard Worker if (!characteristics) return KM_ERROR_OUTPUT_PARAMETER_NULL;
845*789431f2SAndroid Build Coastguard Worker
846*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
847*789431f2SAndroid Build Coastguard Worker
848*789431f2SAndroid Build Coastguard Worker auto& impl_ = sk_dev->impl_;
849*789431f2SAndroid Build Coastguard Worker GetKeyCharacteristicsRequest request(impl_->message_version());
850*789431f2SAndroid Build Coastguard Worker request.SetKeyMaterial(*key_blob);
851*789431f2SAndroid Build Coastguard Worker AddClientAndAppData(client_id, app_data, &request);
852*789431f2SAndroid Build Coastguard Worker
853*789431f2SAndroid Build Coastguard Worker GetKeyCharacteristicsResponse response(impl_->message_version());
854*789431f2SAndroid Build Coastguard Worker impl_->GetKeyCharacteristics(request, &response);
855*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
856*789431f2SAndroid Build Coastguard Worker
857*789431f2SAndroid Build Coastguard Worker response.enforced.CopyToParamSet(&characteristics->hw_enforced);
858*789431f2SAndroid Build Coastguard Worker response.unenforced.CopyToParamSet(&characteristics->sw_enforced);
859*789431f2SAndroid Build Coastguard Worker
860*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
861*789431f2SAndroid Build Coastguard Worker }
862*789431f2SAndroid Build Coastguard Worker
863*789431f2SAndroid Build Coastguard Worker /* static */
import_key(const keymaster1_device_t * dev,const keymaster_key_param_set_t * params,keymaster_key_format_t key_format,const keymaster_blob_t * key_data,keymaster_key_blob_t * key_blob,keymaster_key_characteristics_t ** characteristics)864*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::import_key(
865*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* dev, const keymaster_key_param_set_t* params,
866*789431f2SAndroid Build Coastguard Worker keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
867*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) {
868*789431f2SAndroid Build Coastguard Worker if (!params || !key_data) return KM_ERROR_UNEXPECTED_NULL_POINTER;
869*789431f2SAndroid Build Coastguard Worker
870*789431f2SAndroid Build Coastguard Worker if (!key_blob) return KM_ERROR_OUTPUT_PARAMETER_NULL;
871*789431f2SAndroid Build Coastguard Worker
872*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
873*789431f2SAndroid Build Coastguard Worker
874*789431f2SAndroid Build Coastguard Worker auto& impl_ = sk_dev->impl_;
875*789431f2SAndroid Build Coastguard Worker ImportKeyRequest request(impl_->message_version());
876*789431f2SAndroid Build Coastguard Worker request.key_description.Reinitialize(*params);
877*789431f2SAndroid Build Coastguard Worker
878*789431f2SAndroid Build Coastguard Worker keymaster1_device_t* km1_dev = sk_dev->wrapped_km1_device_;
879*789431f2SAndroid Build Coastguard Worker if (km1_dev && !sk_dev->KeyRequiresSoftwareDigesting(request.key_description))
880*789431f2SAndroid Build Coastguard Worker return km1_dev->import_key(km1_dev, params, key_format, key_data, key_blob,
881*789431f2SAndroid Build Coastguard Worker characteristics);
882*789431f2SAndroid Build Coastguard Worker
883*789431f2SAndroid Build Coastguard Worker if (characteristics) *characteristics = nullptr;
884*789431f2SAndroid Build Coastguard Worker
885*789431f2SAndroid Build Coastguard Worker request.key_format = key_format;
886*789431f2SAndroid Build Coastguard Worker request.key_data = KeymasterKeyBlob(key_data->data, key_data->data_length);
887*789431f2SAndroid Build Coastguard Worker
888*789431f2SAndroid Build Coastguard Worker ImportKeyResponse response(impl_->message_version());
889*789431f2SAndroid Build Coastguard Worker impl_->ImportKey(request, &response);
890*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
891*789431f2SAndroid Build Coastguard Worker
892*789431f2SAndroid Build Coastguard Worker key_blob->key_material_size = response.key_blob.key_material_size;
893*789431f2SAndroid Build Coastguard Worker key_blob->key_material = reinterpret_cast<uint8_t*>(malloc(key_blob->key_material_size));
894*789431f2SAndroid Build Coastguard Worker if (!key_blob->key_material) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
895*789431f2SAndroid Build Coastguard Worker memcpy(const_cast<uint8_t*>(key_blob->key_material), response.key_blob.key_material,
896*789431f2SAndroid Build Coastguard Worker response.key_blob.key_material_size);
897*789431f2SAndroid Build Coastguard Worker
898*789431f2SAndroid Build Coastguard Worker if (characteristics) {
899*789431f2SAndroid Build Coastguard Worker *characteristics = BuildCharacteristics(response.enforced, response.unenforced);
900*789431f2SAndroid Build Coastguard Worker if (!*characteristics) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
901*789431f2SAndroid Build Coastguard Worker }
902*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
903*789431f2SAndroid Build Coastguard Worker }
904*789431f2SAndroid Build Coastguard Worker
905*789431f2SAndroid Build Coastguard Worker /* static */
import_key(const keymaster2_device_t * dev,const keymaster_key_param_set_t * params,keymaster_key_format_t key_format,const keymaster_blob_t * key_data,keymaster_key_blob_t * key_blob,keymaster_key_characteristics_t * characteristics)906*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::import_key(
907*789431f2SAndroid Build Coastguard Worker const keymaster2_device_t* dev, const keymaster_key_param_set_t* params,
908*789431f2SAndroid Build Coastguard Worker keymaster_key_format_t key_format, const keymaster_blob_t* key_data,
909*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics) {
910*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
911*789431f2SAndroid Build Coastguard Worker
912*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
913*789431f2SAndroid Build Coastguard Worker
914*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
915*789431f2SAndroid Build Coastguard Worker
916*789431f2SAndroid Build Coastguard Worker keymaster_error_t error;
917*789431f2SAndroid Build Coastguard Worker if (characteristics) {
918*789431f2SAndroid Build Coastguard Worker keymaster_key_characteristics_t* characteristics_ptr;
919*789431f2SAndroid Build Coastguard Worker error = import_key(&sk_dev->km1_device_, params, key_format, key_data, key_blob,
920*789431f2SAndroid Build Coastguard Worker &characteristics_ptr);
921*789431f2SAndroid Build Coastguard Worker if (error == KM_ERROR_OK) {
922*789431f2SAndroid Build Coastguard Worker *characteristics = *characteristics_ptr;
923*789431f2SAndroid Build Coastguard Worker free(characteristics_ptr);
924*789431f2SAndroid Build Coastguard Worker }
925*789431f2SAndroid Build Coastguard Worker } else {
926*789431f2SAndroid Build Coastguard Worker error = import_key(&sk_dev->km1_device_, params, key_format, key_data, key_blob, nullptr);
927*789431f2SAndroid Build Coastguard Worker }
928*789431f2SAndroid Build Coastguard Worker
929*789431f2SAndroid Build Coastguard Worker return error;
930*789431f2SAndroid Build Coastguard Worker }
931*789431f2SAndroid Build Coastguard Worker
932*789431f2SAndroid Build Coastguard Worker /* static */
export_key(const keymaster1_device_t * dev,keymaster_key_format_t export_format,const keymaster_key_blob_t * key_to_export,const keymaster_blob_t * client_id,const keymaster_blob_t * app_data,keymaster_blob_t * export_data)933*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::export_key(const keymaster1_device_t* dev,
934*789431f2SAndroid Build Coastguard Worker keymaster_key_format_t export_format,
935*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key_to_export,
936*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* client_id,
937*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* app_data,
938*789431f2SAndroid Build Coastguard Worker keymaster_blob_t* export_data) {
939*789431f2SAndroid Build Coastguard Worker if (!key_to_export || !key_to_export->key_material) return KM_ERROR_UNEXPECTED_NULL_POINTER;
940*789431f2SAndroid Build Coastguard Worker
941*789431f2SAndroid Build Coastguard Worker if (!export_data) return KM_ERROR_OUTPUT_PARAMETER_NULL;
942*789431f2SAndroid Build Coastguard Worker
943*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
944*789431f2SAndroid Build Coastguard Worker if (km1_dev)
945*789431f2SAndroid Build Coastguard Worker return km1_dev->export_key(km1_dev, export_format, key_to_export, client_id, app_data,
946*789431f2SAndroid Build Coastguard Worker export_data);
947*789431f2SAndroid Build Coastguard Worker
948*789431f2SAndroid Build Coastguard Worker export_data->data = nullptr;
949*789431f2SAndroid Build Coastguard Worker export_data->data_length = 0;
950*789431f2SAndroid Build Coastguard Worker
951*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
952*789431f2SAndroid Build Coastguard Worker ExportKeyRequest request(impl_->message_version());
953*789431f2SAndroid Build Coastguard Worker request.key_format = export_format;
954*789431f2SAndroid Build Coastguard Worker request.SetKeyMaterial(*key_to_export);
955*789431f2SAndroid Build Coastguard Worker AddClientAndAppData(client_id, app_data, &request);
956*789431f2SAndroid Build Coastguard Worker
957*789431f2SAndroid Build Coastguard Worker ExportKeyResponse response(impl_->message_version());
958*789431f2SAndroid Build Coastguard Worker impl_->ExportKey(request, &response);
959*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
960*789431f2SAndroid Build Coastguard Worker
961*789431f2SAndroid Build Coastguard Worker export_data->data_length = response.key_data_length;
962*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(export_data->data_length));
963*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
964*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.key_data, export_data->data_length);
965*789431f2SAndroid Build Coastguard Worker export_data->data = tmp;
966*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
967*789431f2SAndroid Build Coastguard Worker }
968*789431f2SAndroid Build Coastguard Worker
969*789431f2SAndroid Build Coastguard Worker /* static */
export_key(const keymaster2_device_t * dev,keymaster_key_format_t export_format,const keymaster_key_blob_t * key_to_export,const keymaster_blob_t * client_id,const keymaster_blob_t * app_data,keymaster_blob_t * export_data)970*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::export_key(const keymaster2_device_t* dev,
971*789431f2SAndroid Build Coastguard Worker keymaster_key_format_t export_format,
972*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key_to_export,
973*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* client_id,
974*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* app_data,
975*789431f2SAndroid Build Coastguard Worker keymaster_blob_t* export_data) {
976*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
977*789431f2SAndroid Build Coastguard Worker
978*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
979*789431f2SAndroid Build Coastguard Worker
980*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
981*789431f2SAndroid Build Coastguard Worker return export_key(&sk_dev->km1_device_, export_format, key_to_export, client_id, app_data,
982*789431f2SAndroid Build Coastguard Worker export_data);
983*789431f2SAndroid Build Coastguard Worker }
984*789431f2SAndroid Build Coastguard Worker
985*789431f2SAndroid Build Coastguard Worker /* static */
attest_key(const keymaster2_device_t * dev,const keymaster_key_blob_t * key_to_attest,const keymaster_key_param_set_t * attest_params,keymaster_cert_chain_t * cert_chain)986*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::attest_key(const keymaster2_device_t* dev,
987*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key_to_attest,
988*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* attest_params,
989*789431f2SAndroid Build Coastguard Worker keymaster_cert_chain_t* cert_chain) {
990*789431f2SAndroid Build Coastguard Worker if (!dev || !key_to_attest || !attest_params || !cert_chain)
991*789431f2SAndroid Build Coastguard Worker return KM_ERROR_UNEXPECTED_NULL_POINTER;
992*789431f2SAndroid Build Coastguard Worker
993*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
994*789431f2SAndroid Build Coastguard Worker
995*789431f2SAndroid Build Coastguard Worker *cert_chain = {};
996*789431f2SAndroid Build Coastguard Worker
997*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
998*789431f2SAndroid Build Coastguard Worker AttestKeyRequest request(impl_->message_version());
999*789431f2SAndroid Build Coastguard Worker request.SetKeyMaterial(*key_to_attest);
1000*789431f2SAndroid Build Coastguard Worker request.attest_params.Reinitialize(*attest_params);
1001*789431f2SAndroid Build Coastguard Worker
1002*789431f2SAndroid Build Coastguard Worker keymaster_blob_t attestation_challenge = {};
1003*789431f2SAndroid Build Coastguard Worker request.attest_params.GetTagValue(TAG_ATTESTATION_CHALLENGE, &attestation_challenge);
1004*789431f2SAndroid Build Coastguard Worker if (attestation_challenge.data_length > kMaximumAttestationChallengeLength) {
1005*789431f2SAndroid Build Coastguard Worker LOG_E("%zu-byte attestation challenge; only %zu bytes allowed",
1006*789431f2SAndroid Build Coastguard Worker attestation_challenge.data_length, kMaximumAttestationChallengeLength);
1007*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_INPUT_LENGTH;
1008*789431f2SAndroid Build Coastguard Worker }
1009*789431f2SAndroid Build Coastguard Worker
1010*789431f2SAndroid Build Coastguard Worker AttestKeyResponse response(impl_->message_version());
1011*789431f2SAndroid Build Coastguard Worker impl_->AttestKey(request, &response);
1012*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
1013*789431f2SAndroid Build Coastguard Worker
1014*789431f2SAndroid Build Coastguard Worker // Allocate and clear storage for cert_chain.
1015*789431f2SAndroid Build Coastguard Worker keymaster_cert_chain_t& rsp_chain = response.certificate_chain;
1016*789431f2SAndroid Build Coastguard Worker cert_chain->entries = reinterpret_cast<keymaster_blob_t*>(
1017*789431f2SAndroid Build Coastguard Worker malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries)));
1018*789431f2SAndroid Build Coastguard Worker if (!cert_chain->entries) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1019*789431f2SAndroid Build Coastguard Worker cert_chain->entry_count = rsp_chain.entry_count;
1020*789431f2SAndroid Build Coastguard Worker for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count))
1021*789431f2SAndroid Build Coastguard Worker entry = {};
1022*789431f2SAndroid Build Coastguard Worker
1023*789431f2SAndroid Build Coastguard Worker // Copy cert_chain contents
1024*789431f2SAndroid Build Coastguard Worker size_t i = 0;
1025*789431f2SAndroid Build Coastguard Worker for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) {
1026*789431f2SAndroid Build Coastguard Worker cert_chain->entries[i].data = reinterpret_cast<uint8_t*>(malloc(entry.data_length));
1027*789431f2SAndroid Build Coastguard Worker if (!cert_chain->entries[i].data) {
1028*789431f2SAndroid Build Coastguard Worker keymaster_free_cert_chain(cert_chain);
1029*789431f2SAndroid Build Coastguard Worker return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1030*789431f2SAndroid Build Coastguard Worker }
1031*789431f2SAndroid Build Coastguard Worker cert_chain->entries[i].data_length = entry.data_length;
1032*789431f2SAndroid Build Coastguard Worker memcpy(const_cast<uint8_t*>(cert_chain->entries[i].data), entry.data, entry.data_length);
1033*789431f2SAndroid Build Coastguard Worker ++i;
1034*789431f2SAndroid Build Coastguard Worker }
1035*789431f2SAndroid Build Coastguard Worker
1036*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1037*789431f2SAndroid Build Coastguard Worker }
1038*789431f2SAndroid Build Coastguard Worker
1039*789431f2SAndroid Build Coastguard Worker /* static */
upgrade_key(const keymaster2_device_t * dev,const keymaster_key_blob_t * key_to_upgrade,const keymaster_key_param_set_t * upgrade_params,keymaster_key_blob_t * upgraded_key)1040*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::upgrade_key(const keymaster2_device_t* dev,
1041*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key_to_upgrade,
1042*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* upgrade_params,
1043*789431f2SAndroid Build Coastguard Worker keymaster_key_blob_t* upgraded_key) {
1044*789431f2SAndroid Build Coastguard Worker if (!dev || !key_to_upgrade || !upgrade_params) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1045*789431f2SAndroid Build Coastguard Worker
1046*789431f2SAndroid Build Coastguard Worker if (!upgraded_key) return KM_ERROR_OUTPUT_PARAMETER_NULL;
1047*789431f2SAndroid Build Coastguard Worker
1048*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1049*789431f2SAndroid Build Coastguard Worker
1050*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
1051*789431f2SAndroid Build Coastguard Worker UpgradeKeyRequest request(impl_->message_version());
1052*789431f2SAndroid Build Coastguard Worker request.SetKeyMaterial(*key_to_upgrade);
1053*789431f2SAndroid Build Coastguard Worker request.upgrade_params.Reinitialize(*upgrade_params);
1054*789431f2SAndroid Build Coastguard Worker
1055*789431f2SAndroid Build Coastguard Worker UpgradeKeyResponse response(impl_->message_version());
1056*789431f2SAndroid Build Coastguard Worker impl_->UpgradeKey(request, &response);
1057*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
1058*789431f2SAndroid Build Coastguard Worker
1059*789431f2SAndroid Build Coastguard Worker upgraded_key->key_material_size = response.upgraded_key.key_material_size;
1060*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(upgraded_key->key_material_size));
1061*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1062*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.upgraded_key.key_material, response.upgraded_key.key_material_size);
1063*789431f2SAndroid Build Coastguard Worker upgraded_key->key_material = tmp;
1064*789431f2SAndroid Build Coastguard Worker
1065*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1066*789431f2SAndroid Build Coastguard Worker }
1067*789431f2SAndroid Build Coastguard Worker
1068*789431f2SAndroid Build Coastguard Worker /* static */
delete_key(const keymaster1_device_t * dev,const keymaster_key_blob_t * key)1069*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::delete_key(const keymaster1_device_t* dev,
1070*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key) {
1071*789431f2SAndroid Build Coastguard Worker if (!dev || !key || !key->key_material) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1072*789431f2SAndroid Build Coastguard Worker
1073*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob blob(*key);
1074*789431f2SAndroid Build Coastguard Worker return convert_device(dev)->context_->DeleteKey(blob);
1075*789431f2SAndroid Build Coastguard Worker }
1076*789431f2SAndroid Build Coastguard Worker
1077*789431f2SAndroid Build Coastguard Worker /* static */
delete_key(const keymaster2_device_t * dev,const keymaster_key_blob_t * key)1078*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::delete_key(const keymaster2_device_t* dev,
1079*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key) {
1080*789431f2SAndroid Build Coastguard Worker if (!dev || !key || !key->key_material) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1081*789431f2SAndroid Build Coastguard Worker
1082*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1083*789431f2SAndroid Build Coastguard Worker
1084*789431f2SAndroid Build Coastguard Worker KeymasterKeyBlob blob(*key);
1085*789431f2SAndroid Build Coastguard Worker return convert_device(dev)->context_->DeleteKey(blob);
1086*789431f2SAndroid Build Coastguard Worker }
1087*789431f2SAndroid Build Coastguard Worker
1088*789431f2SAndroid Build Coastguard Worker /* static */
delete_all_keys(const keymaster1_device_t * dev)1089*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::delete_all_keys(const keymaster1_device_t* dev) {
1090*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1091*789431f2SAndroid Build Coastguard Worker
1092*789431f2SAndroid Build Coastguard Worker return convert_device(dev)->context_->DeleteAllKeys();
1093*789431f2SAndroid Build Coastguard Worker }
1094*789431f2SAndroid Build Coastguard Worker
1095*789431f2SAndroid Build Coastguard Worker /* static */
delete_all_keys(const keymaster2_device_t * dev)1096*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::delete_all_keys(const keymaster2_device_t* dev) {
1097*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1098*789431f2SAndroid Build Coastguard Worker
1099*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1100*789431f2SAndroid Build Coastguard Worker
1101*789431f2SAndroid Build Coastguard Worker return convert_device(dev)->context_->DeleteAllKeys();
1102*789431f2SAndroid Build Coastguard Worker }
1103*789431f2SAndroid Build Coastguard Worker
1104*789431f2SAndroid Build Coastguard Worker /* static */
begin(const keymaster1_device_t * dev,keymaster_purpose_t purpose,const keymaster_key_blob_t * key,const keymaster_key_param_set_t * in_params,keymaster_key_param_set_t * out_params,keymaster_operation_handle_t * operation_handle)1105*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::begin(const keymaster1_device_t* dev,
1106*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
1107*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key,
1108*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* in_params,
1109*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t* out_params,
1110*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t* operation_handle) {
1111*789431f2SAndroid Build Coastguard Worker if (!dev || !key || !key->key_material) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1112*789431f2SAndroid Build Coastguard Worker
1113*789431f2SAndroid Build Coastguard Worker if (!operation_handle) return KM_ERROR_OUTPUT_PARAMETER_NULL;
1114*789431f2SAndroid Build Coastguard Worker
1115*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* skdev = convert_device(dev);
1116*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = skdev->wrapped_km1_device_;
1117*789431f2SAndroid Build Coastguard Worker
1118*789431f2SAndroid Build Coastguard Worker if (km1_dev) {
1119*789431f2SAndroid Build Coastguard Worker AuthorizationSet in_params_set(*in_params);
1120*789431f2SAndroid Build Coastguard Worker
1121*789431f2SAndroid Build Coastguard Worker UniquePtr<Key> akmKey; // android keymaster key
1122*789431f2SAndroid Build Coastguard Worker skdev->context_->ParseKeyBlob(KeymasterKeyBlob(*key), in_params_set, &akmKey);
1123*789431f2SAndroid Build Coastguard Worker
1124*789431f2SAndroid Build Coastguard Worker keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
1125*789431f2SAndroid Build Coastguard Worker if (!akmKey->hw_enforced().GetTagValue(TAG_ALGORITHM, &algorithm) &&
1126*789431f2SAndroid Build Coastguard Worker !akmKey->sw_enforced().GetTagValue(TAG_ALGORITHM, &algorithm)) {
1127*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
1128*789431f2SAndroid Build Coastguard Worker }
1129*789431f2SAndroid Build Coastguard Worker
1130*789431f2SAndroid Build Coastguard Worker if (algorithm == KM_ALGORITHM_HMAC) {
1131*789431f2SAndroid Build Coastguard Worker // Because HMAC keys can have only one digest, in_params_set doesn't contain it. We
1132*789431f2SAndroid Build Coastguard Worker // need to get the digest from the key and add it to in_params_set.
1133*789431f2SAndroid Build Coastguard Worker keymaster_digest_t digest;
1134*789431f2SAndroid Build Coastguard Worker if (!akmKey->hw_enforced().GetTagValue(TAG_DIGEST, &digest) &&
1135*789431f2SAndroid Build Coastguard Worker !akmKey->sw_enforced().GetTagValue(TAG_DIGEST, &digest)) {
1136*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_KEY_BLOB;
1137*789431f2SAndroid Build Coastguard Worker }
1138*789431f2SAndroid Build Coastguard Worker in_params_set.push_back(TAG_DIGEST, digest);
1139*789431f2SAndroid Build Coastguard Worker }
1140*789431f2SAndroid Build Coastguard Worker
1141*789431f2SAndroid Build Coastguard Worker if (!skdev->RequiresSoftwareDigesting(algorithm, purpose, in_params_set)) {
1142*789431f2SAndroid Build Coastguard Worker LOG_D("Operation supported by %s, passing through to keymaster1 module",
1143*789431f2SAndroid Build Coastguard Worker km1_dev->common.module->name);
1144*789431f2SAndroid Build Coastguard Worker return km1_dev->begin(km1_dev, purpose, key, in_params, out_params, operation_handle);
1145*789431f2SAndroid Build Coastguard Worker }
1146*789431f2SAndroid Build Coastguard Worker LOG_I("Doing software digesting for keymaster1 module %s", km1_dev->common.module->name);
1147*789431f2SAndroid Build Coastguard Worker }
1148*789431f2SAndroid Build Coastguard Worker
1149*789431f2SAndroid Build Coastguard Worker if (out_params) {
1150*789431f2SAndroid Build Coastguard Worker out_params->params = nullptr;
1151*789431f2SAndroid Build Coastguard Worker out_params->length = 0;
1152*789431f2SAndroid Build Coastguard Worker }
1153*789431f2SAndroid Build Coastguard Worker
1154*789431f2SAndroid Build Coastguard Worker auto& impl_ = skdev->impl_;
1155*789431f2SAndroid Build Coastguard Worker BeginOperationRequest request(impl_->message_version());
1156*789431f2SAndroid Build Coastguard Worker request.purpose = purpose;
1157*789431f2SAndroid Build Coastguard Worker request.SetKeyMaterial(*key);
1158*789431f2SAndroid Build Coastguard Worker request.additional_params.Reinitialize(*in_params);
1159*789431f2SAndroid Build Coastguard Worker
1160*789431f2SAndroid Build Coastguard Worker BeginOperationResponse response(impl_->message_version());
1161*789431f2SAndroid Build Coastguard Worker impl_->BeginOperation(request, &response);
1162*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
1163*789431f2SAndroid Build Coastguard Worker
1164*789431f2SAndroid Build Coastguard Worker if (response.output_params.size() > 0) {
1165*789431f2SAndroid Build Coastguard Worker if (out_params)
1166*789431f2SAndroid Build Coastguard Worker response.output_params.CopyToParamSet(out_params);
1167*789431f2SAndroid Build Coastguard Worker else
1168*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1169*789431f2SAndroid Build Coastguard Worker }
1170*789431f2SAndroid Build Coastguard Worker
1171*789431f2SAndroid Build Coastguard Worker *operation_handle = response.op_handle;
1172*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1173*789431f2SAndroid Build Coastguard Worker }
1174*789431f2SAndroid Build Coastguard Worker
1175*789431f2SAndroid Build Coastguard Worker /* static */
begin(const keymaster2_device_t * dev,keymaster_purpose_t purpose,const keymaster_key_blob_t * key,const keymaster_key_param_set_t * in_params,keymaster_key_param_set_t * out_params,keymaster_operation_handle_t * operation_handle)1176*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::begin(const keymaster2_device_t* dev,
1177*789431f2SAndroid Build Coastguard Worker keymaster_purpose_t purpose,
1178*789431f2SAndroid Build Coastguard Worker const keymaster_key_blob_t* key,
1179*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* in_params,
1180*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t* out_params,
1181*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t* operation_handle) {
1182*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1183*789431f2SAndroid Build Coastguard Worker
1184*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1185*789431f2SAndroid Build Coastguard Worker
1186*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
1187*789431f2SAndroid Build Coastguard Worker return begin(&sk_dev->km1_device_, purpose, key, in_params, out_params, operation_handle);
1188*789431f2SAndroid Build Coastguard Worker }
1189*789431f2SAndroid Build Coastguard Worker
1190*789431f2SAndroid Build Coastguard Worker /* static */
update(const keymaster1_device_t * dev,keymaster_operation_handle_t operation_handle,const keymaster_key_param_set_t * in_params,const keymaster_blob_t * input,size_t * input_consumed,keymaster_key_param_set_t * out_params,keymaster_blob_t * output)1191*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::update(const keymaster1_device_t* dev,
1192*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t operation_handle,
1193*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* in_params,
1194*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* input, size_t* input_consumed,
1195*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t* out_params,
1196*789431f2SAndroid Build Coastguard Worker keymaster_blob_t* output) {
1197*789431f2SAndroid Build Coastguard Worker if (!input) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1198*789431f2SAndroid Build Coastguard Worker
1199*789431f2SAndroid Build Coastguard Worker if (!input_consumed) return KM_ERROR_OUTPUT_PARAMETER_NULL;
1200*789431f2SAndroid Build Coastguard Worker
1201*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
1202*789431f2SAndroid Build Coastguard Worker if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
1203*789431f2SAndroid Build Coastguard Worker // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
1204*789431f2SAndroid Build Coastguard Worker // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
1205*789431f2SAndroid Build Coastguard Worker // km1_dev after doing necessary digesting.
1206*789431f2SAndroid Build Coastguard Worker return km1_dev->update(km1_dev, operation_handle, in_params, input, input_consumed,
1207*789431f2SAndroid Build Coastguard Worker out_params, output);
1208*789431f2SAndroid Build Coastguard Worker }
1209*789431f2SAndroid Build Coastguard Worker
1210*789431f2SAndroid Build Coastguard Worker if (out_params) {
1211*789431f2SAndroid Build Coastguard Worker out_params->params = nullptr;
1212*789431f2SAndroid Build Coastguard Worker out_params->length = 0;
1213*789431f2SAndroid Build Coastguard Worker }
1214*789431f2SAndroid Build Coastguard Worker if (output) {
1215*789431f2SAndroid Build Coastguard Worker output->data = nullptr;
1216*789431f2SAndroid Build Coastguard Worker output->data_length = 0;
1217*789431f2SAndroid Build Coastguard Worker }
1218*789431f2SAndroid Build Coastguard Worker
1219*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
1220*789431f2SAndroid Build Coastguard Worker UpdateOperationRequest request(impl_->message_version());
1221*789431f2SAndroid Build Coastguard Worker request.op_handle = operation_handle;
1222*789431f2SAndroid Build Coastguard Worker if (input) request.input.Reinitialize(input->data, input->data_length);
1223*789431f2SAndroid Build Coastguard Worker if (in_params) request.additional_params.Reinitialize(*in_params);
1224*789431f2SAndroid Build Coastguard Worker
1225*789431f2SAndroid Build Coastguard Worker UpdateOperationResponse response(impl_->message_version());
1226*789431f2SAndroid Build Coastguard Worker impl_->UpdateOperation(request, &response);
1227*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
1228*789431f2SAndroid Build Coastguard Worker
1229*789431f2SAndroid Build Coastguard Worker if (response.output_params.size() > 0) {
1230*789431f2SAndroid Build Coastguard Worker if (out_params)
1231*789431f2SAndroid Build Coastguard Worker response.output_params.CopyToParamSet(out_params);
1232*789431f2SAndroid Build Coastguard Worker else
1233*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1234*789431f2SAndroid Build Coastguard Worker }
1235*789431f2SAndroid Build Coastguard Worker
1236*789431f2SAndroid Build Coastguard Worker *input_consumed = response.input_consumed;
1237*789431f2SAndroid Build Coastguard Worker if (output) {
1238*789431f2SAndroid Build Coastguard Worker output->data_length = response.output.available_read();
1239*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
1240*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1241*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.output.peek_read(), output->data_length);
1242*789431f2SAndroid Build Coastguard Worker output->data = tmp;
1243*789431f2SAndroid Build Coastguard Worker } else if (response.output.available_read() > 0) {
1244*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1245*789431f2SAndroid Build Coastguard Worker }
1246*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1247*789431f2SAndroid Build Coastguard Worker }
1248*789431f2SAndroid Build Coastguard Worker
1249*789431f2SAndroid Build Coastguard Worker /* static */
update(const keymaster2_device_t * dev,keymaster_operation_handle_t operation_handle,const keymaster_key_param_set_t * in_params,const keymaster_blob_t * input,size_t * input_consumed,keymaster_key_param_set_t * out_params,keymaster_blob_t * output)1250*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::update(const keymaster2_device_t* dev,
1251*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t operation_handle,
1252*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* in_params,
1253*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* input, size_t* input_consumed,
1254*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t* out_params,
1255*789431f2SAndroid Build Coastguard Worker keymaster_blob_t* output) {
1256*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1257*789431f2SAndroid Build Coastguard Worker
1258*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1259*789431f2SAndroid Build Coastguard Worker
1260*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
1261*789431f2SAndroid Build Coastguard Worker return update(&sk_dev->km1_device_, operation_handle, in_params, input, input_consumed,
1262*789431f2SAndroid Build Coastguard Worker out_params, output);
1263*789431f2SAndroid Build Coastguard Worker }
1264*789431f2SAndroid Build Coastguard Worker
1265*789431f2SAndroid Build Coastguard Worker /* static */
finish(const keymaster1_device_t * dev,keymaster_operation_handle_t operation_handle,const keymaster_key_param_set_t * params,const keymaster_blob_t * signature,keymaster_key_param_set_t * out_params,keymaster_blob_t * output)1266*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::finish(const keymaster1_device_t* dev,
1267*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t operation_handle,
1268*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* params,
1269*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* signature,
1270*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t* out_params,
1271*789431f2SAndroid Build Coastguard Worker keymaster_blob_t* output) {
1272*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1273*789431f2SAndroid Build Coastguard Worker
1274*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
1275*789431f2SAndroid Build Coastguard Worker if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
1276*789431f2SAndroid Build Coastguard Worker // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
1277*789431f2SAndroid Build Coastguard Worker // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
1278*789431f2SAndroid Build Coastguard Worker // km1_dev after doing necessary digesting.
1279*789431f2SAndroid Build Coastguard Worker return km1_dev->finish(km1_dev, operation_handle, params, signature, out_params, output);
1280*789431f2SAndroid Build Coastguard Worker }
1281*789431f2SAndroid Build Coastguard Worker
1282*789431f2SAndroid Build Coastguard Worker if (out_params) {
1283*789431f2SAndroid Build Coastguard Worker out_params->params = nullptr;
1284*789431f2SAndroid Build Coastguard Worker out_params->length = 0;
1285*789431f2SAndroid Build Coastguard Worker }
1286*789431f2SAndroid Build Coastguard Worker
1287*789431f2SAndroid Build Coastguard Worker if (output) {
1288*789431f2SAndroid Build Coastguard Worker output->data = nullptr;
1289*789431f2SAndroid Build Coastguard Worker output->data_length = 0;
1290*789431f2SAndroid Build Coastguard Worker }
1291*789431f2SAndroid Build Coastguard Worker
1292*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
1293*789431f2SAndroid Build Coastguard Worker FinishOperationRequest request(impl_->message_version());
1294*789431f2SAndroid Build Coastguard Worker request.op_handle = operation_handle;
1295*789431f2SAndroid Build Coastguard Worker if (signature && signature->data_length > 0)
1296*789431f2SAndroid Build Coastguard Worker request.signature.Reinitialize(signature->data, signature->data_length);
1297*789431f2SAndroid Build Coastguard Worker request.additional_params.Reinitialize(*params);
1298*789431f2SAndroid Build Coastguard Worker
1299*789431f2SAndroid Build Coastguard Worker FinishOperationResponse response(impl_->message_version());
1300*789431f2SAndroid Build Coastguard Worker impl_->FinishOperation(request, &response);
1301*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
1302*789431f2SAndroid Build Coastguard Worker
1303*789431f2SAndroid Build Coastguard Worker if (response.output_params.size() > 0) {
1304*789431f2SAndroid Build Coastguard Worker if (out_params)
1305*789431f2SAndroid Build Coastguard Worker response.output_params.CopyToParamSet(out_params);
1306*789431f2SAndroid Build Coastguard Worker else
1307*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1308*789431f2SAndroid Build Coastguard Worker }
1309*789431f2SAndroid Build Coastguard Worker if (output) {
1310*789431f2SAndroid Build Coastguard Worker output->data_length = response.output.available_read();
1311*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
1312*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1313*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.output.peek_read(), output->data_length);
1314*789431f2SAndroid Build Coastguard Worker output->data = tmp;
1315*789431f2SAndroid Build Coastguard Worker } else if (response.output.available_read() > 0) {
1316*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1317*789431f2SAndroid Build Coastguard Worker }
1318*789431f2SAndroid Build Coastguard Worker
1319*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1320*789431f2SAndroid Build Coastguard Worker }
1321*789431f2SAndroid Build Coastguard Worker
1322*789431f2SAndroid Build Coastguard Worker struct KeyParamSetContents_Delete {
operator ()keymaster::KeyParamSetContents_Delete1323*789431f2SAndroid Build Coastguard Worker void operator()(keymaster_key_param_set_t* p) { keymaster_free_param_set(p); }
1324*789431f2SAndroid Build Coastguard Worker };
1325*789431f2SAndroid Build Coastguard Worker
1326*789431f2SAndroid Build Coastguard Worker /* static */
finish(const keymaster2_device_t * dev,keymaster_operation_handle_t operation_handle,const keymaster_key_param_set_t * params,const keymaster_blob_t * input,const keymaster_blob_t * signature,keymaster_key_param_set_t * out_params,keymaster_blob_t * output)1327*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::finish(const keymaster2_device_t* dev,
1328*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t operation_handle,
1329*789431f2SAndroid Build Coastguard Worker const keymaster_key_param_set_t* params,
1330*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* input,
1331*789431f2SAndroid Build Coastguard Worker const keymaster_blob_t* signature,
1332*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t* out_params,
1333*789431f2SAndroid Build Coastguard Worker keymaster_blob_t* output) {
1334*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1335*789431f2SAndroid Build Coastguard Worker
1336*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1337*789431f2SAndroid Build Coastguard Worker
1338*789431f2SAndroid Build Coastguard Worker if (out_params) *out_params = {};
1339*789431f2SAndroid Build Coastguard Worker
1340*789431f2SAndroid Build Coastguard Worker if (output) *output = {};
1341*789431f2SAndroid Build Coastguard Worker
1342*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
1343*789431f2SAndroid Build Coastguard Worker if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
1344*789431f2SAndroid Build Coastguard Worker // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
1345*789431f2SAndroid Build Coastguard Worker // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
1346*789431f2SAndroid Build Coastguard Worker // km1_dev after doing necessary digesting.
1347*789431f2SAndroid Build Coastguard Worker
1348*789431f2SAndroid Build Coastguard Worker std::vector<uint8_t> accumulated_output;
1349*789431f2SAndroid Build Coastguard Worker AuthorizationSet accumulated_out_params;
1350*789431f2SAndroid Build Coastguard Worker AuthorizationSet mutable_params(*params);
1351*789431f2SAndroid Build Coastguard Worker if (input && input->data && input->data_length) {
1352*789431f2SAndroid Build Coastguard Worker // Keymaster1 doesn't support input to finish(). Call update() to process input.
1353*789431f2SAndroid Build Coastguard Worker
1354*789431f2SAndroid Build Coastguard Worker accumulated_output.reserve(input->data_length); // Guess at output size
1355*789431f2SAndroid Build Coastguard Worker keymaster_blob_t mutable_input = *input;
1356*789431f2SAndroid Build Coastguard Worker
1357*789431f2SAndroid Build Coastguard Worker while (mutable_input.data_length > 0) {
1358*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t update_out_params = {};
1359*789431f2SAndroid Build Coastguard Worker keymaster_blob_t update_output = {};
1360*789431f2SAndroid Build Coastguard Worker size_t input_consumed = 0;
1361*789431f2SAndroid Build Coastguard Worker keymaster_error_t error =
1362*789431f2SAndroid Build Coastguard Worker km1_dev->update(km1_dev, operation_handle, &mutable_params, &mutable_input,
1363*789431f2SAndroid Build Coastguard Worker &input_consumed, &update_out_params, &update_output);
1364*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) {
1365*789431f2SAndroid Build Coastguard Worker return error;
1366*789431f2SAndroid Build Coastguard Worker }
1367*789431f2SAndroid Build Coastguard Worker
1368*789431f2SAndroid Build Coastguard Worker accumulated_output.reserve(accumulated_output.size() + update_output.data_length);
1369*789431f2SAndroid Build Coastguard Worker std::copy(update_output.data, update_output.data + update_output.data_length,
1370*789431f2SAndroid Build Coastguard Worker std::back_inserter(accumulated_output));
1371*789431f2SAndroid Build Coastguard Worker free(const_cast<uint8_t*>(update_output.data));
1372*789431f2SAndroid Build Coastguard Worker
1373*789431f2SAndroid Build Coastguard Worker accumulated_out_params.push_back(update_out_params);
1374*789431f2SAndroid Build Coastguard Worker keymaster_free_param_set(&update_out_params);
1375*789431f2SAndroid Build Coastguard Worker
1376*789431f2SAndroid Build Coastguard Worker mutable_input.data += input_consumed;
1377*789431f2SAndroid Build Coastguard Worker mutable_input.data_length -= input_consumed;
1378*789431f2SAndroid Build Coastguard Worker
1379*789431f2SAndroid Build Coastguard Worker // AAD should only be sent once, so remove it if present.
1380*789431f2SAndroid Build Coastguard Worker int aad_pos = mutable_params.find(TAG_ASSOCIATED_DATA);
1381*789431f2SAndroid Build Coastguard Worker if (aad_pos != -1) {
1382*789431f2SAndroid Build Coastguard Worker mutable_params.erase(aad_pos);
1383*789431f2SAndroid Build Coastguard Worker }
1384*789431f2SAndroid Build Coastguard Worker
1385*789431f2SAndroid Build Coastguard Worker if (input_consumed == 0) {
1386*789431f2SAndroid Build Coastguard Worker // Apparently we need more input than we have to complete an operation.
1387*789431f2SAndroid Build Coastguard Worker km1_dev->abort(km1_dev, operation_handle);
1388*789431f2SAndroid Build Coastguard Worker return KM_ERROR_INVALID_INPUT_LENGTH;
1389*789431f2SAndroid Build Coastguard Worker }
1390*789431f2SAndroid Build Coastguard Worker }
1391*789431f2SAndroid Build Coastguard Worker }
1392*789431f2SAndroid Build Coastguard Worker
1393*789431f2SAndroid Build Coastguard Worker keymaster_key_param_set_t finish_out_params = {};
1394*789431f2SAndroid Build Coastguard Worker keymaster_blob_t finish_output = {};
1395*789431f2SAndroid Build Coastguard Worker keymaster_error_t error = km1_dev->finish(km1_dev, operation_handle, &mutable_params,
1396*789431f2SAndroid Build Coastguard Worker signature, &finish_out_params, &finish_output);
1397*789431f2SAndroid Build Coastguard Worker if (error != KM_ERROR_OK) {
1398*789431f2SAndroid Build Coastguard Worker return error;
1399*789431f2SAndroid Build Coastguard Worker }
1400*789431f2SAndroid Build Coastguard Worker
1401*789431f2SAndroid Build Coastguard Worker if (!accumulated_out_params.empty()) {
1402*789431f2SAndroid Build Coastguard Worker accumulated_out_params.push_back(finish_out_params);
1403*789431f2SAndroid Build Coastguard Worker keymaster_free_param_set(&finish_out_params);
1404*789431f2SAndroid Build Coastguard Worker accumulated_out_params.Deduplicate();
1405*789431f2SAndroid Build Coastguard Worker accumulated_out_params.CopyToParamSet(&finish_out_params);
1406*789431f2SAndroid Build Coastguard Worker }
1407*789431f2SAndroid Build Coastguard Worker std::unique_ptr<keymaster_key_param_set_t, KeyParamSetContents_Delete>
1408*789431f2SAndroid Build Coastguard Worker finish_out_params_deleter(&finish_out_params);
1409*789431f2SAndroid Build Coastguard Worker
1410*789431f2SAndroid Build Coastguard Worker if (!accumulated_output.empty()) {
1411*789431f2SAndroid Build Coastguard Worker size_t finish_out_length = accumulated_output.size() + finish_output.data_length;
1412*789431f2SAndroid Build Coastguard Worker uint8_t* finish_out_buf = reinterpret_cast<uint8_t*>(malloc(finish_out_length));
1413*789431f2SAndroid Build Coastguard Worker
1414*789431f2SAndroid Build Coastguard Worker std::copy(accumulated_output.begin(), accumulated_output.end(), finish_out_buf);
1415*789431f2SAndroid Build Coastguard Worker std::copy(finish_output.data, finish_output.data + finish_output.data_length,
1416*789431f2SAndroid Build Coastguard Worker finish_out_buf + accumulated_output.size());
1417*789431f2SAndroid Build Coastguard Worker
1418*789431f2SAndroid Build Coastguard Worker free(const_cast<uint8_t*>(finish_output.data));
1419*789431f2SAndroid Build Coastguard Worker finish_output.data_length = finish_out_length;
1420*789431f2SAndroid Build Coastguard Worker finish_output.data = finish_out_buf;
1421*789431f2SAndroid Build Coastguard Worker }
1422*789431f2SAndroid Build Coastguard Worker std::unique_ptr<uint8_t, Malloc_Delete> finish_output_deleter(
1423*789431f2SAndroid Build Coastguard Worker const_cast<uint8_t*>(finish_output.data));
1424*789431f2SAndroid Build Coastguard Worker
1425*789431f2SAndroid Build Coastguard Worker if ((!out_params && finish_out_params.length) || (!output && finish_output.data_length)) {
1426*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1427*789431f2SAndroid Build Coastguard Worker }
1428*789431f2SAndroid Build Coastguard Worker
1429*789431f2SAndroid Build Coastguard Worker *out_params = finish_out_params;
1430*789431f2SAndroid Build Coastguard Worker *output = finish_output;
1431*789431f2SAndroid Build Coastguard Worker
1432*789431f2SAndroid Build Coastguard Worker finish_out_params_deleter.release(); // NOLINT(bugprone-unused-return-value)
1433*789431f2SAndroid Build Coastguard Worker finish_output_deleter.release(); // NOLINT(bugprone-unused-return-value)
1434*789431f2SAndroid Build Coastguard Worker
1435*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1436*789431f2SAndroid Build Coastguard Worker }
1437*789431f2SAndroid Build Coastguard Worker
1438*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
1439*789431f2SAndroid Build Coastguard Worker FinishOperationRequest request(impl_->message_version());
1440*789431f2SAndroid Build Coastguard Worker request.op_handle = operation_handle;
1441*789431f2SAndroid Build Coastguard Worker if (signature && signature->data_length > 0)
1442*789431f2SAndroid Build Coastguard Worker request.signature.Reinitialize(signature->data, signature->data_length);
1443*789431f2SAndroid Build Coastguard Worker if (input && input->data_length > 0)
1444*789431f2SAndroid Build Coastguard Worker request.input.Reinitialize(input->data, input->data_length);
1445*789431f2SAndroid Build Coastguard Worker request.additional_params.Reinitialize(*params);
1446*789431f2SAndroid Build Coastguard Worker
1447*789431f2SAndroid Build Coastguard Worker FinishOperationResponse response(impl_->message_version());
1448*789431f2SAndroid Build Coastguard Worker impl_->FinishOperation(request, &response);
1449*789431f2SAndroid Build Coastguard Worker if (response.error != KM_ERROR_OK) return response.error;
1450*789431f2SAndroid Build Coastguard Worker
1451*789431f2SAndroid Build Coastguard Worker if (response.output_params.size() > 0) {
1452*789431f2SAndroid Build Coastguard Worker if (out_params)
1453*789431f2SAndroid Build Coastguard Worker response.output_params.CopyToParamSet(out_params);
1454*789431f2SAndroid Build Coastguard Worker else
1455*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1456*789431f2SAndroid Build Coastguard Worker }
1457*789431f2SAndroid Build Coastguard Worker if (output) {
1458*789431f2SAndroid Build Coastguard Worker output->data_length = response.output.available_read();
1459*789431f2SAndroid Build Coastguard Worker uint8_t* tmp = reinterpret_cast<uint8_t*>(malloc(output->data_length));
1460*789431f2SAndroid Build Coastguard Worker if (!tmp) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
1461*789431f2SAndroid Build Coastguard Worker memcpy(tmp, response.output.peek_read(), output->data_length);
1462*789431f2SAndroid Build Coastguard Worker output->data = tmp;
1463*789431f2SAndroid Build Coastguard Worker } else if (response.output.available_read() > 0) {
1464*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OUTPUT_PARAMETER_NULL;
1465*789431f2SAndroid Build Coastguard Worker }
1466*789431f2SAndroid Build Coastguard Worker
1467*789431f2SAndroid Build Coastguard Worker return KM_ERROR_OK;
1468*789431f2SAndroid Build Coastguard Worker }
1469*789431f2SAndroid Build Coastguard Worker
1470*789431f2SAndroid Build Coastguard Worker /* static */
abort(const keymaster1_device_t * dev,keymaster_operation_handle_t operation_handle)1471*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::abort(const keymaster1_device_t* dev,
1472*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t operation_handle) {
1473*789431f2SAndroid Build Coastguard Worker const keymaster1_device_t* km1_dev = convert_device(dev)->wrapped_km1_device_;
1474*789431f2SAndroid Build Coastguard Worker if (km1_dev && !convert_device(dev)->impl_->has_operation(operation_handle)) {
1475*789431f2SAndroid Build Coastguard Worker // This operation is being handled by km1_dev (or doesn't exist). Pass it through to
1476*789431f2SAndroid Build Coastguard Worker // km1_dev. Otherwise, we'll use the software AndroidKeymaster, which may delegate to
1477*789431f2SAndroid Build Coastguard Worker // km1_dev.
1478*789431f2SAndroid Build Coastguard Worker return km1_dev->abort(km1_dev, operation_handle);
1479*789431f2SAndroid Build Coastguard Worker }
1480*789431f2SAndroid Build Coastguard Worker
1481*789431f2SAndroid Build Coastguard Worker auto& impl_ = convert_device(dev)->impl_;
1482*789431f2SAndroid Build Coastguard Worker AbortOperationRequest request(impl_->message_version());
1483*789431f2SAndroid Build Coastguard Worker request.op_handle = operation_handle;
1484*789431f2SAndroid Build Coastguard Worker AbortOperationResponse response(impl_->message_version());
1485*789431f2SAndroid Build Coastguard Worker impl_->AbortOperation(request, &response);
1486*789431f2SAndroid Build Coastguard Worker return response.error;
1487*789431f2SAndroid Build Coastguard Worker }
1488*789431f2SAndroid Build Coastguard Worker
1489*789431f2SAndroid Build Coastguard Worker /* static */
abort(const keymaster2_device_t * dev,keymaster_operation_handle_t operation_handle)1490*789431f2SAndroid Build Coastguard Worker keymaster_error_t SoftKeymasterDevice::abort(const keymaster2_device_t* dev,
1491*789431f2SAndroid Build Coastguard Worker keymaster_operation_handle_t operation_handle) {
1492*789431f2SAndroid Build Coastguard Worker if (!dev) return KM_ERROR_UNEXPECTED_NULL_POINTER;
1493*789431f2SAndroid Build Coastguard Worker
1494*789431f2SAndroid Build Coastguard Worker if (!convert_device(dev)->configured()) return KM_ERROR_KEYMASTER_NOT_CONFIGURED;
1495*789431f2SAndroid Build Coastguard Worker
1496*789431f2SAndroid Build Coastguard Worker SoftKeymasterDevice* sk_dev = convert_device(dev);
1497*789431f2SAndroid Build Coastguard Worker return abort(&sk_dev->km1_device_, operation_handle);
1498*789431f2SAndroid Build Coastguard Worker }
1499*789431f2SAndroid Build Coastguard Worker
1500*789431f2SAndroid Build Coastguard Worker /* static */
StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm,AuthorizationSet * auth_set)1501*789431f2SAndroid Build Coastguard Worker void SoftKeymasterDevice::StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm,
1502*789431f2SAndroid Build Coastguard Worker AuthorizationSet* auth_set) {
1503*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN);
1504*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY);
1505*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_ALL_USERS);
1506*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_NO_AUTH_REQUIRED);
1507*789431f2SAndroid Build Coastguard Worker
1508*789431f2SAndroid Build Coastguard Worker // All digests.
1509*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE);
1510*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_MD5);
1511*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA1);
1512*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224);
1513*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256);
1514*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384);
1515*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512);
1516*789431f2SAndroid Build Coastguard Worker
1517*789431f2SAndroid Build Coastguard Worker if (algorithm == KM_ALGORITHM_RSA) {
1518*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
1519*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
1520*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PADDING, KM_PAD_NONE);
1521*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN);
1522*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
1523*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PSS);
1524*789431f2SAndroid Build Coastguard Worker auth_set->push_back(TAG_PADDING, KM_PAD_RSA_OAEP);
1525*789431f2SAndroid Build Coastguard Worker }
1526*789431f2SAndroid Build Coastguard Worker }
1527*789431f2SAndroid Build Coastguard Worker
1528*789431f2SAndroid Build Coastguard Worker } // namespace keymaster
1529