• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_KDFTLS12
18 
19 #include <stdint.h>
20 #include "securec.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_sal.h"
23 #include "crypt_local_types.h"
24 #include "crypt_errno.h"
25 #include "crypt_utils.h"
26 #include "crypt_kdf_tls12.h"
27 #include "eal_mac_local.h"
28 #include "bsl_params.h"
29 #include "crypt_params_key.h"
30 
31 #define KDFTLS12_MAX_BLOCKSIZE 64
32 
33 static const uint32_t KDFTLS12_ID_LIST[] = {
34     CRYPT_MAC_HMAC_SHA256,
35     CRYPT_MAC_HMAC_SHA384,
36     CRYPT_MAC_HMAC_SHA512,
37 };
38 
39 struct CryptKdfTls12Ctx {
40     CRYPT_MAC_AlgId macId;
41     const EAL_MacMethod *macMeth;
42     void *macCtx;
43     uint8_t *key;
44     uint32_t keyLen;
45     uint8_t *label;
46     uint32_t labelLen;
47     uint8_t *seed;
48     uint32_t seedLen;
49 };
50 
CRYPT_KDFTLS12_IsValidAlgId(CRYPT_MAC_AlgId id)51 bool CRYPT_KDFTLS12_IsValidAlgId(CRYPT_MAC_AlgId id)
52 {
53     return ParamIdIsValid(id, KDFTLS12_ID_LIST, sizeof(KDFTLS12_ID_LIST) / sizeof(KDFTLS12_ID_LIST[0]));
54 }
55 
KDF_Hmac(const EAL_MacMethod * macMeth,void * macCtx,uint8_t * data,uint32_t * len)56 int32_t KDF_Hmac(const EAL_MacMethod *macMeth, void *macCtx, uint8_t *data, uint32_t *len)
57 {
58     macMeth->reinit(macCtx);
59     int32_t ret = macMeth->update(macCtx, data, *len);
60     if (ret != CRYPT_SUCCESS) {
61         return ret;
62     }
63     return macMeth->final(macCtx, data, len);
64 }
65 
66 // algorithm implementation see https://datatracker.ietf.org/doc/pdf/rfc5246.pdf, chapter 5, p_hash function
KDF_PHASH(CRYPT_KDFTLS12_Ctx * ctx,uint8_t * out,uint32_t len)67 int32_t KDF_PHASH(CRYPT_KDFTLS12_Ctx *ctx, uint8_t *out, uint32_t len)
68 {
69     int32_t ret = CRYPT_SUCCESS;
70     const EAL_MacMethod *macMeth = ctx->macMeth;
71     uint32_t totalLen = 0;
72     uint8_t nextIn[KDFTLS12_MAX_BLOCKSIZE];
73     uint32_t nextInLen = KDFTLS12_MAX_BLOCKSIZE;
74     uint8_t outTmp[KDFTLS12_MAX_BLOCKSIZE];
75     uint32_t outTmpLen = KDFTLS12_MAX_BLOCKSIZE;
76 
77     void *macCtx = macMeth->newCtx(ctx->macId);
78     if (macCtx == NULL) {
79         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
80         return CRYPT_MEM_ALLOC_FAIL;
81     }
82     ctx->macCtx = macCtx;
83 
84     while (len > totalLen) {
85         if (totalLen == 0) {
86             GOTO_ERR_IF(macMeth->init(ctx->macCtx, ctx->key, ctx->keyLen, NULL), ret);
87             GOTO_ERR_IF(macMeth->update(ctx->macCtx, ctx->label, ctx->labelLen), ret);
88             GOTO_ERR_IF(macMeth->update(ctx->macCtx, ctx->seed, ctx->seedLen), ret);
89             GOTO_ERR_IF(macMeth->final(ctx->macCtx, nextIn, &nextInLen), ret);
90         } else {
91             GOTO_ERR_IF(KDF_Hmac(macMeth, ctx->macCtx, nextIn, &nextInLen), ret);
92         }
93 
94         macMeth->reinit(ctx->macCtx);
95         GOTO_ERR_IF(macMeth->update(ctx->macCtx, nextIn, nextInLen), ret);
96         GOTO_ERR_IF(macMeth->update(ctx->macCtx, ctx->label, ctx->labelLen), ret);
97         GOTO_ERR_IF(macMeth->update(ctx->macCtx, ctx->seed, ctx->seedLen), ret);
98         GOTO_ERR_IF(macMeth->final(ctx->macCtx, outTmp, &outTmpLen), ret);
99 
100         uint32_t cpyLen = outTmpLen > (len - totalLen) ? (len - totalLen) : outTmpLen;
101         (void)memcpy_s(out + totalLen, len - totalLen, outTmp, cpyLen);
102         totalLen += cpyLen;
103     }
104 
105 ERR:
106     macMeth->deinit(ctx->macCtx);
107     macMeth->freeCtx(ctx->macCtx);
108     ctx->macCtx = NULL;
109     return ret;
110 }
111 
CRYPT_KDFTLS12_NewCtx(void)112 CRYPT_KDFTLS12_Ctx* CRYPT_KDFTLS12_NewCtx(void)
113 {
114     CRYPT_KDFTLS12_Ctx *ctx = BSL_SAL_Calloc(1, sizeof(CRYPT_KDFTLS12_Ctx));
115     if (ctx == NULL) {
116         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
117         return NULL;
118     }
119     return ctx;
120 }
121 
CRYPT_KDFTLS12_SetMacMethod(CRYPT_KDFTLS12_Ctx * ctx,const CRYPT_MAC_AlgId id)122 int32_t CRYPT_KDFTLS12_SetMacMethod(CRYPT_KDFTLS12_Ctx *ctx, const CRYPT_MAC_AlgId id)
123 {
124     EAL_MacMethLookup method;
125     if (!CRYPT_KDFTLS12_IsValidAlgId(id)) {
126         BSL_ERR_PUSH_ERROR(CRYPT_KDFTLS12_PARAM_ERROR);
127         return CRYPT_KDFTLS12_PARAM_ERROR;
128     }
129     int32_t ret = EAL_MacFindMethod(id, &method);
130     if (ret != CRYPT_SUCCESS) {
131         BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_METH_NULL_NUMBER);
132         return CRYPT_EAL_ERR_METH_NULL_NUMBER;
133     }
134     ctx->macMeth = method.macMethod;
135     ctx->macId = id;
136     return CRYPT_SUCCESS;
137 }
138 
CRYPT_KDFTLS12_SetKey(CRYPT_KDFTLS12_Ctx * ctx,const uint8_t * key,uint32_t keyLen)139 int32_t CRYPT_KDFTLS12_SetKey(CRYPT_KDFTLS12_Ctx *ctx, const uint8_t *key, uint32_t keyLen)
140 {
141     if (key == NULL && keyLen > 0) {
142         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
143         return CRYPT_NULL_INPUT;
144     }
145 
146     BSL_SAL_ClearFree((void *)ctx->key, ctx->keyLen);
147 
148     ctx->key = BSL_SAL_Dump(key, keyLen);
149     if (ctx->key == NULL && keyLen > 0) {
150         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
151         return CRYPT_MEM_ALLOC_FAIL;
152     }
153     ctx->keyLen = keyLen;
154     return CRYPT_SUCCESS;
155 }
156 
CRYPT_KDFTLS12_SetLabel(CRYPT_KDFTLS12_Ctx * ctx,const uint8_t * label,uint32_t labelLen)157 int32_t CRYPT_KDFTLS12_SetLabel(CRYPT_KDFTLS12_Ctx *ctx, const uint8_t *label, uint32_t labelLen)
158 {
159     if (label == NULL && labelLen > 0) {
160         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
161         return CRYPT_NULL_INPUT;
162     }
163 
164     BSL_SAL_ClearFree((void *)ctx->label, ctx->labelLen);
165 
166     ctx->label = BSL_SAL_Dump(label, labelLen);
167     if (ctx->label == NULL && labelLen > 0) {
168         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
169         return CRYPT_MEM_ALLOC_FAIL;
170     }
171     ctx->labelLen = labelLen;
172     return CRYPT_SUCCESS;
173 }
174 
CRYPT_KDFTLS12_SetSeed(CRYPT_KDFTLS12_Ctx * ctx,const uint8_t * seed,uint32_t seedLen)175 int32_t CRYPT_KDFTLS12_SetSeed(CRYPT_KDFTLS12_Ctx *ctx, const uint8_t *seed, uint32_t seedLen)
176 {
177     if (seed == NULL && seedLen > 0) {
178         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
179         return CRYPT_NULL_INPUT;
180     }
181 
182     BSL_SAL_ClearFree((void *)ctx->seed, ctx->seedLen);
183 
184     ctx->seed = BSL_SAL_Dump(seed, seedLen);
185     if (ctx->seed == NULL && seedLen > 0) {
186         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
187         return CRYPT_MEM_ALLOC_FAIL;
188     }
189     ctx->seedLen = seedLen;
190     return CRYPT_SUCCESS;
191 }
192 
CRYPT_KDFTLS12_SetParam(CRYPT_KDFTLS12_Ctx * ctx,const BSL_Param * param)193 int32_t CRYPT_KDFTLS12_SetParam(CRYPT_KDFTLS12_Ctx *ctx, const BSL_Param *param)
194 {
195     uint32_t val = 0;
196     uint32_t len = 0;
197     const BSL_Param *temp = NULL;
198     int32_t ret = CRYPT_PBKDF2_PARAM_ERROR;
199     if (ctx == NULL || param == NULL) {
200         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
201         return CRYPT_NULL_INPUT;
202     }
203 
204     if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_KDF_MAC_ID)) != NULL) {
205         len = sizeof(val);
206         GOTO_ERR_IF(BSL_PARAM_GetValue(temp, CRYPT_PARAM_KDF_MAC_ID,
207             BSL_PARAM_TYPE_UINT32, &val, &len), ret);
208         GOTO_ERR_IF(CRYPT_KDFTLS12_SetMacMethod(ctx, val), ret);
209     }
210     if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_KDF_KEY)) != NULL) {
211         GOTO_ERR_IF(CRYPT_KDFTLS12_SetKey(ctx, temp->value, temp->valueLen), ret);
212     }
213     if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_KDF_LABEL)) != NULL) {
214         GOTO_ERR_IF(CRYPT_KDFTLS12_SetLabel(ctx, temp->value, temp->valueLen), ret);
215     }
216     if ((temp = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_KDF_SEED)) != NULL) {
217         GOTO_ERR_IF(CRYPT_KDFTLS12_SetSeed(ctx, temp->value, temp->valueLen), ret);
218     }
219 ERR:
220     return ret;
221 }
222 
CRYPT_KDFTLS12_Derive(CRYPT_KDFTLS12_Ctx * ctx,uint8_t * out,uint32_t len)223 int32_t CRYPT_KDFTLS12_Derive(CRYPT_KDFTLS12_Ctx *ctx, uint8_t *out, uint32_t len)
224 {
225     if (ctx->macMeth == NULL) {
226         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
227         return CRYPT_NULL_INPUT;
228     }
229     if (ctx->key == NULL && ctx->keyLen > 0) {
230         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
231         return CRYPT_NULL_INPUT;
232     }
233     if (ctx->label == NULL && ctx->labelLen > 0) {
234         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
235         return CRYPT_NULL_INPUT;
236     }
237     if (ctx->seed == NULL && ctx->seedLen > 0) {
238         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
239         return CRYPT_NULL_INPUT;
240     }
241     if ((out == NULL) || (len == 0)) {
242         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
243         return CRYPT_NULL_INPUT;
244     }
245 
246     return KDF_PHASH(ctx, out, len);
247 }
248 
CRYPT_KDFTLS12_Deinit(CRYPT_KDFTLS12_Ctx * ctx)249 int32_t CRYPT_KDFTLS12_Deinit(CRYPT_KDFTLS12_Ctx *ctx)
250 {
251     if (ctx == NULL) {
252         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
253         return CRYPT_NULL_INPUT;
254     }
255     BSL_SAL_ClearFree((void *)ctx->key, ctx->keyLen);
256     BSL_SAL_ClearFree((void *)ctx->label, ctx->labelLen);
257     BSL_SAL_ClearFree((void *)ctx->seed, ctx->seedLen);
258     (void)memset_s(ctx, sizeof(CRYPT_KDFTLS12_Ctx), 0, sizeof(CRYPT_KDFTLS12_Ctx));
259     return CRYPT_SUCCESS;
260 }
261 
CRYPT_KDFTLS12_FreeCtx(CRYPT_KDFTLS12_Ctx * ctx)262 void CRYPT_KDFTLS12_FreeCtx(CRYPT_KDFTLS12_Ctx *ctx)
263 {
264     if (ctx == NULL) {
265         return;
266     }
267     BSL_SAL_ClearFree((void *)ctx->key, ctx->keyLen);
268     BSL_SAL_ClearFree((void *)ctx->label, ctx->labelLen);
269     BSL_SAL_ClearFree((void *)ctx->seed, ctx->seedLen);
270     BSL_SAL_Free(ctx);
271 }
272 
273 #endif // HITLS_CRYPTO_KDFTLS12
274