* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <stddef.h>
#include <string.h>
#include "hitls_build.h"
#include "config_type.h"
#include "hitls_crypt_type.h"
#include "tls_config.h"
#include "hitls_error.h"
#include "crypt_algid.h"
#include "config.h"
#ifdef HITLS_TLS_FEATURE_PROVIDER_DYNAMIC
#include "crypt_eal_provider.h"
#include "crypt_params_key.h"
#include "crypt_eal_implprovider.h"
#include "crypt_eal_pkey.h"
#endif
#ifdef HITLS_TLS_CONFIG_CIPHER_SUITE
static const char DEFAULT_GROUP_ID[] =
"?*X25519MLKEM768/?*x25519:?secp256r1:?secp384r1:?secp521r1"
#if defined(HITLS_TLS_PROTO_TLCP11) || defined(HITLS_TLS_FEATURE_SM_TLS13)
":?sm2"
#endif
"/?ffdhe2048:?ffdhe3072:?ffdhe4096:?ffdhe6144:?ffdhe8192";
#else
static const uint16_t DEFAULT_GROUP_ID[] = {
HITLS_HYBRID_X25519_MLKEM768,
HITLS_EC_GROUP_CURVE25519,
HITLS_EC_GROUP_SECP256R1,
HITLS_EC_GROUP_SECP384R1,
HITLS_EC_GROUP_SECP521R1,
#if defined(HITLS_TLS_PROTO_TLCP11) || defined(HITLS_TLS_FEATURE_SM_TLS13)
HITLS_EC_GROUP_SM2,
#endif
HITLS_FF_DHE_2048,
HITLS_FF_DHE_3072,
HITLS_FF_DHE_4096,
HITLS_FF_DHE_6144,
HITLS_FF_DHE_8192,
};
#endif
#ifndef HITLS_TLS_FEATURE_PROVIDER_DYNAMIC
#ifndef HITLS_TLS_CAP_NO_STR
#define CONST_CAST(str) ((char *)(uintptr_t)(str))
#else
#define CONST_CAST(str) NULL
#endif
static const TLS_GroupInfo GROUP_INFO[] = {
{
CONST_CAST("x25519"),
CRYPT_PKEY_PARAID_MAX,
CRYPT_PKEY_X25519,
128,
HITLS_EC_GROUP_CURVE25519,
32, 32, 0,
TLS_VERSION_MASK | DTLS_VERSION_MASK,
false,
},
#ifdef HITLS_TLS_FEATURE_KEM
#ifdef HITLS_TLS_PROTO_TLS13
{
CONST_CAST("X25519MLKEM768"),
CRYPT_HYBRID_X25519_MLKEM768,
CRYPT_PKEY_HYBRID_KEM,
192,
HITLS_HYBRID_X25519_MLKEM768,
1184 + 32, 32 + 32, 1088 + 32,
TLS13_VERSION_BIT,
true,
},
{
CONST_CAST("SecP256r1MLKEM768"),
CRYPT_HYBRID_ECDH_NISTP256_MLKEM768,
CRYPT_PKEY_HYBRID_KEM,
192,
HITLS_HYBRID_ECDH_NISTP256_MLKEM768,
1184 + 65, 32 + 32, 1088 + 65,
TLS13_VERSION_BIT,
true,
},
{
CONST_CAST("SecP384r1MLKEM1024"),
CRYPT_HYBRID_ECDH_NISTP384_MLKEM1024,
CRYPT_PKEY_HYBRID_KEM,
256,
HITLS_HYBRID_ECDH_NISTP384_MLKEM1024,
1568 + 97, 32 + 48, 1568 + 97,
TLS13_VERSION_BIT,
true,
},
#endif
#endif
#ifdef HITLS_CRYPTO_CURVE_NISTP256
{
CONST_CAST("secp256r1"),
CRYPT_ECC_NISTP256,
CRYPT_PKEY_ECDH,
128,
HITLS_EC_GROUP_SECP256R1,
65, 32, 0,
TLS_VERSION_MASK | DTLS_VERSION_MASK,
false,
},
#endif
#ifdef HITLS_CRYPTO_CURVE_NISTP384
{
CONST_CAST("secp384r1"),
CRYPT_ECC_NISTP384,
CRYPT_PKEY_ECDH,
192,
HITLS_EC_GROUP_SECP384R1,
97, 48, 0,
TLS_VERSION_MASK | DTLS_VERSION_MASK,
false,
},
#endif
#ifdef HITLS_CRYPTO_CURVE_NISTP521
{
CONST_CAST("secp521r1"),
CRYPT_ECC_NISTP521,
CRYPT_PKEY_ECDH,
256,
HITLS_EC_GROUP_SECP521R1,
133, 66, 0,
TLS_VERSION_MASK | DTLS_VERSION_MASK,
false,
},
#endif
#ifdef HITLS_CRYPTO_CURVE_BP256R1
{
CONST_CAST("brainpoolP256r1"),
CRYPT_ECC_BRAINPOOLP256R1,
CRYPT_PKEY_ECDH,
128,
HITLS_EC_GROUP_BRAINPOOLP256R1,
65, 32, 0,
TLS10_VERSION_BIT | TLS11_VERSION_BIT | TLS12_VERSION_BIT | DTLS_VERSION_MASK,
false,
},
#endif
#ifdef HITLS_CRYPTO_CURVE_BP384R1
{
CONST_CAST("brainpoolP384r1"),
CRYPT_ECC_BRAINPOOLP384R1,
CRYPT_PKEY_ECDH,
192,
HITLS_EC_GROUP_BRAINPOOLP384R1,
97, 48, 0,
TLS10_VERSION_BIT | TLS11_VERSION_BIT | TLS12_VERSION_BIT | DTLS_VERSION_MASK,
false,
},
#endif
#ifdef HITLS_CRYPTO_CURVE_BP512R1
{
CONST_CAST("brainpoolP512r1"),
CRYPT_ECC_BRAINPOOLP512R1,
CRYPT_PKEY_ECDH,
256,
HITLS_EC_GROUP_BRAINPOOLP512R1,
129, 64, 0,
TLS10_VERSION_BIT | TLS11_VERSION_BIT | TLS12_VERSION_BIT | DTLS_VERSION_MASK,
false,
},
#endif
#ifdef HITLS_TLS_FEATURE_SM_TLS13
{
"curveSm2",
CRYPT_ECC_SM2,
CRYPT_PKEY_ECDH,
128,
HITLS_EC_GROUP_SM2,
65, 32, 0,
TLS13_VERSION_BIT,
false,
},
#endif
#ifdef HITLS_TLS_PROTO_TLCP11
{
CONST_CAST("sm2"),
CRYPT_PKEY_PARAID_MAX,
CRYPT_PKEY_SM2,
128,
HITLS_EC_GROUP_SM2,
65, 48, 0,
TLCP11_VERSION_BIT | DTLCP11_VERSION_BIT,
false,
},
#endif
#ifdef HITLS_CRYPTO_DH
{
CONST_CAST("ffdhe8192"),
CRYPT_DH_RFC7919_8192,
CRYPT_PKEY_DH,
192,
HITLS_FF_DHE_8192,
1024, 1024, 0,
TLS13_VERSION_BIT,
false,
},
{
CONST_CAST("ffdhe6144"),
CRYPT_DH_RFC7919_6144,
CRYPT_PKEY_DH,
128,
HITLS_FF_DHE_6144,
768, 768, 0,
TLS13_VERSION_BIT,
false,
},
{
CONST_CAST("ffdhe4096"),
CRYPT_DH_RFC7919_4096,
CRYPT_PKEY_DH,
128,
HITLS_FF_DHE_4096,
512, 512, 0,
TLS13_VERSION_BIT,
false,
},
{
CONST_CAST("ffdhe3072"),
CRYPT_DH_RFC7919_3072,
CRYPT_PKEY_DH,
128,
HITLS_FF_DHE_3072,
384, 384, 0,
TLS13_VERSION_BIT,
false,
},
{
CONST_CAST("ffdhe2048"),
CRYPT_DH_RFC7919_2048,
CRYPT_PKEY_DH,
112,
HITLS_FF_DHE_2048,
256, 256, 0,
TLS13_VERSION_BIT,
false,
}
#endif
};
int32_t ConfigLoadGroupInfo(HITLS_Config *config)
{
if (config == NULL) {
return HITLS_INVALID_INPUT;
}
#ifdef HITLS_TLS_CONFIG_CIPHER_SUITE
return HITLS_CFG_SetGroupList(config, DEFAULT_GROUP_ID, (uint32_t)strlen(DEFAULT_GROUP_ID));
#else
return HITLS_CFG_SetGroups(config, DEFAULT_GROUP_ID, sizeof(DEFAULT_GROUP_ID) / sizeof(DEFAULT_GROUP_ID[0]));
#endif
}
const TLS_GroupInfo *ConfigGetGroupInfo(const HITLS_Config *config, uint16_t groupId)
{
for (uint32_t i = 0; i < sizeof(GROUP_INFO) / sizeof(TLS_GroupInfo); i++) {
if (GROUP_INFO[i].groupId == groupId) {
if (config != NULL && (config->version & GROUP_INFO[i].versionBits) == 0) {
continue;
}
return &GROUP_INFO[i];
}
}
return NULL;
}
const TLS_GroupInfo *ConfigGetGroupInfoList(const HITLS_Config *config, uint32_t *size)
{
(void)config;
*size = sizeof(GROUP_INFO) / sizeof(GROUP_INFO[0]);
return &GROUP_INFO[0];
}
#else
static int32_t ProviderAddGroupInfo(const BSL_Param *params, void *args)
{
if (params == NULL || args == NULL) {
return HITLS_INVALID_INPUT;
}
TLS_CapabilityData *data = (TLS_CapabilityData *)args;
TLS_Config *config = data->config;
TLS_GroupInfo *group = NULL;
CRYPT_EAL_PkeyCtx *pkey = NULL;
BSL_Param *param = NULL;
int32_t ret = HITLS_CONFIG_ERR_LOAD_GROUP_INFO;
if (config->groupInfolen == config->groupInfoSize) {
void *ptr = BSL_SAL_Realloc(config->groupInfo,
(config->groupInfoSize + TLS_CAPABILITY_LIST_MALLOC_SIZE) * sizeof(TLS_GroupInfo),
config->groupInfoSize * sizeof(TLS_GroupInfo));
if (ptr == NULL) {
return HITLS_MEMALLOC_FAIL;
}
config->groupInfo = ptr;
memset(config->groupInfo + config->groupInfoSize, 0, TLS_CAPABILITY_LIST_MALLOC_SIZE * sizeof(TLS_GroupInfo));
config->groupInfoSize += TLS_CAPABILITY_LIST_MALLOC_SIZE;
}
group = config->groupInfo + config->groupInfolen;
#ifndef HITLS_TLS_CAP_NO_STR
PROCESS_STRING_PARAM(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_IANA_GROUP_NAME, name);
#endif
PROCESS_PARAM_UINT16(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_IANA_GROUP_ID, groupId);
PROCESS_PARAM_INT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_PARA_ID, paraId);
PROCESS_PARAM_INT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_ALG_ID, algId);
PROCESS_PARAM_INT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_SEC_BITS, secBits);
PROCESS_PARAM_UINT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_VERSION_BITS, versionBits);
PROCESS_PARAM_BOOL(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_IS_KEM, isKem);
PROCESS_PARAM_INT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_PUBKEY_LEN, pubkeyLen);
PROCESS_PARAM_INT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_SHAREDKEY_LEN, sharedkeyLen);
PROCESS_PARAM_INT32(param, group, params, CRYPT_PARAM_CAP_TLS_GROUP_CIPHERTEXT_LEN, ciphertextLen);
ret = HITLS_SUCCESS;
pkey = CRYPT_EAL_ProviderPkeyNewCtx(LIBCTX_FROM_CONFIG(config),
group->algId,
group->isKem ? CRYPT_EAL_PKEY_KEM_OPERATE : CRYPT_EAL_PKEY_EXCH_OPERATE,
ATTRIBUTE_FROM_CONFIG(config));
if (pkey != NULL) {
config->groupInfolen++;
CRYPT_EAL_PkeyFreeCtx(pkey);
group = NULL;
}
ERR:
if (group != NULL) {
BSL_SAL_Free(group->name);
memset(group, 0, sizeof(TLS_GroupInfo));
}
return ret;
}
static int32_t ProviderLoadGroupInfo(CRYPT_EAL_ProvMgrCtx *ctx, void *args)
{
if (ctx == NULL || args == NULL) {
return HITLS_INVALID_INPUT;
}
TLS_CapabilityData data = {
.config = (TLS_Config *)args,
.provMgrCtx = ctx,
};
return CRYPT_EAL_ProviderGetCaps(ctx, CRYPT_EAL_GET_GROUP_CAP, ProviderAddGroupInfo, &data);
}
int32_t ConfigLoadGroupInfo(HITLS_Config *config)
{
HITLS_Lib_Ctx *libCtx = LIBCTX_FROM_CONFIG(config);
int32_t ret = CRYPT_EAL_ProviderProcessAll(libCtx, ProviderLoadGroupInfo, config);
if (ret != HITLS_SUCCESS) {
return ret;
}
#ifdef HITLS_TLS_CONFIG_CIPHER_SUITE
return HITLS_CFG_SetGroupList(config, DEFAULT_GROUP_ID, (uint32_t)strlen(DEFAULT_GROUP_ID));
#else
return HITLS_CFG_SetGroups(config, DEFAULT_GROUP_ID, sizeof(DEFAULT_GROUP_ID) / sizeof(DEFAULT_GROUP_ID[0]));
#endif
}
const TLS_GroupInfo *ConfigGetGroupInfo(const HITLS_Config *config, uint16_t groupId)
{
for (uint32_t i = 0; i < config->groupInfolen; i++) {
if (config->groupInfo[i].groupId == groupId && (config->version & config->groupInfo[i].versionBits) != 0) {
return &config->groupInfo[i];
}
}
return NULL;
}
const TLS_GroupInfo *ConfigGetGroupInfoList(const HITLS_Config *config, uint32_t *size)
{
*size = config->groupInfolen;
return config->groupInfo;
}
#endif