1*e1997b9aSAndroid Build Coastguard Worker /*
2*e1997b9aSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*e1997b9aSAndroid Build Coastguard Worker *
4*e1997b9aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e1997b9aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e1997b9aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e1997b9aSAndroid Build Coastguard Worker *
8*e1997b9aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e1997b9aSAndroid Build Coastguard Worker *
10*e1997b9aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e1997b9aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e1997b9aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1997b9aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e1997b9aSAndroid Build Coastguard Worker * limitations under the License.
15*e1997b9aSAndroid Build Coastguard Worker */
16*e1997b9aSAndroid Build Coastguard Worker
17*e1997b9aSAndroid Build Coastguard Worker #include <string>
18*e1997b9aSAndroid Build Coastguard Worker
19*e1997b9aSAndroid Build Coastguard Worker #include <android-base/file.h>
20*e1997b9aSAndroid Build Coastguard Worker #include <android-base/logging.h>
21*e1997b9aSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
22*e1997b9aSAndroid Build Coastguard Worker
23*e1997b9aSAndroid Build Coastguard Worker #include <fcntl.h>
24*e1997b9aSAndroid Build Coastguard Worker #include <sys/stat.h>
25*e1997b9aSAndroid Build Coastguard Worker #include <sys/types.h>
26*e1997b9aSAndroid Build Coastguard Worker
27*e1997b9aSAndroid Build Coastguard Worker #include "CertUtils.h"
28*e1997b9aSAndroid Build Coastguard Worker #include "KeyConstants.h"
29*e1997b9aSAndroid Build Coastguard Worker #include "KeystoreKey.h"
30*e1997b9aSAndroid Build Coastguard Worker
31*e1997b9aSAndroid Build Coastguard Worker using android::defaultServiceManager;
32*e1997b9aSAndroid Build Coastguard Worker using android::IServiceManager;
33*e1997b9aSAndroid Build Coastguard Worker using android::sp;
34*e1997b9aSAndroid Build Coastguard Worker using android::String16;
35*e1997b9aSAndroid Build Coastguard Worker
36*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::Algorithm;
37*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::Digest;
38*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::KeyParameter;
39*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::KeyParameterValue;
40*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::KeyPurpose;
41*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::PaddingMode;
42*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::SecurityLevel;
43*e1997b9aSAndroid Build Coastguard Worker using android::hardware::security::keymint::Tag;
44*e1997b9aSAndroid Build Coastguard Worker
45*e1997b9aSAndroid Build Coastguard Worker using android::system::keystore2::CreateOperationResponse;
46*e1997b9aSAndroid Build Coastguard Worker using android::system::keystore2::Domain;
47*e1997b9aSAndroid Build Coastguard Worker using android::system::keystore2::KeyDescriptor;
48*e1997b9aSAndroid Build Coastguard Worker using android::system::keystore2::KeyEntryResponse;
49*e1997b9aSAndroid Build Coastguard Worker
50*e1997b9aSAndroid Build Coastguard Worker using android::base::Error;
51*e1997b9aSAndroid Build Coastguard Worker using android::base::Result;
52*e1997b9aSAndroid Build Coastguard Worker
getKeyDescriptor(const android::String16 & keyAlias,int64_t keyNspace)53*e1997b9aSAndroid Build Coastguard Worker static KeyDescriptor getKeyDescriptor(const android::String16& keyAlias, int64_t keyNspace) {
54*e1997b9aSAndroid Build Coastguard Worker // AIDL parcelable objects don't have constructor
55*e1997b9aSAndroid Build Coastguard Worker static KeyDescriptor descriptor;
56*e1997b9aSAndroid Build Coastguard Worker static std::once_flag flag;
57*e1997b9aSAndroid Build Coastguard Worker std::call_once(flag, [&]() {
58*e1997b9aSAndroid Build Coastguard Worker descriptor.domain = Domain::SELINUX;
59*e1997b9aSAndroid Build Coastguard Worker descriptor.alias = keyAlias;
60*e1997b9aSAndroid Build Coastguard Worker descriptor.nspace = keyNspace;
61*e1997b9aSAndroid Build Coastguard Worker });
62*e1997b9aSAndroid Build Coastguard Worker
63*e1997b9aSAndroid Build Coastguard Worker return descriptor;
64*e1997b9aSAndroid Build Coastguard Worker }
65*e1997b9aSAndroid Build Coastguard Worker
KeystoreKey(std::string signedPubKeyPath,const android::String16 & keyAlias,int64_t keyNspace,int keyBootLevel)66*e1997b9aSAndroid Build Coastguard Worker KeystoreKey::KeystoreKey(std::string signedPubKeyPath, const android::String16& keyAlias,
67*e1997b9aSAndroid Build Coastguard Worker int64_t keyNspace, int keyBootLevel)
68*e1997b9aSAndroid Build Coastguard Worker : mDescriptor(getKeyDescriptor(keyAlias, keyNspace)),
69*e1997b9aSAndroid Build Coastguard Worker mHmacKey(keyAlias, keyNspace, keyBootLevel), mSignedPubKeyPath(std::move(signedPubKeyPath)),
70*e1997b9aSAndroid Build Coastguard Worker mKeyBootLevel(keyBootLevel) {}
71*e1997b9aSAndroid Build Coastguard Worker
createKey()72*e1997b9aSAndroid Build Coastguard Worker Result<std::vector<uint8_t>> KeystoreKey::createKey() {
73*e1997b9aSAndroid Build Coastguard Worker std::vector<KeyParameter> params;
74*e1997b9aSAndroid Build Coastguard Worker
75*e1997b9aSAndroid Build Coastguard Worker KeyParameter algo;
76*e1997b9aSAndroid Build Coastguard Worker algo.tag = Tag::ALGORITHM;
77*e1997b9aSAndroid Build Coastguard Worker algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
78*e1997b9aSAndroid Build Coastguard Worker params.push_back(algo);
79*e1997b9aSAndroid Build Coastguard Worker
80*e1997b9aSAndroid Build Coastguard Worker KeyParameter key_size;
81*e1997b9aSAndroid Build Coastguard Worker key_size.tag = Tag::KEY_SIZE;
82*e1997b9aSAndroid Build Coastguard Worker key_size.value = KeyParameterValue::make<KeyParameterValue::integer>(kRsaKeySize);
83*e1997b9aSAndroid Build Coastguard Worker params.push_back(key_size);
84*e1997b9aSAndroid Build Coastguard Worker
85*e1997b9aSAndroid Build Coastguard Worker KeyParameter digest;
86*e1997b9aSAndroid Build Coastguard Worker digest.tag = Tag::DIGEST;
87*e1997b9aSAndroid Build Coastguard Worker digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
88*e1997b9aSAndroid Build Coastguard Worker params.push_back(digest);
89*e1997b9aSAndroid Build Coastguard Worker
90*e1997b9aSAndroid Build Coastguard Worker KeyParameter padding;
91*e1997b9aSAndroid Build Coastguard Worker padding.tag = Tag::PADDING;
92*e1997b9aSAndroid Build Coastguard Worker padding.value =
93*e1997b9aSAndroid Build Coastguard Worker KeyParameterValue::make<KeyParameterValue::paddingMode>(PaddingMode::RSA_PKCS1_1_5_SIGN);
94*e1997b9aSAndroid Build Coastguard Worker params.push_back(padding);
95*e1997b9aSAndroid Build Coastguard Worker
96*e1997b9aSAndroid Build Coastguard Worker KeyParameter exponent;
97*e1997b9aSAndroid Build Coastguard Worker exponent.tag = Tag::RSA_PUBLIC_EXPONENT;
98*e1997b9aSAndroid Build Coastguard Worker exponent.value = KeyParameterValue::make<KeyParameterValue::longInteger>(kRsaKeyExponent);
99*e1997b9aSAndroid Build Coastguard Worker params.push_back(exponent);
100*e1997b9aSAndroid Build Coastguard Worker
101*e1997b9aSAndroid Build Coastguard Worker KeyParameter purpose;
102*e1997b9aSAndroid Build Coastguard Worker purpose.tag = Tag::PURPOSE;
103*e1997b9aSAndroid Build Coastguard Worker purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
104*e1997b9aSAndroid Build Coastguard Worker params.push_back(purpose);
105*e1997b9aSAndroid Build Coastguard Worker
106*e1997b9aSAndroid Build Coastguard Worker KeyParameter auth;
107*e1997b9aSAndroid Build Coastguard Worker auth.tag = Tag::NO_AUTH_REQUIRED;
108*e1997b9aSAndroid Build Coastguard Worker auth.value = KeyParameterValue::make<KeyParameterValue::boolValue>(true);
109*e1997b9aSAndroid Build Coastguard Worker params.push_back(auth);
110*e1997b9aSAndroid Build Coastguard Worker
111*e1997b9aSAndroid Build Coastguard Worker KeyParameter boot_level;
112*e1997b9aSAndroid Build Coastguard Worker boot_level.tag = Tag::MAX_BOOT_LEVEL;
113*e1997b9aSAndroid Build Coastguard Worker boot_level.value = KeyParameterValue::make<KeyParameterValue::integer>(mKeyBootLevel);
114*e1997b9aSAndroid Build Coastguard Worker params.push_back(boot_level);
115*e1997b9aSAndroid Build Coastguard Worker
116*e1997b9aSAndroid Build Coastguard Worker KeyMetadata metadata;
117*e1997b9aSAndroid Build Coastguard Worker auto status = mSecurityLevel->generateKey(mDescriptor, {}, params, 0, {}, &metadata);
118*e1997b9aSAndroid Build Coastguard Worker if (!status.isOk()) {
119*e1997b9aSAndroid Build Coastguard Worker return Error() << "Failed to create new key: " << status;
120*e1997b9aSAndroid Build Coastguard Worker }
121*e1997b9aSAndroid Build Coastguard Worker
122*e1997b9aSAndroid Build Coastguard Worker // Extract the public key from the certificate, HMAC it and store the signature
123*e1997b9aSAndroid Build Coastguard Worker auto cert = metadata.certificate;
124*e1997b9aSAndroid Build Coastguard Worker if (!cert) {
125*e1997b9aSAndroid Build Coastguard Worker return Error() << "Key did not have a certificate.";
126*e1997b9aSAndroid Build Coastguard Worker }
127*e1997b9aSAndroid Build Coastguard Worker auto publicKey = extractPublicKeyFromX509(cert.value());
128*e1997b9aSAndroid Build Coastguard Worker if (!publicKey.ok()) {
129*e1997b9aSAndroid Build Coastguard Worker return publicKey.error();
130*e1997b9aSAndroid Build Coastguard Worker }
131*e1997b9aSAndroid Build Coastguard Worker std::string publicKeyString = {publicKey->begin(), publicKey->end()};
132*e1997b9aSAndroid Build Coastguard Worker auto signature = mHmacKey.sign(publicKeyString);
133*e1997b9aSAndroid Build Coastguard Worker if (!signature.ok()) {
134*e1997b9aSAndroid Build Coastguard Worker return Error() << "Failed to sign public key.";
135*e1997b9aSAndroid Build Coastguard Worker }
136*e1997b9aSAndroid Build Coastguard Worker
137*e1997b9aSAndroid Build Coastguard Worker if (!android::base::WriteStringToFile(*signature, mSignedPubKeyPath)) {
138*e1997b9aSAndroid Build Coastguard Worker return Error() << "Can't write public key signature.";
139*e1997b9aSAndroid Build Coastguard Worker }
140*e1997b9aSAndroid Build Coastguard Worker
141*e1997b9aSAndroid Build Coastguard Worker return *publicKey;
142*e1997b9aSAndroid Build Coastguard Worker }
143*e1997b9aSAndroid Build Coastguard Worker
initialize()144*e1997b9aSAndroid Build Coastguard Worker bool KeystoreKey::initialize() {
145*e1997b9aSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
146*e1997b9aSAndroid Build Coastguard Worker if (sm == nullptr) {
147*e1997b9aSAndroid Build Coastguard Worker return false;
148*e1997b9aSAndroid Build Coastguard Worker }
149*e1997b9aSAndroid Build Coastguard Worker auto service = sm->getService(String16("android.system.keystore2.IKeystoreService/default"));
150*e1997b9aSAndroid Build Coastguard Worker if (service == nullptr) {
151*e1997b9aSAndroid Build Coastguard Worker return false;
152*e1997b9aSAndroid Build Coastguard Worker }
153*e1997b9aSAndroid Build Coastguard Worker mService = interface_cast<android::system::keystore2::IKeystoreService>(service);
154*e1997b9aSAndroid Build Coastguard Worker if (mService == nullptr) {
155*e1997b9aSAndroid Build Coastguard Worker return false;
156*e1997b9aSAndroid Build Coastguard Worker }
157*e1997b9aSAndroid Build Coastguard Worker
158*e1997b9aSAndroid Build Coastguard Worker auto status = mService->getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT, &mSecurityLevel);
159*e1997b9aSAndroid Build Coastguard Worker if (!status.isOk()) {
160*e1997b9aSAndroid Build Coastguard Worker return false;
161*e1997b9aSAndroid Build Coastguard Worker }
162*e1997b9aSAndroid Build Coastguard Worker
163*e1997b9aSAndroid Build Coastguard Worker // Initialize the HMAC key we use to sign/verify information about this key
164*e1997b9aSAndroid Build Coastguard Worker auto hmacStatus = mHmacKey.initialize(mService, mSecurityLevel);
165*e1997b9aSAndroid Build Coastguard Worker if (!hmacStatus.ok()) {
166*e1997b9aSAndroid Build Coastguard Worker LOG(ERROR) << hmacStatus.error().message();
167*e1997b9aSAndroid Build Coastguard Worker return false;
168*e1997b9aSAndroid Build Coastguard Worker }
169*e1997b9aSAndroid Build Coastguard Worker
170*e1997b9aSAndroid Build Coastguard Worker auto key = getOrCreateKey();
171*e1997b9aSAndroid Build Coastguard Worker if (!key.ok()) {
172*e1997b9aSAndroid Build Coastguard Worker // Delete the HMAC, just in case signing failed, and we could recover by recreating it.
173*e1997b9aSAndroid Build Coastguard Worker mHmacKey.deleteKey();
174*e1997b9aSAndroid Build Coastguard Worker LOG(ERROR) << key.error().message();
175*e1997b9aSAndroid Build Coastguard Worker return false;
176*e1997b9aSAndroid Build Coastguard Worker }
177*e1997b9aSAndroid Build Coastguard Worker mPublicKey = *key;
178*e1997b9aSAndroid Build Coastguard Worker LOG(INFO) << "Initialized Keystore key.";
179*e1997b9aSAndroid Build Coastguard Worker return true;
180*e1997b9aSAndroid Build Coastguard Worker }
181*e1997b9aSAndroid Build Coastguard Worker
verifyExistingKey()182*e1997b9aSAndroid Build Coastguard Worker Result<std::vector<uint8_t>> KeystoreKey::verifyExistingKey() {
183*e1997b9aSAndroid Build Coastguard Worker // See if we can fetch an existing key
184*e1997b9aSAndroid Build Coastguard Worker KeyEntryResponse keyEntryResponse;
185*e1997b9aSAndroid Build Coastguard Worker LOG(INFO) << "Trying to retrieve existing keystore key...";
186*e1997b9aSAndroid Build Coastguard Worker auto status = mService->getKeyEntry(mDescriptor, &keyEntryResponse);
187*e1997b9aSAndroid Build Coastguard Worker
188*e1997b9aSAndroid Build Coastguard Worker if (!status.isOk()) {
189*e1997b9aSAndroid Build Coastguard Worker return Error() << "Failed to find keystore key...";
190*e1997b9aSAndroid Build Coastguard Worker }
191*e1997b9aSAndroid Build Coastguard Worker
192*e1997b9aSAndroid Build Coastguard Worker // On some earlier builds, we created this key on the Strongbox security level;
193*e1997b9aSAndroid Build Coastguard Worker // we now use TEE keys instead (mostly for speed). It shouldn't matter since
194*e1997b9aSAndroid Build Coastguard Worker // verified boot is protected by the TEE anyway. If the key happens to be on
195*e1997b9aSAndroid Build Coastguard Worker // the wrong security level, delete it (this should happen just once).
196*e1997b9aSAndroid Build Coastguard Worker if (keyEntryResponse.metadata.keySecurityLevel != SecurityLevel::TRUSTED_ENVIRONMENT) {
197*e1997b9aSAndroid Build Coastguard Worker return Error() << "Found invalid keystore key with security level: "
198*e1997b9aSAndroid Build Coastguard Worker << android::hardware::security::keymint::toString(
199*e1997b9aSAndroid Build Coastguard Worker keyEntryResponse.metadata.keySecurityLevel);
200*e1997b9aSAndroid Build Coastguard Worker }
201*e1997b9aSAndroid Build Coastguard Worker
202*e1997b9aSAndroid Build Coastguard Worker // Make sure this is an early boot key
203*e1997b9aSAndroid Build Coastguard Worker bool foundBootLevel = false;
204*e1997b9aSAndroid Build Coastguard Worker for (const auto& auth : keyEntryResponse.metadata.authorizations) {
205*e1997b9aSAndroid Build Coastguard Worker if (auth.keyParameter.tag == Tag::MAX_BOOT_LEVEL) {
206*e1997b9aSAndroid Build Coastguard Worker if (auth.keyParameter.value.get<KeyParameterValue::integer>() == mKeyBootLevel) {
207*e1997b9aSAndroid Build Coastguard Worker foundBootLevel = true;
208*e1997b9aSAndroid Build Coastguard Worker break;
209*e1997b9aSAndroid Build Coastguard Worker }
210*e1997b9aSAndroid Build Coastguard Worker }
211*e1997b9aSAndroid Build Coastguard Worker }
212*e1997b9aSAndroid Build Coastguard Worker if (!foundBootLevel) {
213*e1997b9aSAndroid Build Coastguard Worker return Error() << "Found invalid keystore key without MAX_BOOT_LEVEL tag";
214*e1997b9aSAndroid Build Coastguard Worker }
215*e1997b9aSAndroid Build Coastguard Worker
216*e1997b9aSAndroid Build Coastguard Worker // If the key is still considered valid at this point, extract the public
217*e1997b9aSAndroid Build Coastguard Worker // key from the certificate. Note that we cannot trust this public key,
218*e1997b9aSAndroid Build Coastguard Worker // because it is a part of the keystore2 database, which can be modified by
219*e1997b9aSAndroid Build Coastguard Worker // an attacker. So instead, when creating the key we HMAC the public key
220*e1997b9aSAndroid Build Coastguard Worker // with a key of the same boot level, and verify the signature here.
221*e1997b9aSAndroid Build Coastguard Worker auto cert = keyEntryResponse.metadata.certificate;
222*e1997b9aSAndroid Build Coastguard Worker if (!cert) {
223*e1997b9aSAndroid Build Coastguard Worker return Error() << "Key did not have a certificate.";
224*e1997b9aSAndroid Build Coastguard Worker }
225*e1997b9aSAndroid Build Coastguard Worker auto publicKey = extractPublicKeyFromX509(cert.value());
226*e1997b9aSAndroid Build Coastguard Worker if (!publicKey.ok()) {
227*e1997b9aSAndroid Build Coastguard Worker return publicKey.error();
228*e1997b9aSAndroid Build Coastguard Worker }
229*e1997b9aSAndroid Build Coastguard Worker std::string publicKeyString = {publicKey->begin(), publicKey->end()};
230*e1997b9aSAndroid Build Coastguard Worker
231*e1997b9aSAndroid Build Coastguard Worker std::string signature;
232*e1997b9aSAndroid Build Coastguard Worker if (!android::base::ReadFileToString(mSignedPubKeyPath, &signature)) {
233*e1997b9aSAndroid Build Coastguard Worker return Error() << "Can't find signature for public key.";
234*e1997b9aSAndroid Build Coastguard Worker }
235*e1997b9aSAndroid Build Coastguard Worker
236*e1997b9aSAndroid Build Coastguard Worker auto signatureValid = mHmacKey.verify(publicKeyString, signature);
237*e1997b9aSAndroid Build Coastguard Worker if (!signatureValid.ok()) {
238*e1997b9aSAndroid Build Coastguard Worker return Error() << "Signature of public key did not match.";
239*e1997b9aSAndroid Build Coastguard Worker }
240*e1997b9aSAndroid Build Coastguard Worker LOG(INFO) << "Verified public key signature.";
241*e1997b9aSAndroid Build Coastguard Worker
242*e1997b9aSAndroid Build Coastguard Worker return *publicKey;
243*e1997b9aSAndroid Build Coastguard Worker }
244*e1997b9aSAndroid Build Coastguard Worker
getOrCreateKey()245*e1997b9aSAndroid Build Coastguard Worker Result<std::vector<uint8_t>> KeystoreKey::getOrCreateKey() {
246*e1997b9aSAndroid Build Coastguard Worker auto existingKey = verifyExistingKey();
247*e1997b9aSAndroid Build Coastguard Worker if (!existingKey.ok()) {
248*e1997b9aSAndroid Build Coastguard Worker LOG(INFO) << existingKey.error().message();
249*e1997b9aSAndroid Build Coastguard Worker LOG(INFO) << "Existing keystore key not found or invalid, creating new key";
250*e1997b9aSAndroid Build Coastguard Worker return createKey();
251*e1997b9aSAndroid Build Coastguard Worker }
252*e1997b9aSAndroid Build Coastguard Worker
253*e1997b9aSAndroid Build Coastguard Worker return *existingKey;
254*e1997b9aSAndroid Build Coastguard Worker }
255*e1997b9aSAndroid Build Coastguard Worker
getInstance(const std::string & signedPubKeyPath,const android::String16 & keyAlias,int64_t keyNspace,int keyBootLevel)256*e1997b9aSAndroid Build Coastguard Worker Result<SigningKey*> KeystoreKey::getInstance(const std::string& signedPubKeyPath,
257*e1997b9aSAndroid Build Coastguard Worker const android::String16& keyAlias, int64_t keyNspace,
258*e1997b9aSAndroid Build Coastguard Worker int keyBootLevel) {
259*e1997b9aSAndroid Build Coastguard Worker auto keystoreKey = new KeystoreKey(signedPubKeyPath, keyAlias, keyNspace, keyBootLevel);
260*e1997b9aSAndroid Build Coastguard Worker
261*e1997b9aSAndroid Build Coastguard Worker if (!keystoreKey->initialize()) {
262*e1997b9aSAndroid Build Coastguard Worker return Error() << "Failed to initialize keystore key.";
263*e1997b9aSAndroid Build Coastguard Worker } else {
264*e1997b9aSAndroid Build Coastguard Worker return keystoreKey;
265*e1997b9aSAndroid Build Coastguard Worker }
266*e1997b9aSAndroid Build Coastguard Worker }
267*e1997b9aSAndroid Build Coastguard Worker
getSignOpParameters()268*e1997b9aSAndroid Build Coastguard Worker static std::vector<KeyParameter> getSignOpParameters() {
269*e1997b9aSAndroid Build Coastguard Worker std::vector<KeyParameter> opParameters;
270*e1997b9aSAndroid Build Coastguard Worker
271*e1997b9aSAndroid Build Coastguard Worker KeyParameter algo;
272*e1997b9aSAndroid Build Coastguard Worker algo.tag = Tag::ALGORITHM;
273*e1997b9aSAndroid Build Coastguard Worker algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
274*e1997b9aSAndroid Build Coastguard Worker opParameters.push_back(algo);
275*e1997b9aSAndroid Build Coastguard Worker
276*e1997b9aSAndroid Build Coastguard Worker KeyParameter digest;
277*e1997b9aSAndroid Build Coastguard Worker digest.tag = Tag::DIGEST;
278*e1997b9aSAndroid Build Coastguard Worker digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
279*e1997b9aSAndroid Build Coastguard Worker opParameters.push_back(digest);
280*e1997b9aSAndroid Build Coastguard Worker
281*e1997b9aSAndroid Build Coastguard Worker KeyParameter padding;
282*e1997b9aSAndroid Build Coastguard Worker padding.tag = Tag::PADDING;
283*e1997b9aSAndroid Build Coastguard Worker padding.value =
284*e1997b9aSAndroid Build Coastguard Worker KeyParameterValue::make<KeyParameterValue::paddingMode>(PaddingMode::RSA_PKCS1_1_5_SIGN);
285*e1997b9aSAndroid Build Coastguard Worker opParameters.push_back(padding);
286*e1997b9aSAndroid Build Coastguard Worker
287*e1997b9aSAndroid Build Coastguard Worker KeyParameter purpose;
288*e1997b9aSAndroid Build Coastguard Worker purpose.tag = Tag::PURPOSE;
289*e1997b9aSAndroid Build Coastguard Worker purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
290*e1997b9aSAndroid Build Coastguard Worker opParameters.push_back(purpose);
291*e1997b9aSAndroid Build Coastguard Worker
292*e1997b9aSAndroid Build Coastguard Worker return opParameters;
293*e1997b9aSAndroid Build Coastguard Worker }
294*e1997b9aSAndroid Build Coastguard Worker
sign(const std::string & message) const295*e1997b9aSAndroid Build Coastguard Worker Result<std::string> KeystoreKey::sign(const std::string& message) const {
296*e1997b9aSAndroid Build Coastguard Worker static auto opParameters = getSignOpParameters();
297*e1997b9aSAndroid Build Coastguard Worker CreateOperationResponse opResponse;
298*e1997b9aSAndroid Build Coastguard Worker
299*e1997b9aSAndroid Build Coastguard Worker auto status = mSecurityLevel->createOperation(mDescriptor, opParameters, false, &opResponse);
300*e1997b9aSAndroid Build Coastguard Worker if (!status.isOk()) {
301*e1997b9aSAndroid Build Coastguard Worker return Error() << "Failed to create keystore signing operation: " << status;
302*e1997b9aSAndroid Build Coastguard Worker }
303*e1997b9aSAndroid Build Coastguard Worker auto operation = opResponse.iOperation;
304*e1997b9aSAndroid Build Coastguard Worker
305*e1997b9aSAndroid Build Coastguard Worker std::optional<std::vector<uint8_t>> input{std::in_place, message.begin(), message.end()};
306*e1997b9aSAndroid Build Coastguard Worker std::optional<std::vector<uint8_t>> signature;
307*e1997b9aSAndroid Build Coastguard Worker status = operation->finish(input, {}, &signature);
308*e1997b9aSAndroid Build Coastguard Worker if (!status.isOk()) {
309*e1997b9aSAndroid Build Coastguard Worker return Error() << "Failed to call keystore finish operation.";
310*e1997b9aSAndroid Build Coastguard Worker }
311*e1997b9aSAndroid Build Coastguard Worker
312*e1997b9aSAndroid Build Coastguard Worker if (!signature.has_value()) {
313*e1997b9aSAndroid Build Coastguard Worker return Error() << "Didn't receive a signature from keystore finish operation.";
314*e1997b9aSAndroid Build Coastguard Worker }
315*e1997b9aSAndroid Build Coastguard Worker
316*e1997b9aSAndroid Build Coastguard Worker return std::string{signature.value().begin(), signature.value().end()};
317*e1997b9aSAndroid Build Coastguard Worker }
318*e1997b9aSAndroid Build Coastguard Worker
getPublicKey() const319*e1997b9aSAndroid Build Coastguard Worker Result<std::vector<uint8_t>> KeystoreKey::getPublicKey() const {
320*e1997b9aSAndroid Build Coastguard Worker return mPublicKey;
321*e1997b9aSAndroid Build Coastguard Worker }
322