• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include "hks_openssl_kdf.h"
17 
18 #include <openssl/evp.h>
19 #include <openssl/kdf.h>
20 #include <openssl/ossl_typ.h>
21 #include <stddef.h>
22 
23 #include "hks_crypto_hal.h"
24 #include "hks_log.h"
25 #include "hks_mem.h"
26 #include "hks_openssl_engine.h"
27 #include "hks_openssl_hash.h"
28 #include "hks_template.h"
29 #include "securec.h"
30 
31 #ifdef HKS_SUPPORT_KDF_SM3
32 #define HKS_DIGEST_SM3_LEN 32
33 #define HKS_BITS_PER_INT 32
34 #define HKS_BYTE_PER_INT 4
35 #define HKS_START_NUM 1
36 #endif
GetDeriveDigestType(uint32_t digestAlg)37 static const EVP_MD *GetDeriveDigestType(uint32_t digestAlg)
38 {
39     switch (digestAlg) {
40         case (HKS_DIGEST_SHA256):
41             return EVP_sha256();
42         case (HKS_DIGEST_SHA384):
43             return EVP_sha384();
44         case (HKS_DIGEST_SHA512):
45             return EVP_sha512();
46         default:
47             return NULL;
48     }
49 }
50 
HksOpensslPbkdf2(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)51 int32_t HksOpensslPbkdf2(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
52     struct HksBlob *derivedKey)
53 {
54     struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
55     const EVP_MD *md = GetDeriveDigestType(deriveParam->digestAlg);
56     if (PKCS5_PBKDF2_HMAC((char *)mainKey->data, mainKey->size, deriveParam->salt.data, deriveParam->salt.size,
57         deriveParam->iterations, md, derivedKey->size, derivedKey->data) != 1) {
58         HKS_LOG_E("derive pbkdf2 key using openssl interface failed");
59         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
60     }
61     return HKS_SUCCESS;
62 }
63 
HksOpensslHkdf(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)64 int32_t HksOpensslHkdf(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
65     struct HksBlob *derivedKey)
66 {
67     struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
68     const EVP_MD *md = GetDeriveDigestType(deriveParam->digestAlg);
69     EVP_PKEY_CTX *pctx;
70     pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
71     int32_t ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
72     do {
73         if (EVP_PKEY_derive_init(pctx) <= 0) {
74             HksLogOpensslError();
75             break;
76         }
77         if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) {
78             HksLogOpensslError();
79             break;
80         }
81         if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, deriveParam->salt.data, deriveParam->salt.size) <= 0) {
82             HksLogOpensslError();
83             break;
84         }
85         if (EVP_PKEY_CTX_set1_hkdf_key(pctx, mainKey->data, mainKey->size) <= 0) {
86             HksLogOpensslError();
87             break;
88         }
89         if (EVP_PKEY_CTX_add1_hkdf_info(pctx, deriveParam->info.data, deriveParam->info.size) <= 0) {
90             HksLogOpensslError();
91             break;
92         }
93         size_t keyLen = derivedKey->size;
94         if (EVP_PKEY_derive(pctx, derivedKey->data, &keyLen) <= 0) {
95             HksLogOpensslError();
96             break;
97         }
98         derivedKey->size = (uint32_t)keyLen;
99         ret = HKS_SUCCESS;
100     } while (0);
101     EVP_PKEY_CTX_free(pctx);
102     return ret;
103 }
104 
105 #ifdef HKS_SUPPORT_KDF_SM3
106 
AppendKekAndFactor(const struct HksBlob * kekData,const struct HksBlob * factor,struct HksBlob * appendedData)107 static int32_t AppendKekAndFactor(const struct HksBlob *kekData, const struct HksBlob *factor,
108     struct HksBlob *appendedData)
109 {
110     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(factor), HKS_ERROR_INVALID_ARGUMENT, "Invalid param mainKey!");
111     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(kekData), HKS_ERROR_INVALID_ARGUMENT, "Invalid param derivedKey!");
112     struct HksBlob destData = {0, NULL};
113     destData.size = kekData->size + factor->size;
114     destData.data = (uint8_t *)HksMalloc(destData.size);
115     HKS_IF_NULL_LOGE_RETURN(destData.data, HKS_ERROR_MALLOC_FAIL, "malloc destData memory failed!");
116     (void)memcpy_s(destData.data, destData.size, kekData->data, kekData->size);
117     (void)memcpy_s(destData.data + kekData->size, destData.size - kekData->size, factor->data, factor->size);
118     appendedData->size = destData.size;
119     appendedData->data = destData.data;
120     return HKS_SUCCESS;
121 }
122 
HksOpensslSmKdf(const struct HksBlob * mainKey,const struct HksKeySpec * derivationSpec,struct HksBlob * derivedKey)123 int32_t HksOpensslSmKdf(const struct HksBlob *mainKey, const struct HksKeySpec *derivationSpec,
124     struct HksBlob *derivedKey)
125 {
126     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(mainKey), HKS_ERROR_INVALID_ARGUMENT, "Invalid param mainKey!");
127     HKS_IF_NOT_SUCC_LOGE_RETURN(HksOpensslCheckBlob(derivedKey),
128         HKS_ERROR_INVALID_ARGUMENT, "Invalid param derivedKey!");
129     struct HksKeyDerivationParam *deriveParam = (struct HksKeyDerivationParam *)derivationSpec->algParam;
130     struct HksBlob appendedKeyData = { 0, NULL };
131     int32_t ret = AppendKekAndFactor(mainKey, &deriveParam->info, &appendedKeyData);
132     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "append data failed!")
133     unsigned int hashSize = appendedKeyData.size + HKS_BYTE_PER_INT;
134     struct HksBlob inputHashBlob = { 0, NULL };
135     inputHashBlob.size = hashSize;
136     inputHashBlob.data = (uint8_t *)HksMalloc(inputHashBlob.size);
137     if (inputHashBlob.data == NULL) {
138         HKS_FREE(appendedKeyData.data);
139         return HKS_ERROR_MALLOC_FAIL;
140     }
141     (void)memcpy_s(inputHashBlob.data, inputHashBlob.size, appendedKeyData.data, appendedKeyData.size);
142     uint8_t digestDataArray[HKS_DIGEST_SM3_LEN] = { 0 };
143     unsigned int digestLength = HKS_DIGEST_SM3_LEN;
144     struct HksBlob cdgstBlob = {digestLength, digestDataArray};
145     unsigned int index = (derivedKey->size - 1) / HKS_DIGEST_SM3_LEN + 1; // round up
146     unsigned char counterBytes[HKS_BYTE_PER_INT] = { 0 };
147     unsigned int counter = HKS_START_NUM;
148     do {
149         for (unsigned int i = 0; i < index; i++) {
150             for (unsigned int j = HKS_START_NUM; j <= HKS_BYTE_PER_INT; j++) {
151                 counterBytes[j - 1] = (counter >> (HKS_BITS_PER_INT - HKS_BITS_PER_BYTE * j)) & 0xFF;
152             }
153             (void)memcpy_s(inputHashBlob.data + appendedKeyData.size, HKS_BYTE_PER_INT, counterBytes, HKS_BYTE_PER_INT);
154             ret = HksOpensslHash(HKS_DIGEST_SM3, &inputHashBlob, &cdgstBlob);
155             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "Hash data failed!");
156             if ((i == (index - 1)) && (derivedKey->size % HKS_DIGEST_SM3_LEN != 0)) {
157                 digestLength = (derivedKey->size) % HKS_DIGEST_SM3_LEN;
158             }
159             if (memcpy_s(derivedKey->data + HKS_DIGEST_SM3_LEN * i,
160                          digestLength, cdgstBlob.data, digestLength) != EOK) {
161                 ret = HKS_ERROR_INSUFFICIENT_MEMORY;
162                 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "memcp derivedkey data failed!");
163             }
164             counter++;
165         }
166     } while (0);
167     HKS_FREE_BLOB(appendedKeyData);
168     HKS_FREE_BLOB(inputHashBlob);
169     HKS_IF_NOT_SUCC_RETURN(ret, ret);
170     return ret;
171 }
172 #endif /* HKS_SUPPORT_KDF_SM3 */