• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &paramConfig,
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(&params);
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(&params);
80         return false;
81     }
82     return true;
83 }
84 
GetRootKeyParams(HksParamSet * & params,uint32_t storageLevel,const std::string & userId)85 int32_t GetRootKeyParams(HksParamSet *&params, uint32_t storageLevel, const std::string &userId)
86 {
87     int32_t ret = HksInitParamSet(&params);
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(&params);
110         return ret;
111     }
112 
113     ret = HksBuildParamSet(&params);
114     if (ret != HKS_SUCCESS) {
115         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
116         HksFreeParamSet(&params);
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(&params);
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(&params);
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(&params);
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(&params);
245     if (ret != HKS_SUCCESS) {
246         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
247         HksFreeParamSet(&params);
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(&params);
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(&params);
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(&params);
346     if (ret != HKS_SUCCESS) {
347         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
348         HksFreeParamSet(&params);
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(&params);
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 *&params)
371 {
372     int32_t ret = HksInitParamSet(&params);
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(&params);
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(&params);
393         return false;
394     }
395     ret = HksBuildParamSet(&params);
396     if (ret != HKS_SUCCESS) {
397         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
398         HksFreeParamSet(&params);
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(&params);
418         return false;
419     }
420     HksFreeParamSet(&params);
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(&params);
434         return false;
435     }
436     return true;
437 }
438 } // namespace OHOS::DistributedData