• 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/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 &paramConfig)
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(&params);
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(&params);
99         return false;
100     }
101     return true;
102 }
103 
GetRootKeyParams(HksParamSet * & params,uint32_t storageLevel,const std::string & userId)104 int32_t GetRootKeyParams(HksParamSet *&params, uint32_t storageLevel, const std::string &userId)
105 {
106     int32_t ret = HksInitParamSet(&params);
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(&params);
129         return ret;
130     }
131 
132     ret = HksBuildParamSet(&params);
133     if (ret != HKS_SUCCESS) {
134         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
135         HksFreeParamSet(&params);
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(&params);
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(&params);
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(&params);
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(&params);
250     if (ret != HKS_SUCCESS) {
251         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
252         HksFreeParamSet(&params);
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(&params);
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(&params);
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(&params);
304     if (ret != HKS_SUCCESS) {
305         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
306         HksFreeParamSet(&params);
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(&params);
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 *&params)
351 {
352     int32_t ret = HksInitParamSet(&params);
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(&params);
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(&params);
373         return false;
374     }
375     ret = HksBuildParamSet(&params);
376     if (ret != HKS_SUCCESS) {
377         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
378         HksFreeParamSet(&params);
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(&params);
398         return false;
399     }
400     HksFreeParamSet(&params);
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(&params);
414         return false;
415     }
416     return true;
417 }
418 } // namespace OHOS::DistributedData