1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "CryptoManager"
16 #include "crypto/crypto_manager.h"
17
18 #include <cstring>
19 #include <string>
20
21 #include "hks_api.h"
22 #include "hks_param.h"
23 #include "log_print.h"
24 #include "metadata/meta_data_manager.h"
25 #include "securec.h"
26
27 namespace OHOS::DistributedData {
28 static constexpr int32_t NONCE_SIZE = 12;
29 static constexpr const char *ROOT_KEY_ALIAS = "distributed_db_root_key";
30 static constexpr const char *HKS_BLOB_TYPE_NONCE = "Z5s0Bo571KoqwIi6";
31 static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata";
32
33 using system_clock = std::chrono::system_clock;
34
CryptoManager()35 CryptoManager::CryptoManager()
36 {
37 vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
38 vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
39 vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
40 }
41
~CryptoManager()42 CryptoManager::~CryptoManager()
43 {
44 }
45
GetInstance()46 CryptoManager &CryptoManager::GetInstance()
47 {
48 static CryptoManager instance;
49 return instance;
50 }
51
52 struct HksParam aes256Param[] = {
53 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
54 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
55 { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE },
56 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
57 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
58 };
59
AddHksParams(HksParamSet * params,CryptoManager::ParamConfig & paramConfig)60 bool AddHksParams(HksParamSet *params, CryptoManager::ParamConfig ¶mConfig)
61 {
62 if (paramConfig.nonce.empty()) {
63 uint8_t nonce[NONCE_SIZE] = {0};
64 struct HksBlob blobNonce = { .size = NONCE_SIZE, .data = nonce };
65 auto result = HksGenerateRandom(nullptr, &blobNonce);
66 if (result != HKS_SUCCESS) {
67 ZLOGE("HksGenerateRandom failed with error %{public}d", result);
68 return false;
69 }
70 std::vector<uint8_t> nonceContent(blobNonce.data, blobNonce.data + blobNonce.size);
71 paramConfig.nonce = nonceContent;
72 }
73
74 struct HksBlob blobAad = { uint32_t(paramConfig.aadValue.size()),
75 const_cast<uint8_t *>(paramConfig.aadValue.data()) };
76 std::vector<HksParam> hksParam = {
77 { .tag = HKS_TAG_PURPOSE, .uint32Param = paramConfig.purpose },
78 { .tag = HKS_TAG_NONCE,
79 .blob = { uint32_t(paramConfig.nonce.size()), const_cast<uint8_t *>(paramConfig.nonce.data()) } },
80 { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
81 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = paramConfig.storageLevel },
82 };
83
84 if (paramConfig.storageLevel > HKS_AUTH_STORAGE_LEVEL_DE) {
85 hksParam.emplace_back(
86 HksParam { .tag = HKS_TAG_SPECIFIC_USER_ID, .int32Param = std::atoi(paramConfig.userId.c_str()) });
87 }
88
89 auto ret = HksAddParams(params, aes256Param, sizeof(aes256Param) / sizeof(aes256Param[0]));
90 if (ret != HKS_SUCCESS) {
91 ZLOGE("HksAddParams failed with error %{public}d", ret);
92 HksFreeParamSet(¶ms);
93 return false;
94 }
95 ret = HksAddParams(params, hksParam.data(), hksParam.size());
96 if (ret != HKS_SUCCESS) {
97 ZLOGE("HksAddParams failed with error %{public}d", ret);
98 HksFreeParamSet(¶ms);
99 return false;
100 }
101 return true;
102 }
103
GetRootKeyParams(HksParamSet * & params,uint32_t storageLevel,const std::string & userId)104 int32_t GetRootKeyParams(HksParamSet *¶ms, uint32_t storageLevel, const std::string &userId)
105 {
106 int32_t ret = HksInitParamSet(¶ms);
107 if (ret != HKS_SUCCESS) {
108 ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
109 return ret;
110 }
111
112 std::vector<HksParam> hksParam = {
113 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
114 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
115 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
116 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
117 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
118 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
119 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = storageLevel },
120 };
121 if (storageLevel > HKS_AUTH_STORAGE_LEVEL_DE) {
122 hksParam.emplace_back(HksParam { .tag = HKS_TAG_SPECIFIC_USER_ID, .int32Param = std::atoi(userId.c_str()) });
123 }
124
125 ret = HksAddParams(params, hksParam.data(), hksParam.size());
126 if (ret != HKS_SUCCESS) {
127 ZLOGE("HksAddParams failed with error %{public}d", ret);
128 HksFreeParamSet(¶ms);
129 return ret;
130 }
131
132 ret = HksBuildParamSet(¶ms);
133 if (ret != HKS_SUCCESS) {
134 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
135 HksFreeParamSet(¶ms);
136 }
137 return ret;
138 }
139
GenerateRootKey()140 int32_t CryptoManager::GenerateRootKey()
141 {
142 return GenerateRootKey(HKS_AUTH_STORAGE_LEVEL_DE, DEFAULT_USER) == HKS_SUCCESS ? ErrCode::SUCCESS : ErrCode::ERROR;
143 }
144
GenerateRootKey(uint32_t storageLevel,const std::string & userId)145 int32_t CryptoManager::GenerateRootKey(uint32_t storageLevel, const std::string &userId)
146 {
147 ZLOGI("GenerateRootKey, storageLevel=%{public}u, userId=%{public}s", storageLevel, userId.c_str());
148 struct HksParamSet *params = nullptr;
149 int32_t ret = GetRootKeyParams(params, storageLevel, userId);
150 if (ret != HKS_SUCCESS || params == nullptr) {
151 ZLOGE("GetRootKeyParams failed with error %{public}d, storageLevel:%{public}u, userId:%{public}s", ret,
152 storageLevel, userId.c_str());
153 return ErrCode::ERROR;
154 }
155 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
156 ret = HksGenerateKey(&rootKeyName, params, nullptr);
157 HksFreeParamSet(¶ms);
158 if (ret == HKS_SUCCESS) {
159 ZLOGI("GenerateRootKey Succeed. storageLevel:%{public}u, userId:%{public}s", storageLevel, userId.c_str());
160 return ErrCode::SUCCESS;
161 }
162 ZLOGE("HksGenerateKey failed with error %{public}d, storageLevel:%{public}u, userId:%{public}s",
163 ret, storageLevel, userId.c_str());
164 return ErrCode::ERROR;
165 }
166
CheckRootKey()167 int32_t CryptoManager::CheckRootKey()
168 {
169 ZLOGI("CheckRootKey.");
170 return CheckRootKey(HKS_AUTH_STORAGE_LEVEL_DE, DEFAULT_USER);
171 }
172
CheckRootKey(uint32_t storageLevel,const std::string & userId)173 int32_t CryptoManager::CheckRootKey(uint32_t storageLevel, const std::string &userId)
174 {
175 struct HksParamSet *params = nullptr;
176 int32_t ret = GetRootKeyParams(params, storageLevel, userId);
177 if (ret != HKS_SUCCESS) {
178 ZLOGE("GetRootKeyParams failed with error %{public}d, storageLevel: %{public}u", ret, storageLevel);
179 return ErrCode::ERROR;
180 }
181
182 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
183 ret = HksKeyExist(&rootKeyName, params);
184 HksFreeParamSet(¶ms);
185 if (ret == HKS_SUCCESS) {
186 return ErrCode::SUCCESS;
187 }
188 ZLOGE("HksKeyExist failed with error %{public}d, storageLevel: %{public}u", ret, storageLevel);
189 if (ret == HKS_ERROR_NOT_EXIST) {
190 return ErrCode::NOT_EXIST;
191 }
192 return ErrCode::ERROR;
193 }
194
GetStorageLevel(int32_t area)195 uint32_t CryptoManager::GetStorageLevel(int32_t area)
196 {
197 if (area >= EL4 && area <= EL5) {
198 return HKS_AUTH_STORAGE_LEVEL_ECE;
199 }
200 if (area >= EL2 && area <= EL3) {
201 return HKS_AUTH_STORAGE_LEVEL_CE;
202 }
203 return HKS_AUTH_STORAGE_LEVEL_DE;
204 }
205
PrepareRootKey(uint32_t storageLevel,const std::string & userId)206 int32_t CryptoManager::PrepareRootKey(uint32_t storageLevel, const std::string &userId)
207 {
208 if (storageLevel == HKS_AUTH_STORAGE_LEVEL_DE) {
209 return ErrCode::SUCCESS;
210 }
211 auto status = CheckRootKey(storageLevel, userId);
212 if (status == ErrCode::SUCCESS) {
213 return ErrCode::SUCCESS;
214 }
215 if (status == ErrCode::NOT_EXIST && GenerateRootKey(storageLevel, userId) == ErrCode::SUCCESS) {
216 ZLOGI("GenerateRootKey success.");
217 return ErrCode::SUCCESS;
218 }
219 ZLOGW("GenerateRootKey failed, storageLevel:%{public}u, userId:%{public}s, status:%{public}d", storageLevel,
220 userId.c_str(), status);
221 return status;
222 }
223
Encrypt(const std::vector<uint8_t> & password,CryptoParams & encryptParams)224 std::vector<uint8_t> CryptoManager::Encrypt(const std::vector<uint8_t> &password, CryptoParams &encryptParams)
225 {
226 encryptParams.area = encryptParams.area < 0 ? Area::EL1 : encryptParams.area;
227 uint32_t storageLevel = GetStorageLevel(encryptParams.area);
228 if (PrepareRootKey(storageLevel, encryptParams.userId) != ErrCode::SUCCESS) {
229 return {};
230 }
231
232 struct HksParamSet *params = nullptr;
233 int32_t ret = HksInitParamSet(¶ms);
234 if (ret != HKS_SUCCESS) {
235 ZLOGE("HksInitParamSet failed with error %{public}d", ret);
236 return {};
237 }
238
239 ParamConfig paramConfig = {
240 .purpose = HKS_KEY_PURPOSE_ENCRYPT,
241 .storageLevel = storageLevel,
242 .userId = encryptParams.userId,
243 .nonce = encryptParams.nonce,
244 .aadValue = vecAad_
245 };
246 if (!AddHksParams(params, paramConfig)) {
247 return {};
248 }
249 ret = HksBuildParamSet(¶ms);
250 if (ret != HKS_SUCCESS) {
251 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
252 HksFreeParamSet(¶ms);
253 return {};
254 }
255
256 if (encryptParams.keyAlias.empty()) {
257 encryptParams.keyAlias = vecRootKeyAlias_;
258 }
259 struct HksBlob keyName = { uint32_t(encryptParams.keyAlias.size()),
260 const_cast<uint8_t *>(encryptParams.keyAlias.data())};
261 struct HksBlob plainKey = { uint32_t(password.size()), const_cast<uint8_t *>(password.data()) };
262 uint8_t cipherBuf[256] = { 0 };
263 struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
264 ret = HksEncrypt(&keyName, params, &plainKey, &cipherText);
265 (void)HksFreeParamSet(¶ms);
266 if (ret != HKS_SUCCESS) {
267 ZLOGE("HksEncrypt failed with error %{public}d", ret);
268 return {};
269 }
270
271 if (encryptParams.nonce.empty()) {
272 encryptParams.nonce = paramConfig.nonce;
273 }
274 std::vector<uint8_t> encryptedKey(cipherText.data, cipherText.data + cipherText.size);
275 std::fill(cipherBuf, cipherBuf + sizeof(cipherBuf), 0);
276 return encryptedKey;
277 }
278
Decrypt(const std::vector<uint8_t> & source,CryptoParams & decryptParams)279 std::vector<uint8_t> CryptoManager::Decrypt(const std::vector<uint8_t> &source, CryptoParams &decryptParams)
280 {
281 uint32_t storageLevel = GetStorageLevel(decryptParams.area);
282 if (PrepareRootKey(storageLevel, decryptParams.userId) != ErrCode::SUCCESS) {
283 return {};
284 }
285
286 struct HksParamSet *params = nullptr;
287 int32_t ret = HksInitParamSet(¶ms);
288 if (ret != HKS_SUCCESS) {
289 ZLOGE("HksInitParamSet failed with error %{public}d", ret);
290 return {};
291 }
292
293 ParamConfig paramConfig = {
294 .purpose = HKS_KEY_PURPOSE_DECRYPT,
295 .storageLevel = storageLevel,
296 .userId = decryptParams.userId,
297 .nonce = decryptParams.nonce.empty() ? vecNonce_ : decryptParams.nonce,
298 .aadValue = vecAad_
299 };
300 if (!AddHksParams(params, paramConfig)) {
301 return {};
302 }
303 ret = HksBuildParamSet(¶ms);
304 if (ret != HKS_SUCCESS) {
305 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
306 HksFreeParamSet(¶ms);
307 return {};
308 }
309
310 if (decryptParams.keyAlias.empty()) {
311 decryptParams.keyAlias = vecRootKeyAlias_;
312 }
313 struct HksBlob keyName = { uint32_t(decryptParams.keyAlias.size()),
314 const_cast<uint8_t *>(decryptParams.keyAlias.data()) };
315 struct HksBlob encryptedKeyBlob = { uint32_t(source.size()), const_cast<uint8_t*>(source.data()) };
316 uint8_t plainBuf[256] = { 0 };
317 struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
318
319 ret = HksDecrypt(&keyName, params, &encryptedKeyBlob, &plainKeyBlob);
320 (void)HksFreeParamSet(¶ms);
321 if (ret != HKS_SUCCESS) {
322 ZLOGE("HksDecrypt failed with error %{public}d", ret);
323 return {};
324 }
325 std::vector<uint8_t> password(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
326 return password;
327 }
328
UpdateSecretMeta(const std::vector<uint8_t> & password,const StoreMetaData & metaData,const std::string & metaKey,SecretKeyMetaData & secretKey)329 void CryptoManager::UpdateSecretMeta(const std::vector<uint8_t> &password, const StoreMetaData &metaData,
330 const std::string &metaKey, SecretKeyMetaData &secretKey)
331 {
332 if (password.empty() || (!secretKey.nonce.empty() && secretKey.area >= 0)) {
333 return;
334 }
335 CryptoParams encryptParams = { .area = metaData.area, .userId = metaData.user,
336 .nonce = secretKey.nonce };
337 auto encryptKey = Encrypt(password, encryptParams);
338 if (encryptKey.empty()) {
339 return;
340 }
341 secretKey.sKey = encryptKey;
342 secretKey.nonce = encryptParams.nonce;
343 secretKey.area = metaData.area;
344 auto time = system_clock::to_time_t(system_clock::now());
345 secretKey.time = { reinterpret_cast<uint8_t *>(&time),
346 reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
347 MetaDataManager::GetInstance().SaveMeta(metaKey, secretKey, true);
348 }
349
BuildImportKeyParams(struct HksParamSet * & params)350 bool BuildImportKeyParams(struct HksParamSet *¶ms)
351 {
352 int32_t ret = HksInitParamSet(¶ms);
353 if (ret != HKS_SUCCESS) {
354 ZLOGE("HksInitParamSet failed with error %{public}d", ret);
355 return false;
356 }
357 struct HksParam purposeParam[] = {
358 {.tag = HKS_TAG_IS_KEY_ALIAS, .boolParam = true},
359 {.tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT},
360 {.tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT},
361 {.tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
362 };
363 ret = HksAddParams(params, aes256Param, sizeof(aes256Param) / sizeof(aes256Param[0]));
364 if (ret != HKS_SUCCESS) {
365 ZLOGE("HksAddParams failed with error %{public}d", ret);
366 HksFreeParamSet(¶ms);
367 return false;
368 }
369 ret = HksAddParams(params, purposeParam, sizeof(purposeParam) / sizeof(purposeParam[0]));
370 if (ret != HKS_SUCCESS) {
371 ZLOGE("HksAddParams failed with error %{public}d", ret);
372 HksFreeParamSet(¶ms);
373 return false;
374 }
375 ret = HksBuildParamSet(¶ms);
376 if (ret != HKS_SUCCESS) {
377 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
378 HksFreeParamSet(¶ms);
379 return false;
380 }
381 return true;
382 }
383
ImportKey(const std::vector<uint8_t> & key,const std::vector<uint8_t> & keyAlias)384 bool CryptoManager::ImportKey(const std::vector<uint8_t> &key, const std::vector<uint8_t> &keyAlias)
385 {
386 std::lock_guard<std::mutex> lock(mutex_);
387 struct HksBlob hksKey = { key.size(), const_cast<uint8_t *>(key.data()) };
388 struct HksParamSet *params = nullptr;
389 if (!BuildImportKeyParams(params)) {
390 return false;
391 }
392
393 struct HksBlob keyName = { uint32_t(keyAlias.size()), const_cast<uint8_t *>(keyAlias.data()) };
394 int32_t ret = HksImportKey(&keyName, params, &hksKey);
395 if (ret != HKS_SUCCESS) {
396 ZLOGE("Import key failed: %{public}d.", ret);
397 HksFreeParamSet(¶ms);
398 return false;
399 }
400 HksFreeParamSet(¶ms);
401 return true;
402 }
403
DeleteKey(const std::vector<uint8_t> & keyAlias)404 bool CryptoManager::DeleteKey(const std::vector<uint8_t> &keyAlias)
405 {
406 struct HksBlob keyName = { uint32_t(keyAlias.size()), const_cast<uint8_t *>(keyAlias.data()) };
407 struct HksParamSet *params = nullptr;
408 if (!BuildImportKeyParams(params)) {
409 return false;
410 }
411 int32_t ret = HksDeleteKey(&keyName, params);
412 if (ret != HKS_SUCCESS) {
413 HksFreeParamSet(¶ms);
414 return false;
415 }
416 return true;
417 }
418 } // namespace OHOS::DistributedData