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 
20 #include "hks_api.h"
21 #include "hks_param.h"
22 #include "log_print.h"
23 #include "securec.h"
24 namespace OHOS::DistributedData {
CryptoManager()25 CryptoManager::CryptoManager()
26 {
27     vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
28     vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
29     vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
30 }
31 
~CryptoManager()32 CryptoManager::~CryptoManager()
33 {
34 }
35 
GetInstance()36 CryptoManager &CryptoManager::GetInstance()
37 {
38     static CryptoManager instance;
39     return instance;
40 }
41 
GetRootKeyParams(HksParamSet * & params)42 int32_t GetRootKeyParams(HksParamSet *&params)
43 {
44     ZLOGI("GetRootKeyParams.");
45     int32_t ret = HksInitParamSet(&params);
46     if (ret != HKS_SUCCESS) {
47         ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
48         return ret;
49     }
50 
51     struct HksParam hksParam[] = {
52         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
53         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
54         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
55         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
56         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
57         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
58         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
59     };
60 
61     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
62     if (ret != HKS_SUCCESS) {
63         ZLOGE("HksAddParams failed with error %{public}d", ret);
64         HksFreeParamSet(&params);
65         return ret;
66     }
67 
68     ret = HksBuildParamSet(&params);
69     if (ret != HKS_SUCCESS) {
70         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
71         HksFreeParamSet(&params);
72     }
73     return ret;
74 }
75 
GenerateRootKey()76 int32_t CryptoManager::GenerateRootKey()
77 {
78     ZLOGI("GenerateRootKey.");
79     struct HksParamSet *params = nullptr;
80     int32_t ret = GetRootKeyParams(params);
81     if (ret != HKS_SUCCESS) {
82         ZLOGE("GetRootKeyParams failed with error %{public}d", ret);
83         return ErrCode::ERROR;
84     }
85     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
86     ret = HksGenerateKey(&rootKeyName, params, nullptr);
87     HksFreeParamSet(&params);
88     if (ret == HKS_SUCCESS) {
89         ZLOGI("GenerateRootKey Succeed.");
90         return ErrCode::SUCCESS;
91     }
92 
93     ZLOGE("HksGenerateKey failed with error %{public}d", ret);
94     return ErrCode::ERROR;
95 }
96 
CheckRootKey()97 int32_t CryptoManager::CheckRootKey()
98 {
99     ZLOGI("CheckRootKey.");
100     struct HksParamSet *params = nullptr;
101     int32_t ret = GetRootKeyParams(params);
102     if (ret != HKS_SUCCESS) {
103         ZLOGE("GetRootKeyParams failed with error %{public}d", ret);
104         return ErrCode::ERROR;
105     }
106 
107     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
108     ret = HksKeyExist(&rootKeyName, params);
109     HksFreeParamSet(&params);
110     if (ret == HKS_SUCCESS) {
111         return ErrCode::SUCCESS;
112     }
113     ZLOGE("HksKeyExist failed with error %{public}d", ret);
114     if (ret == HKS_ERROR_NOT_EXIST) {
115         return ErrCode::NOT_EXIST;
116     }
117     return ErrCode::ERROR;
118 }
119 
Encrypt(const std::vector<uint8_t> & key)120 std::vector<uint8_t> CryptoManager::Encrypt(const std::vector<uint8_t> &key)
121 {
122     struct HksBlob blobAad = { uint32_t(vecAad_.size()), vecAad_.data() };
123     struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), vecNonce_.data() };
124     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
125     struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(key.data()) };
126     struct HksParamSet *params = nullptr;
127     int32_t ret = HksInitParamSet(&params);
128     if (ret != HKS_SUCCESS) {
129         ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
130         return {};
131     }
132     struct HksParam hksParam[] = {
133         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
134         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
135         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
136         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
137         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
138         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
139         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
140         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
141     };
142     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
143     if (ret != HKS_SUCCESS) {
144         ZLOGE("HksAddParams failed with error %{public}d", ret);
145         HksFreeParamSet(&params);
146         return {};
147     }
148 
149     ret = HksBuildParamSet(&params);
150     if (ret != HKS_SUCCESS) {
151         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
152         HksFreeParamSet(&params);
153         return {};
154     }
155 
156     uint8_t cipherBuf[256] = { 0 };
157     struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
158     ret = HksEncrypt(&rootKeyName, params, &plainKey, &cipherText);
159     (void)HksFreeParamSet(&params);
160     if (ret != HKS_SUCCESS) {
161         ZLOGE("HksEncrypt failed with error %{public}d", ret);
162         return {};
163     }
164 
165     std::vector<uint8_t> encryptedKey(cipherText.data, cipherText.data + cipherText.size);
166     (void)memset_s(cipherBuf, sizeof(cipherBuf), 0, sizeof(cipherBuf));
167     return encryptedKey;
168 }
169 
Decrypt(std::vector<uint8_t> & source,std::vector<uint8_t> & key)170 bool CryptoManager::Decrypt(std::vector<uint8_t> &source, std::vector<uint8_t> &key)
171 {
172     struct HksBlob blobAad = { uint32_t(vecAad_.size()), &(vecAad_[0]) };
173     struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), &(vecNonce_[0]) };
174     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
175     struct HksBlob encryptedKeyBlob = { uint32_t(source.size()), source.data() };
176 
177     struct HksParamSet *params = nullptr;
178     int32_t ret = HksInitParamSet(&params);
179     if (ret != HKS_SUCCESS) {
180         ZLOGE("HksInitParamSet() failed with error %{public}d", ret);
181         return false;
182     }
183     struct HksParam hksParam[] = {
184         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
185         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
186         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
187         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
188         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
189         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
190         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
191         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
192     };
193     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
194     if (ret != HKS_SUCCESS) {
195         ZLOGE("HksAddParams failed with error %{public}d", ret);
196         HksFreeParamSet(&params);
197         return false;
198     }
199 
200     ret = HksBuildParamSet(&params);
201     if (ret != HKS_SUCCESS) {
202         ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
203         HksFreeParamSet(&params);
204         return false;
205     }
206 
207     uint8_t plainBuf[256] = { 0 };
208     struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
209     ret = HksDecrypt(&rootKeyName, params, &encryptedKeyBlob, &plainKeyBlob);
210     (void)HksFreeParamSet(&params);
211     if (ret != HKS_SUCCESS) {
212         ZLOGE("HksDecrypt failed with error %{public}d", ret);
213         return false;
214     }
215 
216     key.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
217     (void)memset_s(plainBuf, sizeof(plainBuf), 0, sizeof(plainBuf));
218     return true;
219 }
220 } // namespace OHOS::DistributedData