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_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 namespace OHOS::DistributedData {
27 using system_clock = std::chrono::system_clock;
28
CryptoManager()29 CryptoManager::CryptoManager()
30 {
31 vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
32 vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
33 vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
34 }
35
~CryptoManager()36 CryptoManager::~CryptoManager()
37 {
38 }
39
GetInstance()40 CryptoManager &CryptoManager::GetInstance()
41 {
42 static CryptoManager instance;
43 return instance;
44 }
45
46 struct HksParam aes256Param[] = {
47 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
48 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
49 { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE },
50 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
51 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
52 };
53
AddHksParams(HksParamSet * params,const CryptoManager::ParamConfig & paramConfig,const std::vector<uint8_t> & vecAad)54 bool AddHksParams(HksParamSet *params, const CryptoManager::ParamConfig ¶mConfig,
55 const std::vector<uint8_t> &vecAad)
56 {
57 struct HksBlob blobAad = { uint32_t(vecAad.size()), const_cast<uint8_t *>(vecAad.data()) };
58 std::vector<HksParam> hksParam = {
59 { .tag = HKS_TAG_PURPOSE, .uint32Param = paramConfig.purpose },
60 { .tag = HKS_TAG_NONCE,
61 .blob = { uint32_t(paramConfig.nonce.size()), const_cast<uint8_t *>(paramConfig.nonce.data()) } },
62 { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
63 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = paramConfig.storageLevel },
64 };
65 if (paramConfig.storageLevel > HKS_AUTH_STORAGE_LEVEL_DE) {
66 hksParam.emplace_back(
67 HksParam { .tag = HKS_TAG_SPECIFIC_USER_ID, .int32Param = std::atoi(paramConfig.userId.c_str()) });
68 }
69
70 auto ret = HksAddParams(params, aes256Param, sizeof(aes256Param) / sizeof(aes256Param[0]));
71 if (ret != HKS_SUCCESS) {
72 ZLOGE("HksAddParams failed with error %{public}d", ret);
73 HksFreeParamSet(¶ms);
74 return false;
75 }
76 ret = HksAddParams(params, hksParam.data(), hksParam.size());
77 if (ret != HKS_SUCCESS) {
78 ZLOGE("HksAddParams failed with error %{public}d", ret);
79 HksFreeParamSet(¶ms);
80 return false;
81 }
82 return true;
83 }
84
GetRootKeyParams(HksParamSet * & params,uint32_t storageLevel,const std::string & userId)85 int32_t GetRootKeyParams(HksParamSet *¶ms, uint32_t storageLevel, const std::string &userId)
86 {
87 int32_t ret = HksInitParamSet(¶ms);
88 if (ret != HKS_SUCCESS) {
89 ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
90 return ret;
91 }
92
93 std::vector<HksParam> hksParam = {
94 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
95 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
96 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
97 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
98 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
99 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
100 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = storageLevel },
101 };
102 if (storageLevel > HKS_AUTH_STORAGE_LEVEL_DE) {
103 hksParam.emplace_back(HksParam { .tag = HKS_TAG_SPECIFIC_USER_ID, .int32Param = std::atoi(userId.c_str()) });
104 }
105
106 ret = HksAddParams(params, hksParam.data(), hksParam.size());
107 if (ret != HKS_SUCCESS) {
108 ZLOGE("HksAddParams failed with error %{public}d", ret);
109 HksFreeParamSet(¶ms);
110 return ret;
111 }
112
113 ret = HksBuildParamSet(¶ms);
114 if (ret != HKS_SUCCESS) {
115 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
116 HksFreeParamSet(¶ms);
117 }
118 return ret;
119 }
120
GenerateRootKey()121 int32_t CryptoManager::GenerateRootKey()
122 {
123 return GenerateRootKey(HKS_AUTH_STORAGE_LEVEL_DE, DEFAULT_USER) == HKS_SUCCESS ? ErrCode::SUCCESS : ErrCode::ERROR;
124 }
125
GenerateRootKey(uint32_t storageLevel,const std::string & userId)126 int32_t CryptoManager::GenerateRootKey(uint32_t storageLevel, const std::string &userId)
127 {
128 ZLOGI("GenerateRootKey, storageLevel=%{public}u, userId=%{public}s", storageLevel, userId.c_str());
129 struct HksParamSet *params = nullptr;
130 int32_t ret = GetRootKeyParams(params, storageLevel, userId);
131 if (ret != HKS_SUCCESS || params == nullptr) {
132 ZLOGE("GetRootKeyParams failed with error %{public}d, storageLevel:%{public}u, userId:%{public}s", ret,
133 storageLevel, userId.c_str());
134 return ErrCode::ERROR;
135 }
136 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
137 ret = HksGenerateKey(&rootKeyName, params, nullptr);
138 HksFreeParamSet(¶ms);
139 if (ret == HKS_SUCCESS) {
140 ZLOGI("GenerateRootKey Succeed. storageLevel:%{public}u, userId:%{public}s", storageLevel, userId.c_str());
141 return ErrCode::SUCCESS;
142 }
143 ZLOGE("HksGenerateKey failed with error %{public}d, storageLevel:%{public}u, userId:%{public}s",
144 ret, storageLevel, userId.c_str());
145 return ErrCode::ERROR;
146 }
147
CheckRootKey()148 int32_t CryptoManager::CheckRootKey()
149 {
150 ZLOGI("CheckRootKey.");
151 return CheckRootKey(HKS_AUTH_STORAGE_LEVEL_DE, DEFAULT_USER);
152 }
153
CheckRootKey(uint32_t storageLevel,const std::string & userId)154 int32_t CryptoManager::CheckRootKey(uint32_t storageLevel, const std::string &userId)
155 {
156 struct HksParamSet *params = nullptr;
157 int32_t ret = GetRootKeyParams(params, storageLevel, userId);
158 if (ret != HKS_SUCCESS) {
159 ZLOGE("GetRootKeyParams failed with error %{public}d, storageLevel: %{public}u", ret, storageLevel);
160 return ErrCode::ERROR;
161 }
162
163 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
164 ret = HksKeyExist(&rootKeyName, params);
165 HksFreeParamSet(¶ms);
166 if (ret == HKS_SUCCESS) {
167 return ErrCode::SUCCESS;
168 }
169 ZLOGE("HksKeyExist failed with error %{public}d, storageLevel: %{public}u", ret, storageLevel);
170 if (ret == HKS_ERROR_NOT_EXIST) {
171 return ErrCode::NOT_EXIST;
172 }
173 return ErrCode::ERROR;
174 }
175
GetStorageLevel(int32_t area)176 uint32_t CryptoManager::GetStorageLevel(int32_t area)
177 {
178 if (area >= EL4 && area <= EL5) {
179 return HKS_AUTH_STORAGE_LEVEL_ECE;
180 }
181 if (area >= EL2 && area <= EL3) {
182 return HKS_AUTH_STORAGE_LEVEL_CE;
183 }
184 return HKS_AUTH_STORAGE_LEVEL_DE;
185 }
186
PrepareRootKey(uint32_t storageLevel,const std::string & userId)187 int32_t CryptoManager::PrepareRootKey(uint32_t storageLevel, const std::string &userId)
188 {
189 if (storageLevel == HKS_AUTH_STORAGE_LEVEL_DE) {
190 return ErrCode::SUCCESS;
191 }
192 auto status = CheckRootKey(storageLevel, userId);
193 if (status == ErrCode::SUCCESS) {
194 return ErrCode::SUCCESS;
195 }
196 if (status == ErrCode::NOT_EXIST && GenerateRootKey(storageLevel, userId) == ErrCode::SUCCESS) {
197 ZLOGI("GenerateRootKey success.");
198 return ErrCode::SUCCESS;
199 }
200 ZLOGW("GenerateRootKey failed, storageLevel:%{public}u, userId:%{public}s, status:%{public}d", storageLevel,
201 userId.c_str(), status);
202 return status;
203 }
Encrypt(const std::vector<uint8_t> & key,int32_t area,const std::string & userId)204 std::vector<uint8_t> CryptoManager::Encrypt(const std::vector<uint8_t> &key, int32_t area, const std::string &userId)
205 {
206 EncryptParams encryptParams = { .keyAlias = vecRootKeyAlias_, .nonce = vecNonce_ };
207 return Encrypt(key, area, userId, encryptParams);
208 }
209
Encrypt(const std::vector<uint8_t> & key)210 std::vector<uint8_t> CryptoManager::Encrypt(const std::vector<uint8_t> &key)
211 {
212 EncryptParams encryptParams = { .keyAlias = vecRootKeyAlias_, .nonce = vecNonce_ };
213 return Encrypt(key, DEFAULT_ENCRYPTION_LEVEL, DEFAULT_USER, encryptParams);
214 }
215
Encrypt(const std::vector<uint8_t> & key,const EncryptParams & encryptParams)216 std::vector<uint8_t> CryptoManager::Encrypt(const std::vector<uint8_t> &key, const EncryptParams &encryptParams)
217 {
218 return Encrypt(key, DEFAULT_ENCRYPTION_LEVEL, DEFAULT_USER, encryptParams);
219 }
220
Encrypt(const std::vector<uint8_t> & key,int32_t area,const std::string & userId,const EncryptParams & encryptParams)221 std::vector<uint8_t> CryptoManager::Encrypt(const std::vector<uint8_t> &key, int32_t area, const std::string &userId,
222 const EncryptParams &encryptParams)
223 {
224 uint32_t storageLevel = GetStorageLevel(area);
225 if (PrepareRootKey(storageLevel, userId) != ErrCode::SUCCESS) {
226 return {};
227 }
228
229 struct HksParamSet *params = nullptr;
230 int32_t ret = HksInitParamSet(¶ms);
231 if (ret != HKS_SUCCESS) {
232 ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
233 return {};
234 }
235 ParamConfig paramConfig = {
236 .nonce = encryptParams.nonce,
237 .purpose = HKS_KEY_PURPOSE_ENCRYPT,
238 .storageLevel = storageLevel,
239 .userId = userId
240 };
241 if (!AddHksParams(params, paramConfig, vecAad_)) {
242 return {};
243 }
244 ret = HksBuildParamSet(¶ms);
245 if (ret != HKS_SUCCESS) {
246 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
247 HksFreeParamSet(¶ms);
248 return {};
249 }
250
251 uint8_t cipherBuf[256] = { 0 };
252 struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
253 struct HksBlob keyName = {
254 uint32_t(encryptParams.keyAlias.size()),
255 const_cast<uint8_t *>(encryptParams.keyAlias.data())};
256 struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(key.data()) };
257 ret = HksEncrypt(&keyName, params, &plainKey, &cipherText);
258 (void)HksFreeParamSet(¶ms);
259 if (ret != HKS_SUCCESS) {
260 ZLOGE("HksEncrypt failed with error %{public}d", ret);
261 return {};
262 }
263
264 std::vector<uint8_t> encryptedKey(cipherText.data, cipherText.data + cipherText.size);
265 (void)memset_s(cipherBuf, sizeof(cipherBuf), 0, sizeof(cipherBuf));
266 return encryptedKey;
267 }
268
UpdateSecretKey(const StoreMetaData & meta,const std::vector<uint8_t> & key,SecretKeyType secretKeyType)269 bool CryptoManager::UpdateSecretKey(const StoreMetaData &meta, const std::vector<uint8_t> &key,
270 SecretKeyType secretKeyType)
271 {
272 if (!meta.isEncrypt) {
273 return false;
274 }
275 SecretKeyMetaData secretKey;
276 EncryptParams encryptParams = { .keyAlias = vecRootKeyAlias_, .nonce = vecNonce_ };
277 secretKey.storeType = meta.storeType;
278 secretKey.area = meta.area;
279 secretKey.sKey = Encrypt(key, meta.area, meta.user, encryptParams);
280 auto time = system_clock::to_time_t(system_clock::now());
281 secretKey.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
282 if (secretKeyType == LOCAL_SECRET_KEY) {
283 return MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), secretKey, true);
284 } else {
285 return MetaDataManager::GetInstance().SaveMeta(meta.GetCloneSecretKey(), secretKey, true);
286 }
287 }
288
Decrypt(const StoreMetaData & meta,SecretKeyMetaData & secretKeyMeta,std::vector<uint8_t> & key,SecretKeyType secretKeyType)289 bool CryptoManager::Decrypt(const StoreMetaData &meta, SecretKeyMetaData &secretKeyMeta, std::vector<uint8_t> &key,
290 SecretKeyType secretKeyType)
291 {
292 EncryptParams encryptParams = { .keyAlias = vecRootKeyAlias_, .nonce = vecNonce_ };
293 if (secretKeyMeta.area < 0) {
294 ZLOGI("Decrypt old secret key");
295 if (Decrypt(secretKeyMeta.sKey, key, DEFAULT_ENCRYPTION_LEVEL, DEFAULT_USER, encryptParams)) {
296 StoreMetaData metaData;
297 if (MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), metaData, true)) {
298 ZLOGI("Upgrade secret key");
299 UpdateSecretKey(metaData, key, secretKeyType);
300 }
301 return true;
302 }
303 } else {
304 return Decrypt(secretKeyMeta.sKey, key, secretKeyMeta.area, meta.user, encryptParams);
305 }
306 return false;
307 }
308
Decrypt(std::vector<uint8_t> & source,std::vector<uint8_t> & key,int32_t area,const std::string & userId)309 bool CryptoManager::Decrypt(std::vector<uint8_t> &source, std::vector<uint8_t> &key, int32_t area,
310 const std::string &userId)
311 {
312 EncryptParams encryptParams = { .keyAlias = vecRootKeyAlias_, .nonce = vecNonce_ };
313 return Decrypt(source, key, area, userId, encryptParams);
314 }
315
Decrypt(std::vector<uint8_t> & source,std::vector<uint8_t> & key,const EncryptParams & encryptParams)316 bool CryptoManager::Decrypt(std::vector<uint8_t> &source, std::vector<uint8_t> &key, const EncryptParams &encryptParams)
317 {
318 return Decrypt(source, key, DEFAULT_ENCRYPTION_LEVEL, DEFAULT_USER, encryptParams);
319 }
320
Decrypt(std::vector<uint8_t> & source,std::vector<uint8_t> & key,int32_t area,const std::string & userId,const EncryptParams & encryptParams)321 bool CryptoManager::Decrypt(std::vector<uint8_t> &source, std::vector<uint8_t> &key,
322 int32_t area, const std::string &userId, const EncryptParams &encryptParams)
323 {
324 uint32_t storageLevel = GetStorageLevel(area);
325 if (PrepareRootKey(storageLevel, userId) != ErrCode::SUCCESS) {
326 return false;
327 }
328 struct HksParamSet *params = nullptr;
329 int32_t ret = HksInitParamSet(¶ms);
330 if (ret != HKS_SUCCESS) {
331 ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
332 return false;
333 }
334
335 ParamConfig paramConfig = {
336 .nonce = encryptParams.nonce,
337 .purpose = HKS_KEY_PURPOSE_DECRYPT,
338 .storageLevel = storageLevel,
339 .userId = userId
340 };
341 if (!AddHksParams(params, paramConfig, vecAad_)) {
342 return false;
343 }
344
345 ret = HksBuildParamSet(¶ms);
346 if (ret != HKS_SUCCESS) {
347 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
348 HksFreeParamSet(¶ms);
349 return false;
350 }
351
352 uint8_t plainBuf[256] = { 0 };
353 struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
354 struct HksBlob encryptedKeyBlob = { uint32_t(source.size()), source.data() };
355 struct HksBlob keyName = { uint32_t(encryptParams.keyAlias.size()),
356 const_cast<uint8_t *>(encryptParams.keyAlias.data()) };
357
358 ret = HksDecrypt(&keyName, params, &encryptedKeyBlob, &plainKeyBlob);
359 (void)HksFreeParamSet(¶ms);
360 if (ret != HKS_SUCCESS) {
361 ZLOGE("HksDecrypt failed with error %{public}d", ret);
362 return false;
363 }
364
365 key.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
366 (void)memset_s(plainBuf, sizeof(plainBuf), 0, sizeof(plainBuf));
367 return true;
368 }
369
BuildImportKeyParams(struct HksParamSet * & params)370 bool BuildImportKeyParams(struct HksParamSet *¶ms)
371 {
372 int32_t ret = HksInitParamSet(¶ms);
373 if (ret != HKS_SUCCESS) {
374 ZLOGE("HksInitParamSet failed with error %{public}d", ret);
375 return false;
376 }
377 struct HksParam purposeParam[] = {
378 {.tag = HKS_TAG_IS_KEY_ALIAS, .boolParam = true},
379 {.tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT},
380 {.tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT},
381 {.tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
382 };
383 ret = HksAddParams(params, aes256Param, sizeof(aes256Param) / sizeof(aes256Param[0]));
384 if (ret != HKS_SUCCESS) {
385 ZLOGE("HksAddParams failed with error %{public}d", ret);
386 HksFreeParamSet(¶ms);
387 return false;
388 }
389 ret = HksAddParams(params, purposeParam, sizeof(purposeParam) / sizeof(purposeParam[0]));
390 if (ret != HKS_SUCCESS) {
391 ZLOGE("HksAddParams failed with error %{public}d", ret);
392 HksFreeParamSet(¶ms);
393 return false;
394 }
395 ret = HksBuildParamSet(¶ms);
396 if (ret != HKS_SUCCESS) {
397 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
398 HksFreeParamSet(¶ms);
399 return false;
400 }
401 return true;
402 }
403
ImportKey(const std::vector<uint8_t> & key,const std::vector<uint8_t> & keyAlias)404 bool CryptoManager::ImportKey(const std::vector<uint8_t> &key, const std::vector<uint8_t> &keyAlias)
405 {
406 std::lock_guard<std::mutex> lock(mutex_);
407 struct HksBlob hksKey = { key.size(), const_cast<uint8_t *>(key.data()) };
408 struct HksParamSet *params = nullptr;
409 if (!BuildImportKeyParams(params)) {
410 return false;
411 }
412
413 struct HksBlob keyName = { uint32_t(keyAlias.size()), const_cast<uint8_t *>(keyAlias.data()) };
414 int32_t ret = HksImportKey(&keyName, params, &hksKey);
415 if (ret != HKS_SUCCESS) {
416 ZLOGE("Import key failed: %{public}d.", ret);
417 HksFreeParamSet(¶ms);
418 return false;
419 }
420 HksFreeParamSet(¶ms);
421 return true;
422 }
423
DeleteKey(const std::vector<uint8_t> & keyAlias)424 bool CryptoManager::DeleteKey(const std::vector<uint8_t> &keyAlias)
425 {
426 struct HksBlob keyName = { uint32_t(keyAlias.size()), const_cast<uint8_t *>(keyAlias.data()) };
427 struct HksParamSet *params = nullptr;
428 if (!BuildImportKeyParams(params)) {
429 return false;
430 }
431 int32_t ret = HksDeleteKey(&keyName, params);
432 if (ret != HKS_SUCCESS) {
433 HksFreeParamSet(¶ms);
434 return false;
435 }
436 return true;
437 }
438 } // namespace OHOS::DistributedData