blob: 596d6e24000705c38edc4978350b0137db0c8817 [file] [log] [blame]
Alan Stokesbfd2ec02021-06-09 18:00:54 +01001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "FakeCompOs.h"
Alan Stokes314845d2021-06-14 15:28:39 +010018
Alan Stokes8b4cb962021-07-06 17:45:39 +010019#include "CertUtils.h"
Alan Stokesbfd2ec02021-06-09 18:00:54 +010020#include "KeyConstants.h"
21
22#include <android-base/file.h>
23#include <android-base/logging.h>
24#include <android-base/result.h>
Alan Stokes314845d2021-06-14 15:28:39 +010025#include <android-base/scopeguard.h>
26
Alan Stokesbfd2ec02021-06-09 18:00:54 +010027#include <binder/IServiceManager.h>
28
Alan Stokesb85739d2021-07-05 16:52:45 +010029#include <openssl/nid.h>
Alan Stokes314845d2021-06-14 15:28:39 +010030#include <openssl/rand.h>
Alan Stokesb85739d2021-07-05 16:52:45 +010031#include <openssl/rsa.h>
32#include <openssl/sha.h>
Alan Stokes314845d2021-06-14 15:28:39 +010033
Alan Stokesbfd2ec02021-06-09 18:00:54 +010034using android::String16;
35
36using android::hardware::security::keymint::Algorithm;
37using android::hardware::security::keymint::Digest;
38using android::hardware::security::keymint::KeyParameter;
39using android::hardware::security::keymint::KeyParameterValue;
40using android::hardware::security::keymint::KeyPurpose;
41using android::hardware::security::keymint::PaddingMode;
42using android::hardware::security::keymint::SecurityLevel;
43using android::hardware::security::keymint::Tag;
44
Alan Stokes314845d2021-06-14 15:28:39 +010045using android::system::keystore2::CreateOperationResponse;
Alan Stokesbfd2ec02021-06-09 18:00:54 +010046using android::system::keystore2::Domain;
47
48using android::base::Error;
49using android::base::Result;
50
Alan Stokes314845d2021-06-14 15:28:39 +010051using android::binder::Status;
52
53// TODO: Allocate a namespace for CompOS
54const int64_t kCompOsNamespace = 101;
55
Alan Stokescd193a92021-07-29 15:28:52 +010056Result<std::unique_ptr<FakeCompOs>>
57FakeCompOs::startInstance(const std::string& /*instanceImagePath*/) {
Alan Stokesbfd2ec02021-06-09 18:00:54 +010058 std::unique_ptr<FakeCompOs> compOs(new FakeCompOs);
59 auto init = compOs->initialize();
60 if (init.ok()) {
61 return compOs;
62 } else {
63 return init.error();
64 }
65}
66
67FakeCompOs::FakeCompOs() {}
68
69Result<void> FakeCompOs::initialize() {
70 auto sm = android::defaultServiceManager();
71 if (!sm) {
72 return Error() << "No ServiceManager";
73 }
74 auto rawService = sm->getService(String16("android.system.keystore2.IKeystoreService/default"));
75 if (!rawService) {
76 return Error() << "No Keystore service";
77 }
78 mService = interface_cast<android::system::keystore2::IKeystoreService>(rawService);
79 if (!mService) {
80 return Error() << "Bad Keystore service";
81 }
82
83 // TODO: We probably want SecurityLevel::SOFTWARE here, in the VM, but Keystore doesn't do it
84 auto status = mService->getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT, &mSecurityLevel);
85 if (!status.isOk()) {
86 return Error() << status;
87 }
88
89 return {};
90}
91
Alan Stokes314845d2021-06-14 15:28:39 +010092Result<FakeCompOs::ByteVector> FakeCompOs::signData(const ByteVector& keyBlob,
93 const ByteVector& data) const {
94 KeyDescriptor descriptor;
95 descriptor.domain = Domain::BLOB;
96 descriptor.nspace = kCompOsNamespace;
97 descriptor.blob = keyBlob;
98
99 std::vector<KeyParameter> parameters;
100
101 {
102 KeyParameter algo;
103 algo.tag = Tag::ALGORITHM;
104 algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
105 parameters.push_back(algo);
106
107 KeyParameter digest;
108 digest.tag = Tag::DIGEST;
109 digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
110 parameters.push_back(digest);
111
112 KeyParameter padding;
113 padding.tag = Tag::PADDING;
114 padding.value = KeyParameterValue::make<KeyParameterValue::paddingMode>(
115 PaddingMode::RSA_PKCS1_1_5_SIGN);
116 parameters.push_back(padding);
117
118 KeyParameter purpose;
119 purpose.tag = Tag::PURPOSE;
120 purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
121 parameters.push_back(purpose);
122 }
123
124 Status status;
125
126 CreateOperationResponse response;
127 status = mSecurityLevel->createOperation(descriptor, parameters, /*forced=*/false, &response);
128 if (!status.isOk()) {
129 return Error() << "Failed to create operation: " << status;
130 }
131
132 auto operation = response.iOperation;
133 auto abort_guard = android::base::make_scope_guard([&] { operation->abort(); });
134
135 if (response.operationChallenge.has_value()) {
136 return Error() << "Key requires user authorization";
137 }
138
139 std::optional<ByteVector> signature;
140 status = operation->finish(data, {}, &signature);
141 if (!status.isOk()) {
142 return Error() << "Failed to sign data: " << status;
143 }
144
145 abort_guard.Disable();
146
147 if (!signature.has_value()) {
148 return Error() << "No signature received from keystore.";
149 }
150
151 return signature.value();
152}
153
154Result<void> FakeCompOs::loadAndVerifyKey(const ByteVector& keyBlob,
155 const ByteVector& publicKey) const {
156 // To verify the key is valid, we use it to sign some data, and then verify the signature using
157 // the supplied public key.
158
159 ByteVector data(32);
160 if (RAND_bytes(data.data(), data.size()) != 1) {
161 return Error() << "No random bytes";
162 }
163
164 auto signature = signData(keyBlob, data);
165 if (!signature.ok()) {
166 return signature.error();
167 }
168
Alan Stokes8b4cb962021-07-06 17:45:39 +0100169 std::string signatureString(reinterpret_cast<char*>(signature.value().data()),
170 signature.value().size());
171 std::string dataString(reinterpret_cast<char*>(data.data()), data.size());
Alan Stokesd2bfee02021-07-12 15:42:58 +0100172 return verifyRsaPublicKeySignature(dataString, signatureString, publicKey);
Alan Stokes314845d2021-06-14 15:28:39 +0100173}