• 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 #include "hitls_build.h"
16 #ifdef HITLS_TLS_HOST_SERVER
17 #if defined(HITLS_TLS_PROTO_TLS_BASIC) || defined(HITLS_TLS_PROTO_DTLS12)
18 #include <stdint.h>
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "tls_binlog_id.h"
22 #include "bsl_log_internal.h"
23 #include "bsl_log.h"
24 #include "bsl_err_internal.h"
25 #include "bsl_bytes.h"
26 #include "hitls_error.h"
27 #include "tls.h"
28 #include "cipher_suite.h"
29 #include "crypt.h"
30 #include "cert.h"
31 #include "hs_ctx.h"
32 #include "hs_common.h"
33 #include "pack_common.h"
34 
35 #if defined(HITLS_TLS_SUITE_KX_ECDHE) || defined(HITLS_TLS_SUITE_KX_DHE)
36 /* Determine whether additional parameter signatures are required. */
IsNeedKeyExchParamSignature(const TLS_Ctx * ctx)37 static bool IsNeedKeyExchParamSignature(const TLS_Ctx *ctx)
38 {
39     /* Add the parameter signature only when the authentication algorithm is not HITLS_AUTH_NULL for the DHE and ECDHE
40      * cipher suites */
41     return ((ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_ECDHE ||
42                 ctx->hsCtx->kxCtx->keyExchAlgo == HITLS_KEY_EXCH_DHE) &&
43             ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_NULL);
44 }
45 #endif
46 
47 #if defined(HITLS_TLS_SUITE_KX_ECDHE) || defined(HITLS_TLS_SUITE_KX_DHE)
SignKeyExchParams(TLS_Ctx * ctx,uint8_t * kxData,uint32_t kxDataLen,uint8_t * signBuf,uint32_t * signLen)48 static int32_t SignKeyExchParams(TLS_Ctx *ctx, uint8_t *kxData, uint32_t kxDataLen, uint8_t *signBuf, uint32_t *signLen)
49 {
50     uint32_t offset = 0u;
51     HITLS_SignHashAlgo signScheme = ctx->negotiatedInfo.signScheme;
52     HITLS_SignAlgo signAlgo;
53     HITLS_HashAlgo hashAlgo;
54     if (CFG_GetSignParamBySchemes(ctx, signScheme, &signAlgo, &hashAlgo) != true) {
55         BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
56         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15496, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
57             "get sign parm fail.", 0, 0, 0, 0);
58         return HITLS_PACK_SIGNATURE_ERR;
59     }
60 
61     uint32_t dataLen;
62     /* Obtain all signature data (random number + server kx content) */
63     uint8_t *data = HS_PrepareSignData(ctx, kxData, kxDataLen, &dataLen);
64     if (data == NULL) {
65         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
66         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15495, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
67             "prepare unsigned data fail.", 0, 0, 0, 0);
68         return HITLS_MEMALLOC_FAIL;
69     }
70 #ifdef HITLS_TLS_PROTO_TLCP11
71     if (ctx->negotiatedInfo.version != HITLS_VERSION_TLCP_DTLCP11)
72 #endif /* HITLS_TLS_PROTO_TLCP11 */
73     {
74         if (ctx->negotiatedInfo.version >= HITLS_VERSION_TLS12) {
75             /* TLS1.2 and later versions require explicit hash and signature algorithms to be specified in messages, and
76              * TLCP are not written */
77             BSL_Uint16ToByte(signScheme, signBuf);
78             offset += sizeof(uint16_t);
79         }
80     }
81     /* Temporarily record the position of the signature length in the packet and fill it later */
82     uint32_t signLenOffset = offset;
83     offset += sizeof(uint16_t);
84 
85     /* Fill signature parameters */
86     CERT_SignParam signParam = {0};
87     signParam.signAlgo = signAlgo;
88     signParam.hashAlgo = hashAlgo;
89     signParam.data = data;
90     signParam.dataLen = dataLen;
91     signParam.sign = &signBuf[offset];
92     signParam.signLen = (uint16_t)(*signLen - offset);
93     /* Fill signature */
94     HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(ctx->config.tlsConfig.certMgrCtx, false);
95     int32_t ret = SAL_CERT_CreateSign(ctx, privateKey, &signParam);
96     BSL_SAL_FREE(data);
97     if ((ret != HITLS_SUCCESS) || (offset + signParam.signLen > *signLen)) {
98         BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
99         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15497, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
100             "create signature fail.", 0, 0, 0, 0);
101         return HITLS_PACK_SIGNATURE_ERR;
102     }
103     offset += signParam.signLen;
104     BSL_Uint16ToByte((uint16_t)signParam.signLen, &signBuf[signLenOffset]);
105     *signLen = offset;
106 
107     return HITLS_SUCCESS;
108 }
109 #endif /* HITLS_TLS_SUITE_KX_ECDHE || HITLS_TLS_SUITE_KX_DHE */
110 #ifdef HITLS_TLS_SUITE_KX_ECDHE
111 
GetNamedCurveMsgLen(TLS_Ctx * ctx,uint32_t pubKeyLen)112 static uint32_t GetNamedCurveMsgLen(TLS_Ctx *ctx, uint32_t pubKeyLen)
113 {
114     HITLS_Config *config = &(ctx->config.tlsConfig);
115 
116     /* Message length = Curve type (1 byte) + Curve ID (2 byte) + Public key length (1 byte) + Public key + Signature
117      * length (2 byte) + Signature */
118     uint32_t dataLen = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t) + pubKeyLen;
119 
120     /* ECDHE_PSK key exchange does not require signature */
121     if (IsNeedKeyExchParamSignature(ctx)) {
122         HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(config->certMgrCtx, false);
123         uint32_t signatureLen = SAL_CERT_GetSignMaxLen(config, privateKey);
124         if ((signatureLen == 0u) || (signatureLen > MAX_SIGN_SIZE)) {
125             BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
126             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15499, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
127                 "pack ske error: invalid signature length = %u.", signatureLen, 0, 0, 0);
128             return 0;
129         }
130 
131         dataLen += sizeof(uint16_t) + signatureLen;
132         /* A signature type needs to be added to TLS1.2/DTLS. The signature type does not need to be transferred */
133         if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS12 || ctx->negotiatedInfo.version == HITLS_VERSION_DTLS12) {
134             dataLen += sizeof(uint16_t);
135         }
136     }
137 
138     return dataLen;
139 }
140 
PackServerKxMsgNamedCurve(TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)141 static int32_t PackServerKxMsgNamedCurve(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
142 {
143     KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx;
144     HITLS_ECParameters *ecParam = &(kxCtx->keyExchParam.ecdh.curveParams);
145     uint32_t pubKeyLen = SAL_CRYPT_GetCryptLength(ctx, HITLS_CRYPT_INFO_CMD_GET_PUBLIC_KEY_LEN, ecParam->param.namedcurve);
146     if (pubKeyLen == 0u) {
147         BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH);
148         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15498, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
149             "pack ske error: unsupport named curve = %u.", ecParam->param.namedcurve, 0, 0, 0);
150         return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH;
151     }
152     uint32_t dataLen = GetNamedCurveMsgLen(ctx, pubKeyLen);
153     if (dataLen == 0) {
154         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16941, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
155             "GetNamedCurveMsgLen err", 0, 0, 0, 0);
156         return HITLS_PACK_SIGNATURE_ERR;
157     }
158 
159     /* If the length of bufLen does not meet the requirements, an error code is returned */
160     if (bufLen < dataLen) {
161         return PackBufLenError(BINLOG_ID15500, BINGLOG_STR("serverKeyexchange"));
162     }
163 
164     /* Curve type and curve ID. Although these parameters are ignored in the TLCP, they are
165      * filled in to ensure the uniform style. However, the client cannot depend on the value of this parameter */
166     buf[0] = (uint8_t)(ecParam->type);
167     uint32_t offset = sizeof(uint8_t);
168     BSL_Uint16ToByte((uint16_t)(ecParam->param.namedcurve), &buf[offset]);
169     offset += sizeof(uint16_t);
170 
171     /* Public key length and public key content */
172     uint32_t pubKeyLenOffset = offset;   // indicates the offset of pubkeyLen.
173     offset += sizeof(uint8_t);
174     uint32_t pubKeyUsedLen = 0;
175     int32_t ret = SAL_CRYPT_EncodeEcdhPubKey(kxCtx->key, &buf[offset], pubKeyLen, &pubKeyUsedLen);
176     if (ret != HITLS_SUCCESS || pubKeyLen != pubKeyUsedLen) {
177         BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_ECDH_KEY);
178         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15501, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
179             "encode ecdh key fail.", 0, 0, 0, 0);
180         return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY;
181     }
182     offset += pubKeyUsedLen;
183     buf[pubKeyLenOffset] = (uint8_t)pubKeyUsedLen;   // Fill pubkeyLen
184 
185     if (IsNeedKeyExchParamSignature(ctx)) {
186         uint32_t signatureLen = dataLen - offset;
187         ret = SignKeyExchParams(ctx, &buf[0], offset, &buf[offset], &signatureLen);
188         if (ret != HITLS_SUCCESS) {
189             BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
190             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15502, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
191                 "signature fail.", 0, 0, 0, 0);
192             return HITLS_PACK_SIGNATURE_ERR;
193         }
194         offset += signatureLen;
195     }
196 
197     *usedLen = offset;
198     return HITLS_SUCCESS;
199 }
200 
PackServerKxMsgEcdhe(TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)201 static int32_t PackServerKxMsgEcdhe(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
202 {
203     HITLS_ECCurveType type = ctx->hsCtx->kxCtx->keyExchParam.ecdh.curveParams.type;
204     switch (type) {
205         case HITLS_EC_CURVE_TYPE_NAMED_CURVE:
206             return PackServerKxMsgNamedCurve(ctx, buf, bufLen, usedLen);
207         default:
208             break;
209     }
210 
211     BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE);
212     BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15503, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
213         "unsupport key exchange curve type.", 0, 0, 0, 0);
214     return HITLS_PACK_UNSUPPORT_KX_CURVE_TYPE;
215 }
216 #endif /* HITLS_TLS_SUITE_KX_ECDHE */
217 #ifdef HITLS_TLS_PROTO_TLCP11
218 /* This function is invoked only by the TLCP */
PackServerKxMsgEcc(TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)219 static int32_t PackServerKxMsgEcc(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
220 {
221     uint8_t *data = NULL;
222     uint32_t offset = 0u;
223     uint32_t dataLen, certLen;
224 
225     uint8_t *encCert = SAL_CERT_SrvrGmEncodeEncCert(ctx, &certLen);
226     if (encCert == NULL) {
227         BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_ENCODE);
228         return RETURN_ERROR_NUMBER_PROCESS(HITLS_CERT_ERR_ENCODE, BINLOG_ID16942, "SAL_CERT_SrvrGmEncodeEncCert fail");
229     }
230     /* Obtain all signature data (random number + server kx content) */
231     data = HS_PrepareSignDataTlcp(ctx, encCert, certLen, &dataLen);
232     BSL_SAL_FREE(encCert);
233     if (data == NULL) {
234         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
235         return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID16219, "prepare unsigned data fail");
236     }
237 
238     HITLS_SignAlgo signAlgo;
239     HITLS_HashAlgo hashAlgo;
240     if (!CFG_GetSignParamBySchemes(ctx, ctx->negotiatedInfo.signScheme, &signAlgo, &hashAlgo)) {
241         BSL_SAL_FREE(data);
242         BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
243         return RETURN_ERROR_NUMBER_PROCESS(HITLS_PACK_SIGNATURE_ERR, BINLOG_ID16220, "get sign parm fail");
244     }
245     /* The hash and signature algorithms do not need to be explicitly specified in messages by TLCP. The hash algorithm
246      * obtained based on signScheme is used. */
247     uint32_t signLenOffset = offset; /* The records the position of the signature length in the message temporarily, and
248                                         then fills the signature length in the message later */
249     offset += sizeof(uint16_t);
250 
251     /* Fill signature parameters */
252     CERT_SignParam signParam = {0};
253     signParam.signAlgo = signAlgo;
254     signParam.hashAlgo = hashAlgo;
255     signParam.data = data;
256     signParam.dataLen = dataLen;
257     signParam.sign = &buf[offset];
258     signParam.signLen = (uint16_t)(bufLen - offset);
259     /* Fill the signature */
260     HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(ctx->config.tlsConfig.certMgrCtx, false);
261     int32_t ret = SAL_CERT_CreateSign(ctx, privateKey, &signParam);
262     if ((ret != HITLS_SUCCESS) || (offset + signParam.signLen > bufLen)) {
263         BSL_SAL_FREE(data);
264         BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
265         return RETURN_ERROR_NUMBER_PROCESS(HITLS_PACK_SIGNATURE_ERR, BINLOG_ID16221, "create sm2 signature fail");
266     }
267     offset += signParam.signLen;
268     BSL_Uint16ToByte((uint16_t)signParam.signLen, &buf[signLenOffset]);
269     *usedLen = offset;
270 
271     BSL_SAL_FREE(data);
272     return HITLS_SUCCESS;
273 }
274 #endif /* HITLS_TLS_PROTO_TLCP11 */
275 
276 #ifdef HITLS_TLS_SUITE_KX_DHE
PackKxPrimaryData(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)277 static int32_t PackKxPrimaryData(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
278 {
279     KeyExchCtx *kxCtx = ctx->hsCtx->kxCtx;
280     DhParam *dh = &ctx->hsCtx->kxCtx->keyExchParam.dh;
281     uint32_t pubkeyLen = dh->plen;
282     uint16_t plen = dh->plen;
283     uint16_t glen = dh->glen;
284     uint32_t bufOffset = 0;
285     BSL_Uint16ToByte(plen, &buf[bufOffset]);
286     bufOffset += sizeof(uint16_t);
287 
288     int32_t ret;
289     if (bufLen - bufOffset < plen) {
290         return PackBufLenError(BINLOG_ID15504, BINGLOG_STR("param p"));
291     }
292     (void)memcpy_s(&buf[bufOffset], bufLen - bufOffset, dh->p, plen);
293     bufOffset += plen;
294 
295     BSL_Uint16ToByte(glen, &buf[bufOffset]);
296     bufOffset += sizeof(uint16_t);
297 
298     if (bufLen - bufOffset < glen) {
299         return PackBufLenError(BINLOG_ID15505, BINGLOG_STR("param g"));
300     }
301     (void)memcpy_s(&buf[bufOffset], bufLen - bufOffset, dh->g, glen);
302     bufOffset += glen;
303 
304     uint32_t pubKeyLenOffset = bufOffset;   // indicates the offset of pubkeyLen
305     bufOffset += sizeof(uint16_t);
306 
307     ret = SAL_CRYPT_EncodeDhPubKey(kxCtx->key, &buf[bufOffset], pubkeyLen, &pubkeyLen);
308     if (ret != HITLS_SUCCESS) {
309         BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_ENCODE_DH_KEY);
310         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15506, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
311             "encode dhe key fail.", 0, 0, 0, 0);
312         return HITLS_CRYPT_ERR_ENCODE_DH_KEY;
313     }
314     bufOffset += pubkeyLen;
315     BSL_Uint16ToByte((uint16_t)pubkeyLen, &buf[pubKeyLenOffset]);
316 
317     *usedLen = bufOffset;
318     return HITLS_SUCCESS;
319 }
320 
PackServerKxMsgDhePre(TLS_Ctx * ctx,uint32_t * signatureLen)321 static int32_t PackServerKxMsgDhePre(TLS_Ctx *ctx, uint32_t *signatureLen)
322 {
323     if (IsNeedKeyExchParamSignature(ctx)) {
324         HITLS_CERT_Key *privateKey = SAL_CERT_GetCurrentPrivateKey(ctx->config.tlsConfig.certMgrCtx, false);
325         *signatureLen = SAL_CERT_GetSignMaxLen(&(ctx->config.tlsConfig), privateKey);
326         if ((*signatureLen == 0u) || (*signatureLen > MAX_SIGN_SIZE)) {
327             BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
328             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15508, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
329                 "invalid signature length.", 0, 0, 0, 0);
330             return HITLS_PACK_SIGNATURE_ERR;
331         }
332     }
333     return HITLS_SUCCESS;
334 }
335 
PackServerKxMsgDhe(TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)336 static int32_t PackServerKxMsgDhe(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
337 {
338     DhParam *dh = &ctx->hsCtx->kxCtx->keyExchParam.dh;
339     uint32_t pubkeyLen = dh->plen;
340     uint16_t plen = dh->plen;
341     uint16_t glen = dh->glen;
342 
343     if (pubkeyLen == 0u) {
344         BSL_ERR_PUSH_ERROR(HITLS_PACK_INVALID_KX_PUBKEY_LENGTH);
345         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15507, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
346             "invalid key exchange pubKey length.", 0, 0, 0, 0);
347         return HITLS_PACK_INVALID_KX_PUBKEY_LENGTH;
348     }
349 
350     /* DHE_PSK and ANON_DH do not need signatures */
351     uint32_t signatureLen = 0;
352     int32_t ret = PackServerKxMsgDhePre(ctx, &signatureLen);
353     if (ret != HITLS_SUCCESS) {
354         return ret;
355     }
356 
357     uint32_t dataLen = sizeof(uint16_t) + plen + sizeof(uint16_t) + glen + sizeof(uint16_t) + pubkeyLen;
358     if (IsNeedKeyExchParamSignature(ctx)) {
359         dataLen += (sizeof(uint16_t) + signatureLen);
360     }
361 #if defined(HITLS_TLS_PROTO_TLS12) || defined(HITLS_TLS_PROTO_DTLS12)
362     if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS12 || ctx->negotiatedInfo.version == HITLS_VERSION_DTLS12) {
363         dataLen += sizeof(uint16_t);   // TLS1.2/DTLS needs to add a signature type
364     }
365 #endif /* HITLS_TLS_PROTO_TLS12 || HITLS_TLS_PROTO_DTLS12 */
366     if (bufLen < dataLen) {
367         return PackBufLenError(BINLOG_ID15509, BINGLOG_STR("serverKeyexchange"));
368     }
369 
370     /* Fill the following values in sequence: plen, p, glen, g, pubkeylen, pubkey, signature len, and signature */
371     uint32_t offset = 0u;
372     ret = PackKxPrimaryData(ctx, buf, bufLen, &offset);
373     if (ret != HITLS_SUCCESS) {
374         return ret;
375     }
376 
377     if (IsNeedKeyExchParamSignature(ctx)) {
378         uint32_t signLen = dataLen - offset;
379         ret = SignKeyExchParams(ctx, &buf[0], offset, &buf[offset], &signLen);
380         if (ret != HITLS_SUCCESS) {
381             BSL_ERR_PUSH_ERROR(HITLS_PACK_SIGNATURE_ERR);
382             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15510, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
383                 "kx msg signature fail. ret %d", ret, 0, 0, 0);
384             return HITLS_PACK_SIGNATURE_ERR;
385         }
386         offset += signLen;
387     }
388 
389     *usedLen = offset;
390     return HITLS_SUCCESS;
391 }
392 #endif /* HITLS_TLS_SUITE_KX_DHE */
393 #ifdef HITLS_TLS_FEATURE_PSK
PackServerKxMsgPskIdentityHint(const TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)394 static int32_t PackServerKxMsgPskIdentityHint(const TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
395 {
396     uint8_t *pskIdentityHint = ctx->config.tlsConfig.pskIdentityHint;
397     /* The length of hintSize <= HITLS_IDENTITY_HINT_MAX_SIZE is ensured during configuration. Therefore, the length of
398      * uint16_t can be forcibly converted to the length of uint16_t */
399     uint16_t pskIdentityHintSize = (uint16_t)ctx->config.tlsConfig.hintSize;
400     uint32_t dataLen;
401 
402     dataLen = sizeof(uint16_t) + pskIdentityHintSize;
403 
404     if (bufLen < dataLen) {
405         return PackBufLenError(BINLOG_ID15511, BINGLOG_STR("serverKeyexchange"));
406     }
407 
408     /* append identity hint */
409     /* for dhe_psk, ecdhe_psk, msg must contain the length of hint even if there is no hint to provide */
410     uint32_t offset = 0u;
411     BSL_Uint16ToByte(pskIdentityHintSize, &buf[offset]);
412     offset += sizeof(uint16_t);
413 
414     if (pskIdentityHint != NULL) {
415         if (bufLen - offset < pskIdentityHintSize) {
416             return PackBufLenError(BINLOG_ID15512, BINGLOG_STR("psk identity hint"));
417         }
418         (void)memcpy_s(&buf[offset], bufLen - offset, pskIdentityHint, pskIdentityHintSize);
419         offset += pskIdentityHintSize;
420     }
421 
422     *usedLen = offset;
423     return HITLS_SUCCESS;
424 }
425 #endif /* HITLS_TLS_FEATURE_PSK */
426 // Pack the ServerKeyExchange message.
PackServerKeyExchange(TLS_Ctx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * usedLen)427 int32_t PackServerKeyExchange(TLS_Ctx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
428 {
429     int32_t ret = HITLS_SUCCESS;
430     uint32_t len = 0u;
431     uint32_t offset = 0u;
432     (void)buf;
433     (void)bufLen;
434 #ifdef HITLS_TLS_FEATURE_PSK
435     /* pack psk identity hint before dynamic key */
436     if (IsPskNegotiation(ctx)) {
437         ret = PackServerKxMsgPskIdentityHint(ctx, buf, bufLen, &len);
438         if (ret != HITLS_SUCCESS) {
439             // log here
440             return ret;
441         }
442         offset += len;
443     }
444 #endif /* HITLS_TLS_FEATURE_PSK */
445     /* Pack a key exchange message */
446     len = 0u;
447     switch (ctx->negotiatedInfo.cipherSuiteInfo.kxAlg) {
448 #ifdef HITLS_TLS_SUITE_KX_ECDHE
449         case HITLS_KEY_EXCH_ECDHE:
450         case HITLS_KEY_EXCH_ECDHE_PSK:
451             ret = PackServerKxMsgEcdhe(ctx, &buf[offset], bufLen - offset, &len);
452             break;
453 #endif
454 #ifdef HITLS_TLS_SUITE_KX_DHE
455         case HITLS_KEY_EXCH_DHE:
456         case HITLS_KEY_EXCH_DHE_PSK:
457             ret = PackServerKxMsgDhe(ctx, &buf[offset], bufLen - offset, &len);
458             break;
459 #endif /* HITLS_TLS_SUITE_KX_DHE */
460 #ifdef HITLS_TLS_SUITE_KX_RSA
461         case HITLS_KEY_EXCH_RSA_PSK:
462         case HITLS_KEY_EXCH_PSK:
463             /* for psk and rsa_psk nego, ServerKeyExchange msg contains only identity hint */
464             ret = HITLS_SUCCESS;
465             break;
466 #endif /* HITLS_TLS_SUITE_KX_RSA */
467 #ifdef HITLS_TLS_PROTO_TLCP11
468         case HITLS_KEY_EXCH_ECC:
469             ret = PackServerKxMsgEcc(ctx, &buf[offset], bufLen - offset, &len);
470             break;
471 #endif
472         default:
473             BSL_ERR_PUSH_ERROR(HITLS_PACK_UNSUPPORT_KX_ALG);
474             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15513, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
475                 "unsupport key exchange algorithm when pack server key exchange msg.", 0, 0, 0, 0);
476             return HITLS_PACK_UNSUPPORT_KX_ALG;
477     }
478 
479     offset += len;
480     *usedLen = offset;
481     return ret;
482 }
483 #endif /* HITLS_TLS_PROTO_TLS_BASIC || HITLS_TLS_PROTO_DTLS12 */
484 #endif /* HITLS_TLS_HOST_SERVER */