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