• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16 
17 #include "hks_local_engine.h"
18 
19 #include <stdbool.h>
20 #include <stddef.h>
21 
22 #include "hks_ability.h"
23 #include "hks_base_check.h"
24 #include "hks_check_paramset.h"
25 #include "hks_cmd_id.h"
26 #include "hks_common_check.h"
27 #include "hks_crypto_adapter.h"
28 #include "hks_crypto_hal.h"
29 #include "hks_log.h"
30 #include "hks_mem.h"
31 #include "hks_param.h"
32 #include "hks_template.h"
33 #include "securec.h"
34 
35 #define MAX_DEGIST_SIZE 64
36 #define X25519_KEY_BYTE_SIZE 32
37 
HksLocalCryptoAbilityInit(void)38 static void HksLocalCryptoAbilityInit(void)
39 {
40     int32_t ret = HksCryptoAbilityInit();
41     HKS_IF_NOT_SUCC_LOGE(ret, "Hks local init crypto ability failed, ret = %" LOG_PUBLIC "d", ret)
42 }
43 
44 #ifndef _CUT_AUTHENTICATE_
HksLocalHash(const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * hash)45 int32_t HksLocalHash(const struct HksParamSet *paramSet, const struct HksBlob *srcData, struct HksBlob *hash)
46 {
47     HKS_IF_NOT_SUCC_RETURN(HksCheckBlob2AndParamSet(srcData, hash, paramSet), HKS_ERROR_INVALID_ARGUMENT)
48 
49     struct HksParam *digestAlg = NULL;
50     int32_t ret = HksGetParam(paramSet, HKS_TAG_DIGEST, &digestAlg);
51     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_DIGEST_FAIL, "get param digest failed")
52 
53     uint32_t digestLen;
54     ret = HksGetDigestLen(digestAlg->uint32Param, &digestLen);
55     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get digest len failed, ret = %" LOG_PUBLIC "d", ret)
56 
57     if (hash->size < digestLen) {
58         HKS_LOG_E("hash len too small, size = %" LOG_PUBLIC "u", hash->size);
59         return HKS_ERROR_BUFFER_TOO_SMALL;
60     }
61     HksLocalCryptoAbilityInit();
62     return HksCryptoHalHash(digestAlg->uint32Param, srcData, hash);
63 }
64 #endif
65 
HksLocalMac(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * mac)66 int32_t HksLocalMac(const struct HksBlob *key, const struct HksParamSet *paramSet,
67     const struct HksBlob *srcData, struct HksBlob *mac)
68 {
69     HKS_IF_NOT_SUCC_RETURN(HksCheckBlob3AndParamSet(key, srcData, mac, paramSet), HKS_ERROR_INVALID_ARGUMENT)
70     int32_t ret = HksCoreCheckMacParams(key, paramSet, srcData, mac, true);
71     HKS_IF_NOT_SUCC_RETURN(ret, ret)
72 
73     struct HksParam *digestAlg = NULL;
74     ret = HksGetParam(paramSet, HKS_TAG_DIGEST, &digestAlg);
75     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_DIGEST_FAIL, "get param digest failed")
76     HksLocalCryptoAbilityInit();
77     return HksCryptoHalHmac(key, digestAlg->uint32Param, srcData, mac);
78 }
79 
HksLocalBnExpMod(struct HksBlob * x,const struct HksBlob * a,const struct HksBlob * e,const struct HksBlob * n)80 int32_t HksLocalBnExpMod(struct HksBlob *x, const struct HksBlob *a, const struct HksBlob *e, const struct HksBlob *n)
81 {
82     int32_t ret = HksCheckBlob4(x, a, e, n);
83     HKS_IF_NOT_SUCC_RETURN(ret, ret)
84     HksLocalCryptoAbilityInit();
85     return HksCryptoHalBnExpMod(x, a, e, n);
86 }
87 
88 #ifndef _CUT_AUTHENTICATE_
CheckLocalGenerateKeyParams(const struct HksParamSet * paramSetIn,const struct HksParamSet * paramSetOut)89 static int32_t CheckLocalGenerateKeyParams(const struct HksParamSet *paramSetIn, const struct HksParamSet *paramSetOut)
90 {
91     int32_t ret;
92     if ((HksCheckParamSetValidity(paramSetIn) != HKS_SUCCESS) || (paramSetOut == NULL)) {
93         return HKS_ERROR_INVALID_ARGUMENT;
94     }
95 
96     ret = HksCoreCheckGenKeyParams(NULL, paramSetIn, NULL, NULL, HKS_KEY_FLAG_GENERATE_KEY);
97     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT,
98         "check generate key parameter failed ret = %" LOG_PUBLIC "x.", ret)
99 
100     return HKS_SUCCESS;
101 }
102 
HksLocalGenerateKey(const struct HksParamSet * paramSetIn,struct HksParamSet * paramSetOut)103 int32_t HksLocalGenerateKey(const struct HksParamSet *paramSetIn, struct HksParamSet *paramSetOut)
104 {
105     int32_t ret = CheckLocalGenerateKeyParams(paramSetIn, paramSetOut);
106     HKS_IF_NOT_SUCC_RETURN(ret, ret)
107 
108     struct HksKeySpec spec = {0};
109     HksFillKeySpec(paramSetIn, &spec);
110     struct HksBlob key = { 0, NULL };
111 
112     HksLocalCryptoAbilityInit();
113     ret = HksCryptoHalGenerateKey(&spec, &key);
114     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "local engine generate key failed, ret:%" LOG_PUBLIC "x!", ret)
115 
116     ret = HksFormatKeyFromMaterial(spec.algType, &key, paramSetOut);
117     (void)memset_s(key.data, key.size, 0, key.size);
118     HKS_FREE(key.data);
119     return ret;
120 }
121 
HksLocalAgreeKey(const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,struct HksBlob * agreedKey)122 int32_t HksLocalAgreeKey(const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
123     const struct HksBlob *peerPublicKey, struct HksBlob *agreedKey)
124 {
125     HKS_IF_NOT_SUCC_RETURN(HksCheckBlob3AndParamSet(privateKey, peerPublicKey, agreedKey, paramSet),
126         HKS_ERROR_INVALID_ARGUMENT)
127 
128     int32_t ret = HksCoreCheckAgreeKeyParams(paramSet, privateKey, peerPublicKey, agreedKey, true);
129     HKS_IF_NOT_SUCC_RETURN(ret, ret)
130 
131     struct HksKeySpec spec = {0};
132     HksFillKeySpec(paramSet, &spec);
133 
134     struct HksBlob privateKeyMaterial = { 0, NULL };
135     ret = HksSetKeyToMaterial(spec.algType, false, privateKey, &privateKeyMaterial);
136     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "set prikey to materail failed, ret:%" LOG_PUBLIC "x!", ret)
137 
138     struct HksBlob publicKeyMaterial = { 0, NULL };
139     ret = HksSetKeyToMaterial(spec.algType, true, peerPublicKey, &publicKeyMaterial);
140     if (ret != HKS_SUCCESS) {
141         HKS_LOG_E("set pubkey to materail failed, ret:%" LOG_PUBLIC "x!", ret);
142         (void)memset_s(privateKeyMaterial.data, privateKeyMaterial.size, 0, privateKeyMaterial.size);
143         HKS_FREE(privateKeyMaterial.data);
144         return ret;
145     }
146 
147     HksLocalCryptoAbilityInit();
148     ret = HksCryptoHalAgreeKey(&privateKeyMaterial, &publicKeyMaterial, &spec, agreedKey);
149     HKS_IF_NOT_SUCC_LOGE(ret, "local engine agree key failed, ret:%" LOG_PUBLIC "x!", ret)
150 
151     (void)memset_s(privateKeyMaterial.data, privateKeyMaterial.size, 0, privateKeyMaterial.size);
152     HKS_FREE(privateKeyMaterial.data);
153     (void)memset_s(publicKeyMaterial.data, publicKeyMaterial.size, 0, publicKeyMaterial.size);
154     HKS_FREE(publicKeyMaterial.data);
155     return ret;
156 }
157 #endif
158 
CipherEncrypt(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksUsageSpec * usageSpec,const struct HksBlob * inData,struct HksBlob * outData)159 static int32_t CipherEncrypt(const struct HksBlob *key, const struct HksParamSet *paramSet,
160     const struct HksUsageSpec *usageSpec, const struct HksBlob *inData, struct HksBlob *outData)
161 {
162     struct HksBlob tag = { 0, NULL };
163     int32_t ret = HksGetEncryptAeTag(paramSet, inData, outData, &tag);
164     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher encrypt get ae tag failed!")
165 
166     ret = HksCryptoHalEncrypt(key, usageSpec, inData, outData, &tag);
167     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher encrypt failed!")
168 
169     outData->size += tag.size;
170     return HKS_SUCCESS;
171 }
172 
CheckLocalCipherParams(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * inputText,struct HksBlob * outputText)173 static int32_t CheckLocalCipherParams(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
174     const struct HksBlob *inputText, struct HksBlob *outputText)
175 {
176     HKS_IF_NOT_SUCC_RETURN(HksCheckBlob3AndParamSet(key, inputText, outputText, paramSet), HKS_ERROR_INVALID_ARGUMENT)
177 
178     struct HksParam *outParam = NULL;
179     HKS_IF_NOT_SUCC_LOGE_RETURN(HksGetParam(paramSet, HKS_TAG_ALGORITHM, &outParam),
180         HKS_ERROR_CHECK_GET_ALG_FAIL, "get tag algorithm failed.")
181 
182     uint32_t keySize = 0;
183     if (outParam->uint32Param == HKS_ALG_AES) {
184         keySize = key->size * HKS_BITS_PER_BYTE;
185     } else if (outParam->uint32Param == HKS_ALG_RSA) {
186         const struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)key->data;
187         keySize = keyMaterial->keySize;
188     } else {
189         return HKS_ERROR_INVALID_ALGORITHM;
190     }
191 
192     return HksLocalCheckCipherParams(cmdId, keySize, paramSet, inputText, outputText);
193 }
194 
EncryptAndDecrypt(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * inputText,struct HksBlob * outputText)195 static int32_t EncryptAndDecrypt(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
196     const struct HksBlob *inputText, struct HksBlob *outputText)
197 {
198     int32_t ret = CheckLocalCipherParams(cmdId, key, paramSet, inputText, outputText);
199     HKS_IF_NOT_SUCC_RETURN(ret, ret)
200 
201     struct HksUsageSpec *usageSpec = NULL;
202     bool isEncrypt = (cmdId == HKS_CMD_ID_ENCRYPT);
203     struct HksBlob tmpInputText = { inputText->size, inputText->data };
204     ret = HksBuildCipherUsageSpec(paramSet, isEncrypt, &tmpInputText, &usageSpec);
205     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "build cipher usagespec failed, ret:%" LOG_PUBLIC "x!", ret)
206 
207     if (cmdId == HKS_CMD_ID_ENCRYPT) {
208         ret = CipherEncrypt(key, paramSet, usageSpec, &tmpInputText, outputText);
209     } else {
210         ret = HksCryptoHalDecrypt(key, usageSpec, &tmpInputText, outputText);
211     }
212     HksFreeUsageSpec(&usageSpec);
213 
214     HKS_IF_NOT_SUCC_LOGE(ret,
215         "local engine EncryptDecrypt cmdId = %" LOG_PUBLIC "u failed, ret:%" LOG_PUBLIC "x!", cmdId, ret)
216     return ret;
217 }
218 
HksLocalEncrypt(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * plainText,struct HksBlob * cipherText)219 int32_t HksLocalEncrypt(const struct HksBlob *key, const struct HksParamSet *paramSet,
220     const struct HksBlob *plainText, struct HksBlob *cipherText)
221 {
222     HksLocalCryptoAbilityInit();
223     return EncryptAndDecrypt(HKS_CMD_ID_ENCRYPT, key, paramSet, plainText, cipherText);
224 }
225 
HksLocalDecrypt(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * cipherText,struct HksBlob * plainText)226 int32_t HksLocalDecrypt(const struct HksBlob *key, const struct HksParamSet *paramSet,
227     const struct HksBlob *cipherText, struct HksBlob *plainText)
228 {
229     HksLocalCryptoAbilityInit();
230     return EncryptAndDecrypt(HKS_CMD_ID_DECRYPT, key, paramSet, cipherText, plainText);
231 }
232 
HksLocalDeriveKey(const struct HksParamSet * paramSet,const struct HksBlob * mainKey,struct HksBlob * derivedKey)233 int32_t HksLocalDeriveKey(const struct HksParamSet *paramSet, const struct HksBlob *mainKey,
234     struct HksBlob *derivedKey)
235 {
236     HksLocalCryptoAbilityInit();
237     HKS_IF_NOT_SUCC_RETURN(HksCheckBlob2AndParamSet(mainKey, derivedKey, paramSet), HKS_ERROR_INVALID_ARGUMENT)
238 
239     int32_t ret = HksCoreCheckDeriveKeyParams(paramSet, mainKey, derivedKey, true);
240     HKS_IF_NOT_SUCC_RETURN(ret, ret)
241 
242     struct HksKeyDerivationParam derivationParam = { { 0, NULL }, { 0, NULL }, 0, 0 };
243     struct HksKeySpec derivationSpec = { 0, 0, &derivationParam };
244 
245     HksFillKeySpec(paramSet, &derivationSpec);
246     HksFillKeyDerivationParam(paramSet, &derivationParam);
247 
248     return HksCryptoHalDeriveKey(mainKey, &derivationSpec, derivedKey);
249 }
250 
251 #ifndef _CUT_AUTHENTICATE_
CheckLocalSignVerifyParams(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,const struct HksBlob * signature)252 static int32_t CheckLocalSignVerifyParams(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
253     const struct HksBlob *srcData, const struct HksBlob *signature)
254 {
255     HksLocalCryptoAbilityInit();
256     HKS_IF_NOT_SUCC_RETURN(HksCheckBlob3AndParamSet(key, srcData, signature, paramSet), HKS_ERROR_INVALID_ARGUMENT)
257 
258     struct HksParam *algParam = NULL;
259     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
260     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL, "get param algorithm failed")
261 
262     uint32_t keySize = 0;
263     if (algParam->uint32Param == HKS_ALG_RSA) {
264         keySize = ((struct KeyMaterialRsa *)key->data)->keySize;
265     } else if (algParam->uint32Param == HKS_ALG_DSA) {
266         keySize = ((struct KeyMaterialDsa *)key->data)->keySize;
267     } else if (algParam->uint32Param == HKS_ALG_ECC) {
268         keySize = ((struct KeyMaterialEcc *)key->data)->keySize;
269     } else if (algParam->uint32Param == HKS_ALG_ED25519) {
270         keySize = key->size * HKS_BITS_PER_BYTE;
271     }
272 
273     ret = HksLocalCheckSignVerifyParams(cmdId, keySize, paramSet, srcData, signature);
274     HKS_IF_NOT_SUCC_RETURN(ret, ret)
275 
276     if (algParam->uint32Param == HKS_ALG_ED25519) {
277         if (key->size != (HKS_CURVE25519_KEY_SIZE_256 / HKS_BITS_PER_BYTE)) {
278             HKS_LOG_E("invalid key size: %" LOG_PUBLIC "u", key->size);
279             return HKS_ERROR_INVALID_KEY_SIZE;
280         }
281 
282         if (signature->size < HKS_SIGNATURE_MIN_SIZE) {
283             HKS_LOG_E("signature size too small, size: %" LOG_PUBLIC "u", signature->size);
284             return HKS_ERROR_INVALID_SIGNATURE_SIZE;
285         }
286     }
287 
288     return HKS_SUCCESS;
289 }
290 
GetSignVerifyMessage(struct HksUsageSpec * usageSpec,const struct HksBlob * srcData,struct HksBlob * message,bool * needFree)291 static int32_t GetSignVerifyMessage(struct HksUsageSpec *usageSpec, const struct HksBlob *srcData,
292     struct HksBlob *message, bool *needFree)
293 {
294     if (HksCheckNeedCache(usageSpec->algType, usageSpec->digest) == HKS_SUCCESS) {
295         message->size = srcData->size;
296         message->data = srcData->data;
297         *needFree = false;
298     } else {
299         message->size = MAX_DEGIST_SIZE;
300         message->data = (uint8_t *)HksMalloc(MAX_DEGIST_SIZE);
301         HKS_IF_NULL_LOGE_RETURN(message->data, HKS_ERROR_MALLOC_FAIL, "SignVerify malloc message data failed!")
302 
303         int32_t ret = HksCryptoHalHash(usageSpec->digest, srcData, message);
304         if (ret != HKS_SUCCESS) {
305             HKS_LOG_E("SignVerify calc hash failed!");
306             HKS_FREE(message->data);
307             return ret;
308         }
309 
310         *needFree = true;
311     }
312     return HKS_SUCCESS;
313 }
314 
HksLocalSign(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * signature)315 int32_t HksLocalSign(const struct HksBlob *key, const struct HksParamSet *paramSet, const struct HksBlob *srcData,
316     struct HksBlob *signature)
317 {
318     int32_t ret = CheckLocalSignVerifyParams(HKS_CMD_ID_SIGN, key, paramSet, srcData, signature);
319     HKS_IF_NOT_SUCC_RETURN(ret, ret)
320 
321     struct HksUsageSpec usageSpec = {0};
322     HksFillUsageSpec(paramSet, &usageSpec);
323     SetRsaPssSaltLenType(paramSet, &usageSpec);
324     bool needFree = true;
325     struct HksBlob message = { 0, NULL };
326     struct HksBlob keyMaterial = { 0, NULL };
327     do {
328         ret = HksSetKeyToMaterial(usageSpec.algType, false, key, &keyMaterial);
329         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "set key to material failed, ret:%" LOG_PUBLIC "x!", ret)
330         ret = GetSignVerifyMessage(&usageSpec, srcData, &message, &needFree);
331         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "SignVerify calc hash failed!")
332 
333         HksLocalCryptoAbilityInit();
334         ret = HksCryptoHalSign(&keyMaterial, &usageSpec, &message, signature);
335         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "local engine Sign failed, ret:%" LOG_PUBLIC "x!", ret)
336     } while (0);
337 
338     if (keyMaterial.data != NULL) {
339         (void)memset_s(keyMaterial.data, keyMaterial.size, 0, keyMaterial.size);
340         HKS_FREE(keyMaterial.data);
341     }
342     if (needFree) {
343         HKS_FREE(message.data);
344     }
345     return ret;
346 }
347 
HksLocalVerify(const struct HksBlob * key,const struct HksParamSet * paramSet,const struct HksBlob * srcData,const struct HksBlob * signature)348 int32_t HksLocalVerify(const struct HksBlob *key, const struct HksParamSet *paramSet, const struct HksBlob *srcData,
349     const struct HksBlob *signature)
350 {
351     int32_t ret = CheckLocalSignVerifyParams(HKS_CMD_ID_VERIFY, key, paramSet, srcData, signature);
352     HKS_IF_NOT_SUCC_RETURN(ret, ret)
353 
354     struct HksUsageSpec usageSpec = {0};
355     HksFillUsageSpec(paramSet, &usageSpec);
356     SetRsaPssSaltLenType(paramSet, &usageSpec);
357     bool needFree = true;
358     struct HksBlob message = { 0, NULL };
359     struct HksBlob keyMaterial = { 0, NULL };
360     do {
361         ret = HksSetKeyToMaterial(usageSpec.algType, true, key, &keyMaterial);
362         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "set key to material failed, ret:%" LOG_PUBLIC "x!", ret)
363 
364         ret = GetSignVerifyMessage(&usageSpec, srcData, &message, &needFree);
365         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "SignVerify calc hash failed!")
366 
367         HksLocalCryptoAbilityInit();
368         ret = HksCryptoHalVerify(&keyMaterial, &usageSpec, &message, signature);
369         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "local engine verify failed, ret:%" LOG_PUBLIC "x!", ret)
370     } while (0);
371 
372     if (needFree) {
373         HKS_FREE(message.data);
374     }
375     if (keyMaterial.data != NULL) {
376         (void)memset_s(keyMaterial.data, keyMaterial.size, 0, keyMaterial.size);
377         HKS_FREE(keyMaterial.data);
378     }
379     return ret;
380 }
381 #endif