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 *¶ms)
43 {
44 ZLOGI("GetRootKeyParams.");
45 int32_t ret = HksInitParamSet(¶ms);
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(¶ms);
65 return ret;
66 }
67
68 ret = HksBuildParamSet(¶ms);
69 if (ret != HKS_SUCCESS) {
70 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
71 HksFreeParamSet(¶ms);
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(¶ms);
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(¶ms);
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(¶ms);
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(¶ms);
146 return {};
147 }
148
149 ret = HksBuildParamSet(¶ms);
150 if (ret != HKS_SUCCESS) {
151 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
152 HksFreeParamSet(¶ms);
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(¶ms);
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(¶ms);
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(¶ms);
197 return false;
198 }
199
200 ret = HksBuildParamSet(¶ms);
201 if (ret != HKS_SUCCESS) {
202 ZLOGE("HksBuildParamSet failed with error %{public}d", ret);
203 HksFreeParamSet(¶ms);
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(¶ms);
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