blob: 82e77122c3d589c14d99125f24c01115522361ca [file] [log] [blame]
Shawn Willden815e8962020-12-11 13:05:27 +00001/*
2 * Copyright 2020, 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#define LOG_TAG "android.hardware.security.keymint-impl"
18#include <log/log.h>
19
20#include "AndroidKeyMintDevice.h"
21
22#include <aidl/android/hardware/security/keymint/ErrorCode.h>
23
24#include <keymaster/android_keymaster.h>
25#include <keymaster/contexts/pure_soft_keymaster_context.h>
26#include <keymaster/keymaster_configuration.h>
27
28#include "AndroidKeyMintOperation.h"
29#include "KeyMintUtils.h"
30
31namespace aidl::android::hardware::security::keymint {
32
33using namespace ::keymaster;
34
35constexpr size_t kOperationTableSize = 16;
36
37AndroidKeyMintDevice::AndroidKeyMintDevice(SecurityLevel securityLevel)
38 : impl_(new ::keymaster::AndroidKeymaster(
39 [&]() -> auto {
40 auto context = new PureSoftKeymasterContext(
41 KmVersion::KEYMINT_1, static_cast<keymaster_security_level_t>(securityLevel));
42 context->SetSystemVersion(::keymaster::GetOsVersion(),
43 ::keymaster::GetOsPatchlevel());
44 return context;
45 }(),
46 kOperationTableSize)),
47 securityLevel_(securityLevel) {}
48
49AndroidKeyMintDevice::~AndroidKeyMintDevice() {}
50
51ScopedAStatus AndroidKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) {
52 info->versionNumber = 1;
53 info->securityLevel = securityLevel_;
54 info->keyMintName = "FakeKeyMintDevice";
55 info->keyMintAuthorName = "Google";
56
57 return ScopedAStatus::ok();
58}
59
60ScopedAStatus AndroidKeyMintDevice::verifyAuthorization(int64_t challenge, //
61 const HardwareAuthToken& authToken, //
62 VerificationToken* verificationToken) {
63
64 VerifyAuthorizationRequest request;
65 request.challenge = static_cast<uint64_t>(challenge);
66 request.auth_token.challenge = authToken.challenge;
67 request.auth_token.user_id = authToken.userId;
68 request.auth_token.authenticator_id = authToken.authenticatorId;
69 request.auth_token.authenticator_type = legacy_enum_conversion(authToken.authenticatorType);
70
71 // TODO(seleneh) b/162481130 remove the casting once uint is supported in aidl
72 request.auth_token.timestamp = static_cast<uint64_t>(authToken.timestamp.milliSeconds);
73 KeymasterBlob mac(authToken.mac.data(), authToken.mac.size());
74 request.auth_token.mac = KeymasterBlob(authToken.mac.data(), authToken.mac.size());
75
76 auto response = impl_->VerifyAuthorization(request);
77
78 if (response.error != KM_ERROR_OK) {
79 return kmError2ScopedAStatus(response.error);
80 }
81
82 verificationToken->challenge = response.token.challenge;
83 verificationToken->timestamp.milliSeconds = static_cast<int64_t>(response.token.timestamp);
84 verificationToken->securityLevel = legacy_enum_conversion(response.token.security_level);
85 verificationToken->mac = kmBlob2vector(response.token.mac);
86
87 return ScopedAStatus::ok();
88}
89
90ScopedAStatus AndroidKeyMintDevice::addRngEntropy(const vector<uint8_t>& data) {
91 if (data.size() == 0) {
92 return ScopedAStatus::ok();
93 }
94
95 AddEntropyRequest request;
96 request.random_data.Reinitialize(data.data(), data.size());
97
98 AddEntropyResponse response;
99 impl_->AddRngEntropy(request, &response);
100
101 return kmError2ScopedAStatus(response.error);
102}
103
104ScopedAStatus AndroidKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams,
105 ByteArray* generatedKeyBlob,
106 KeyCharacteristics* generatedKeyCharacteristics,
107 vector<Certificate>* /* certChain */) {
108
109 GenerateKeyRequest request;
110 request.key_description.Reinitialize(KmParamSet(keyParams));
111
112 GenerateKeyResponse response;
113 impl_->GenerateKey(request, &response);
114
115 if (response.error != KM_ERROR_OK) {
116 // Note a key difference between this current aidl and previous hal, is
117 // that hal returns void where as aidl returns the error status. If
118 // aidl returns error, then aidl will not return any change you may make
119 // to the out parameters. This is quite different from hal where all
120 // output variable can be modified due to hal returning void.
121 //
122 // So the caller need to be aware not to expect aidl functions to clear
123 // the output variables for you in case of error. If you left some
124 // wrong data set in the out parameters, they will stay there.
125 return kmError2ScopedAStatus(response.error);
126 }
127
128 generatedKeyBlob->data = kmBlob2vector(response.key_blob);
129 generatedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
130 generatedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
131
132 return ScopedAStatus::ok();
133}
134
135ScopedAStatus AndroidKeyMintDevice::importKey(const vector<KeyParameter>& keyParams,
136 KeyFormat keyFormat, const vector<uint8_t>& keyData,
137 ByteArray* importedKeyBlob,
138 KeyCharacteristics* importedKeyCharacteristics,
139 vector<Certificate>* /* certChain */) {
140
141 ImportKeyRequest request;
142 request.key_description.Reinitialize(KmParamSet(keyParams));
143 request.key_format = legacy_enum_conversion(keyFormat);
144 request.SetKeyMaterial(keyData.data(), keyData.size());
145
146 ImportKeyResponse response;
147 impl_->ImportKey(request, &response);
148
149 if (response.error != KM_ERROR_OK) {
150 return kmError2ScopedAStatus(response.error);
151 }
152
153 importedKeyBlob->data = kmBlob2vector(response.key_blob);
154 importedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
155 importedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
156
157 return ScopedAStatus::ok();
158}
159
160ScopedAStatus AndroidKeyMintDevice::importWrappedKey(
161 const vector<uint8_t>& wrappedKeyData, const vector<uint8_t>& wrappingKeyBlob,
162 const vector<uint8_t>& maskingKey, const vector<KeyParameter>& unwrappingParams,
163 int64_t passwordSid, int64_t biometricSid, ByteArray* importedKeyBlob,
164 KeyCharacteristics* importedKeyCharacteristics) {
165
166 ImportWrappedKeyRequest request;
167 request.SetWrappedMaterial(wrappedKeyData.data(), wrappedKeyData.size());
168 request.SetWrappingMaterial(wrappingKeyBlob.data(), wrappingKeyBlob.size());
169 request.SetMaskingKeyMaterial(maskingKey.data(), maskingKey.size());
170 request.additional_params.Reinitialize(KmParamSet(unwrappingParams));
171 request.password_sid = static_cast<uint64_t>(passwordSid);
172 request.biometric_sid = static_cast<uint64_t>(biometricSid);
173
174 ImportWrappedKeyResponse response;
175 impl_->ImportWrappedKey(request, &response);
176
177 if (response.error != KM_ERROR_OK) {
178 return kmError2ScopedAStatus(response.error);
179 }
180
181 importedKeyBlob->data = kmBlob2vector(response.key_blob);
182 importedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
183 importedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
184
185 return ScopedAStatus::ok();
186}
187
188ScopedAStatus AndroidKeyMintDevice::upgradeKey(const vector<uint8_t>& keyBlobToUpgrade,
189 const vector<KeyParameter>& upgradeParams,
190 vector<uint8_t>* keyBlob) {
191
192 UpgradeKeyRequest request;
193 request.SetKeyMaterial(keyBlobToUpgrade.data(), keyBlobToUpgrade.size());
194 request.upgrade_params.Reinitialize(KmParamSet(upgradeParams));
195
196 UpgradeKeyResponse response;
197 impl_->UpgradeKey(request, &response);
198
199 if (response.error != KM_ERROR_OK) {
200 return kmError2ScopedAStatus(response.error);
201 }
202
203 *keyBlob = kmBlob2vector(response.upgraded_key);
204 return ScopedAStatus::ok();
205}
206
207ScopedAStatus AndroidKeyMintDevice::deleteKey(const vector<uint8_t>& keyBlob) {
208 DeleteKeyRequest request;
209 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
210
211 DeleteKeyResponse response;
212 impl_->DeleteKey(request, &response);
213
214 return kmError2ScopedAStatus(response.error);
215}
216
217ScopedAStatus AndroidKeyMintDevice::deleteAllKeys() {
218 // There's nothing to be done to delete software key blobs.
219 DeleteAllKeysRequest request;
220 DeleteAllKeysResponse response;
221 impl_->DeleteAllKeys(request, &response);
222
223 return kmError2ScopedAStatus(response.error);
224}
225
226ScopedAStatus AndroidKeyMintDevice::destroyAttestationIds() {
227 return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
228}
229
230ScopedAStatus AndroidKeyMintDevice::begin(KeyPurpose purpose, const vector<uint8_t>& keyBlob,
231 const vector<KeyParameter>& params,
232 const HardwareAuthToken& authToken, BeginResult* result) {
233
234 BeginOperationRequest request;
235 request.purpose = legacy_enum_conversion(purpose);
236 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
237 request.additional_params.Reinitialize(KmParamSet(params));
238
239 vector<uint8_t> vector_token = authToken2AidlVec(authToken);
240 request.additional_params.push_back(
241 TAG_AUTH_TOKEN, reinterpret_cast<uint8_t*>(vector_token.data()), vector_token.size());
242
243 BeginOperationResponse response;
244 impl_->BeginOperation(request, &response);
245
246 if (response.error != KM_ERROR_OK) {
247 return kmError2ScopedAStatus(response.error);
248 }
249
250 result->params = kmParamSet2Aidl(response.output_params);
251 result->challenge = response.op_handle;
252 result->operation =
253 ndk::SharedRefBase::make<AndroidKeyMintOperation>(impl_, response.op_handle);
254 return ScopedAStatus::ok();
255}
256
257IKeyMintDevice* CreateKeyMintDevice(SecurityLevel securityLevel) {
258
259 return ::new AndroidKeyMintDevice(securityLevel);
260}
261
262} // namespace aidl::android::hardware::security::keymint