* 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 "tls_binlog_id.h"
#include "bsl_log_internal.h"
#include "bsl_log.h"
#include "bsl_err_internal.h"
#include "bsl_bytes.h"
#include "bsl_sal.h"
#include "hitls_error.h"
#include "hitls_crypt_reg.h"
#include "crypt.h"
#include "config_type.h"
#ifdef HITLS_TLS_FEATURE_PROVIDER
#include "hitls_crypt.h"
#endif
#ifndef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_BaseMethod g_cryptBaseMethod = {0};
HITLS_CRYPT_EcdhMethod g_cryptEcdhMethod = {0};
HITLS_CRYPT_DhMethod g_cryptDhMethod = {0};
#endif
#ifdef HITLS_TLS_PROTO_TLS13
#ifndef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_KdfMethod g_cryptKdfMethod = {0};
#endif
#endif
#ifdef HITLS_TLS_PROTO_TLS13
#define TLS13_MAX_LABEL_LEN 255
#define TLS13_MAX_CTX_LEN 255
#define TLS13_HKDF_LABEL_LEN(labelLen, ctxLen) \
(sizeof(uint16_t) + sizeof(uint8_t) + (labelLen) + sizeof(uint8_t) + (ctxLen))
#define TLS13_MAX_HKDF_LABEL_LEN TLS13_HKDF_LABEL_LEN(TLS13_MAX_LABEL_LEN, TLS13_MAX_CTX_LEN)
typedef struct {
uint16_t length;
uint8_t labelLen;
uint8_t ctxLen;
const uint8_t *label;
const uint8_t *ctx;
} HkdfLabel;
#endif
const char *g_cryptCallBackStr[] = {
[HITLS_CRYPT_CALLBACK_RAND_BYTES] = "random bytes",
[HITLS_CRYPT_CALLBACK_HMAC_SIZE] = "hmac size",
[HITLS_CRYPT_CALLBACK_HMAC_INIT] = "hmac init",
[HITLS_CRYPT_CALLBACK_HMAC_FREE] = "hmac free",
[HITLS_CRYPT_CALLBACK_HMAC_UPDATE] = "hmac update",
[HITLS_CRYPT_CALLBACK_HMAC_FINAL] = "hmac final",
[HITLS_CRYPT_CALLBACK_HMAC] = "hmac calc",
[HITLS_CRYPT_CALLBACK_DIGEST_SIZE] = "digest size",
[HITLS_CRYPT_CALLBACK_DIGEST_INIT] = "digest init",
[HITLS_CRYPT_CALLBACK_DIGEST_COPY] = "digest copy",
[HITLS_CRYPT_CALLBACK_DIGEST_FREE] = "digest free",
[HITLS_CRYPT_CALLBACK_DIGEST_UPDATE] = "digest update",
[HITLS_CRYPT_CALLBACK_DIGEST_FINAL] = "digest final",
[HITLS_CRYPT_CALLBACK_DIGEST] = "digest calc",
[HITLS_CRYPT_CALLBACK_ENCRYPT] = "encrypt",
[HITLS_CRYPT_CALLBACK_DECRYPT] = "decrpt",
[HITLS_CRYPT_CALLBACK_GENERATE_ECDH_KEY_PAIR] = "generate ecdh key",
[HITLS_CRYPT_CALLBACK_FREE_ECDH_KEY] = "free ecdh key",
[HITLS_CRYPT_CALLBACK_GET_ECDH_ENCODED_PUBKEY] = "get ecdh public key",
[HITLS_CRYPT_CALLBACK_CALC_ECDH_SHARED_SECRET] = "calculate ecdh shared secret",
[HITLS_CRYPT_CALLBACK_SM2_CALC_ECDH_SHARED_SECRET] = "calculate sm2 ecdh shared secret",
[HITLS_CRYPT_CALLBACK_GENERATE_DH_KEY_BY_SECBITS] = "generate Dh key by secbits",
[HITLS_CRYPT_CALLBACK_GENERATE_DH_KEY_BY_PARAMS] = "generate Dh key by params",
[HITLS_CRYPT_CALLBACK_DUP_DH_KEY] = "dup Dh key",
[HITLS_CRYPT_CALLBACK_FREE_DH_KEY] = "free Dh key",
[HITLS_CRYPT_CALLBACK_DH_GET_PARAMETERS] = "get dh params",
[HITLS_CRYPT_CALLBACK_GET_DH_ENCODED_PUBKEY] = "get dh public key",
[HITLS_CRYPT_CALLBACK_CALC_DH_SHARED_SECRET] = "calculate dh shared secret",
[HITLS_CRYPT_CALLBACK_HKDF_EXTRACT] = "HKDF-Extract",
[HITLS_CRYPT_CALLBACK_HKDF_EXPAND] = "HKDF-Expand",
[HITLS_CRYPT_CALLBACK_KEM_ENCAPSULATE] = "KEM-Encapsulate",
[HITLS_CRYPT_CALLBACK_KEM_DECAPSULATE] = "KEM-Decapsulate",
};
#ifndef HITLS_TLS_FEATURE_PROVIDER
int32_t HITLS_CRYPT_RegisterBaseMethod(HITLS_CRYPT_BaseMethod *userCryptCallBack)
{
if (userCryptCallBack == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15063, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Register base crypt method error: input NULL.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
return HITLS_NULL_INPUT;
}
if (userCryptCallBack->randBytes != NULL) {
g_cryptBaseMethod.randBytes = userCryptCallBack->randBytes;
}
if (userCryptCallBack->hmacSize != NULL) {
g_cryptBaseMethod.hmacSize = userCryptCallBack->hmacSize;
}
if (userCryptCallBack->hmacInit != NULL) {
g_cryptBaseMethod.hmacInit = userCryptCallBack->hmacInit;
}
if (userCryptCallBack->hmacReinit != NULL) {
g_cryptBaseMethod.hmacReinit = userCryptCallBack->hmacReinit;
}
if (userCryptCallBack->hmacFree != NULL) {
g_cryptBaseMethod.hmacFree = userCryptCallBack->hmacFree;
}
if (userCryptCallBack->hmacUpdate != NULL) {
g_cryptBaseMethod.hmacUpdate = userCryptCallBack->hmacUpdate;
}
if (userCryptCallBack->hmacFinal != NULL) {
g_cryptBaseMethod.hmacFinal = userCryptCallBack->hmacFinal;
}
if (userCryptCallBack->hmac != NULL) {
g_cryptBaseMethod.hmac = userCryptCallBack->hmac;
}
if (userCryptCallBack->digestSize != NULL) {
g_cryptBaseMethod.digestSize = userCryptCallBack->digestSize;
}
if (userCryptCallBack->digestInit != NULL) {
g_cryptBaseMethod.digestInit = userCryptCallBack->digestInit;
}
if (userCryptCallBack->digestCopy != NULL) {
g_cryptBaseMethod.digestCopy = userCryptCallBack->digestCopy;
}
if (userCryptCallBack->digestFree != NULL) {
g_cryptBaseMethod.digestFree = userCryptCallBack->digestFree;
}
if (userCryptCallBack->digestUpdate != NULL) {
g_cryptBaseMethod.digestUpdate = userCryptCallBack->digestUpdate;
}
if (userCryptCallBack->digestFinal != NULL) {
g_cryptBaseMethod.digestFinal = userCryptCallBack->digestFinal;
}
if (userCryptCallBack->digest != NULL) {
g_cryptBaseMethod.digest = userCryptCallBack->digest;
}
if (userCryptCallBack->encrypt != NULL) {
g_cryptBaseMethod.encrypt = userCryptCallBack->encrypt;
}
if (userCryptCallBack->decrypt != NULL) {
g_cryptBaseMethod.decrypt = userCryptCallBack->decrypt;
}
if (userCryptCallBack->cipherFree != NULL) {
g_cryptBaseMethod.cipherFree = userCryptCallBack->cipherFree;
}
return HITLS_SUCCESS;
}
int32_t HITLS_CRYPT_RegisterEcdhMethod(HITLS_CRYPT_EcdhMethod *userCryptCallBack)
{
if (userCryptCallBack == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15064, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Register ECDH crypt method error: input NULL.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
return HITLS_NULL_INPUT;
}
g_cryptEcdhMethod.generateEcdhKeyPair = userCryptCallBack->generateEcdhKeyPair;
g_cryptEcdhMethod.freeEcdhKey = userCryptCallBack->freeEcdhKey;
g_cryptEcdhMethod.getEcdhPubKey = userCryptCallBack->getEcdhPubKey;
g_cryptEcdhMethod.calcEcdhSharedSecret = userCryptCallBack->calcEcdhSharedSecret;
#ifdef HITLS_TLS_PROTO_TLCP11
g_cryptEcdhMethod.sm2CalEcdhSharedSecret = userCryptCallBack->sm2CalEcdhSharedSecret;
#endif
g_cryptEcdhMethod.kemEncapsulate = userCryptCallBack->kemEncapsulate;
g_cryptEcdhMethod.kemDecapsulate = userCryptCallBack->kemDecapsulate;
return HITLS_SUCCESS;
}
int32_t HITLS_CRYPT_RegisterDhMethod(const HITLS_CRYPT_DhMethod *userCryptCallBack)
{
if (userCryptCallBack == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Register Dh crypt method error: input NULL.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
return HITLS_NULL_INPUT;
}
g_cryptDhMethod.getDhParameters = userCryptCallBack->getDhParameters;
g_cryptDhMethod.generateDhKeyBySecbits = userCryptCallBack->generateDhKeyBySecbits;
g_cryptDhMethod.generateDhKeyByParams = userCryptCallBack->generateDhKeyByParams;
g_cryptDhMethod.freeDhKey = userCryptCallBack->freeDhKey;
g_cryptDhMethod.getDhPubKey = userCryptCallBack->getDhPubKey;
g_cryptDhMethod.calcDhSharedSecret = userCryptCallBack->calcDhSharedSecret;
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
g_cryptDhMethod.dupDhKey = userCryptCallBack->dupDhKey;
#endif
return HITLS_SUCCESS;
}
#ifdef HITLS_TLS_PROTO_TLS13
int32_t HITLS_CRYPT_RegisterHkdfMethod(HITLS_CRYPT_KdfMethod *userCryptCallBack)
{
if (userCryptCallBack == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15066, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Register HKDF crypt method error: input NULL.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
return HITLS_NULL_INPUT;
}
g_cryptKdfMethod.hkdfExtract = userCryptCallBack->hkdfExtract;
g_cryptKdfMethod.hkdfExpand = userCryptCallBack->hkdfExpand;
return HITLS_SUCCESS;
}
#endif
#endif
int32_t CheckCallBackRetVal(int32_t cmd, int32_t callBackRet, uint32_t bingLogId, uint32_t hitlsRet)
{
(void)cmd;
(void)bingLogId;
if (callBackRet != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(bingLogId, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"%s error: callback ret = 0x%x.", g_cryptCallBackStr[cmd], callBackRet, 0, 0);
BSL_ERR_PUSH_ERROR((int32_t)hitlsRet);
return (int32_t)hitlsRet;
}
return HITLS_SUCCESS;
}
int32_t SAL_CRYPT_Rand(HITLS_Lib_Ctx *libCtx, uint8_t *buf, uint32_t len)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_RandbytesEx(libCtx, buf, len);
#else
(void)libCtx;
if (g_cryptBaseMethod.randBytes == NULL) {
return HITLS_CRYPT_ERR_GENERATE_RANDOM;
}
int32_t ret = g_cryptBaseMethod.randBytes(buf, len);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_RAND_BYTES, ret, BINLOG_ID15068,
HITLS_CRYPT_ERR_GENERATE_RANDOM);
}
uint32_t SAL_CRYPT_HmacSize(HITLS_HashAlgo hashAlgo)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_DigestSize(hashAlgo);
#else
if (g_cryptBaseMethod.hmacSize == NULL) {
return 0;
}
return g_cryptBaseMethod.hmacSize(hashAlgo);
#endif
}
#ifdef HITLS_TLS_CALLBACK_CRYPT_HMAC_PRIMITIVES
HITLS_HMAC_Ctx *SAL_CRYPT_HmacInit(HITLS_Lib_Ctx *libCtx, const char *attrName,
HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t len)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_HMAC_Init(libCtx, attrName, hashAlgo, key, len);
#else
(void)libCtx;
(void)attrName;
if (g_cryptBaseMethod.hmacInit == NULL) {
return NULL;
}
return g_cryptBaseMethod.hmacInit(hashAlgo, key, len);
#endif
}
void SAL_CRYPT_HmacFree(HITLS_HMAC_Ctx *hmac)
{
if (hmac != NULL) {
#ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_HMAC_Free(hmac);
#else
if (g_cryptBaseMethod.hmacFree == NULL) {
return;
}
g_cryptBaseMethod.hmacFree(hmac);
#endif
}
return;
}
int32_t SAL_CRYPT_HmacReInit(HITLS_HMAC_Ctx *ctx)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_HMAC_ReInit(ctx);
#else
if (g_cryptBaseMethod.hmacReinit == NULL) {
return HITLS_CRYPT_ERR_HMAC;
}
return g_cryptBaseMethod.hmacReinit(ctx);
#endif
}
int32_t SAL_CRYPT_HmacUpdate(HITLS_HMAC_Ctx *hmac, const uint8_t *data, uint32_t len)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_HMAC_Update(hmac, data, len);
#else
if (g_cryptBaseMethod.hmacUpdate == NULL) {
return HITLS_CRYPT_ERR_HMAC;
}
int32_t ret = g_cryptBaseMethod.hmacUpdate(hmac, data, len);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_HMAC_UPDATE, ret, BINLOG_ID15073, HITLS_CRYPT_ERR_HMAC);
}
int32_t SAL_CRYPT_HmacFinal(HITLS_HMAC_Ctx *hmac, uint8_t *out, uint32_t *len)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_HMAC_Final(hmac, out, len);
#else
if (g_cryptBaseMethod.hmacFinal == NULL) {
return HITLS_CRYPT_ERR_HMAC;
}
int32_t ret = g_cryptBaseMethod.hmacFinal(hmac, out, len);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_HMAC_FINAL, ret, BINLOG_ID15075, HITLS_CRYPT_ERR_HMAC);
}
#endif
int32_t SAL_CRYPT_Hmac(HITLS_Lib_Ctx *libCtx, const char *attrName,
HITLS_HashAlgo hashAlgo, const uint8_t *key, uint32_t keyLen,
const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_HMAC(libCtx, attrName, hashAlgo, key, keyLen, in, inLen, out, outLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptBaseMethod.hmac == NULL) {
return HITLS_CRYPT_ERR_HMAC;
}
int32_t ret = g_cryptBaseMethod.hmac(hashAlgo, key, keyLen, in, inLen, out, outLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_HMAC, ret, BINLOG_ID15077, HITLS_CRYPT_ERR_HMAC);
}
#ifndef HITLS_TLS_FEATURE_PROVIDER
static int32_t IteratorInit(CRYPT_KeyDeriveParameters *input, uint32_t hmacSize,
uint8_t **iterator, uint32_t *iteratorSize)
{
uint8_t *seed = BSL_SAL_Calloc(1u, hmacSize + input->labelLen + input->seedLen);
if (seed == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15078, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"P_Hash error: out of memory.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return HITLS_MEMALLOC_FAIL;
}
memcpy(&seed[hmacSize], input->label, input->labelLen);
memcpy(&seed[hmacSize + input->labelLen], input->seed, input->seedLen);
int32_t ret = SAL_CRYPT_Hmac(input->libCtx, input->attrName,
input->hashAlgo, input->secret, input->secretLen,
&seed[hmacSize], input->labelLen + input->seedLen, seed, &hmacSize);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15079, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"P_Hash error: iterator init fail, HMAC ret = 0x%x.", ret, 0, 0, 0);
BSL_SAL_Free(seed);
return ret;
}
*iterator = seed;
*iteratorSize = hmacSize + input->labelLen + input->seedLen;
return HITLS_SUCCESS;
}
static int32_t PHashPre(uint32_t *hmacSize, uint32_t *alignLen, uint32_t outLen, HITLS_HashAlgo hashAlgo)
{
*alignLen = outLen;
*hmacSize = SAL_CRYPT_HmacSize(hashAlgo);
if (*hmacSize == 0) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15080, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"P_Hash error: hmac size is zero.", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_HMAC);
return HITLS_CRYPT_ERR_HMAC;
}
if ((outLen % *hmacSize) != 0) {
*alignLen += *hmacSize - (outLen % *hmacSize);
}
return HITLS_SUCCESS;
}
int32_t P_Hash(CRYPT_KeyDeriveParameters *input, uint8_t *out, uint32_t outLen)
{
uint8_t *iterator = NULL;
uint32_t iteratorSize = 0;
uint8_t *data = NULL;
uint32_t alignLen;
uint32_t offset = 0;
uint32_t hmacSize;
int32_t ret = PHashPre(&hmacSize, &alignLen, outLen, input->hashAlgo);
if (ret != HITLS_SUCCESS) {
return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16612, "PHashPre fail");
}
data = BSL_SAL_Calloc(1u, alignLen);
uint32_t srcLen = alignLen;
if (data == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
return RETURN_ERROR_NUMBER_PROCESS(HITLS_MEMALLOC_FAIL, BINLOG_ID15081, "Calloc fail");
}
uint32_t tmpLen = hmacSize;
ret = IteratorInit(input, hmacSize, &iterator, &iteratorSize);
if (ret != HITLS_SUCCESS) {
(void)RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16613, "IteratorInit fail");
goto EXIT;
}
while (alignLen > 0) {
ret = SAL_CRYPT_Hmac(input->libCtx, input->attrName, input->hashAlgo, input->secret, input->secretLen,
iterator, iteratorSize, data + offset, &tmpLen);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15082, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"P_Hash error: produce output data fail, HMAC ret = 0x%x.", ret, 0, 0, 0);
goto EXIT;
}
alignLen -= tmpLen;
offset += tmpLen;
ret = SAL_CRYPT_Hmac(input->libCtx, input->attrName, input->hashAlgo,
input->secret, input->secretLen, iterator, tmpLen, iterator, &tmpLen);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15083, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"P_Hash error: iterator update fail, HMAC ret = 0x%x.", ret, 0, 0, 0);
goto EXIT;
}
}
memcpy(out, data, outLen);
EXIT:
BSL_SAL_ClearFree(iterator, iteratorSize);
BSL_SAL_ClearFree(data, srcLen);
return ret;
}
#endif
int32_t SAL_CRYPT_PRF(CRYPT_KeyDeriveParameters *input, uint8_t *out, uint32_t outLen)
{
if (input->hashAlgo < HITLS_HASH_SHA_256) {
input->hashAlgo = HITLS_HASH_SHA_256;
}
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_PRF(input, out, outLen);
#else
return P_Hash(input, out, outLen);
#endif
}
HITLS_HASH_Ctx *SAL_CRYPT_DigestInit(HITLS_Lib_Ctx *libCtx, const char *attrName, HITLS_HashAlgo hashAlgo)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_DigestInit(libCtx, attrName, hashAlgo);
#else
(void)libCtx;
(void)attrName;
if (g_cryptBaseMethod.digestInit == NULL) {
return NULL;
}
return g_cryptBaseMethod.digestInit(hashAlgo);
#endif
}
HITLS_HASH_Ctx *SAL_CRYPT_DigestCopy(HITLS_HASH_Ctx *ctx)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_DigestCopy(ctx);
#else
if (g_cryptBaseMethod.digestCopy == NULL) {
return NULL;
}
return g_cryptBaseMethod.digestCopy(ctx);
#endif
}
void SAL_CRYPT_DigestFree(HITLS_HASH_Ctx *ctx)
{
if (ctx != NULL) {
#ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_DigestFree(ctx);
#else
if (g_cryptBaseMethod.digestFree == NULL) {
return;
}
g_cryptBaseMethod.digestFree(ctx);
#endif
}
return;
}
int32_t SAL_CRYPT_DigestUpdate(HITLS_HASH_Ctx *ctx, const uint8_t *data, uint32_t len)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_DigestUpdate(ctx, data, len);
#else
if (g_cryptBaseMethod.digestUpdate == NULL) {
return HITLS_CRYPT_ERR_DIGEST;
}
int32_t ret = g_cryptBaseMethod.digestUpdate(ctx, data, len);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_DIGEST_UPDATE, ret, BINLOG_ID15090,
HITLS_CRYPT_ERR_DIGEST);
}
int32_t SAL_CRYPT_DigestFinal(HITLS_HASH_Ctx *ctx, uint8_t *out, uint32_t *len)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_DigestFinal(ctx, out, len);
#else
if (g_cryptBaseMethod.digestFinal == NULL) {
return HITLS_CRYPT_ERR_DIGEST;
}
int32_t ret = g_cryptBaseMethod.digestFinal(ctx, out, len);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_DIGEST_FINAL, ret, BINLOG_ID15092,
HITLS_CRYPT_ERR_DIGEST);
}
#ifdef HITLS_TLS_PROTO_TLS13
uint32_t SAL_CRYPT_DigestSize(HITLS_HashAlgo hashAlgo)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_DigestSize(hashAlgo);
#else
if (g_cryptBaseMethod.digestSize == NULL) {
return 0;
}
return g_cryptBaseMethod.digestSize(hashAlgo);
#endif
}
int32_t SAL_CRYPT_Digest(HITLS_Lib_Ctx *libCtx, const char *attrName,
HITLS_HashAlgo hashAlgo, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_Digest(libCtx, attrName, hashAlgo, in, inLen, out, outLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptBaseMethod.digest == NULL) {
return HITLS_CRYPT_ERR_DIGEST;
}
int32_t ret = g_cryptBaseMethod.digest(hashAlgo, in, inLen, out, outLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_DIGEST, ret, BINLOG_ID15094, HITLS_CRYPT_ERR_DIGEST);
}
#endif
int32_t SAL_CRYPT_Encrypt(HITLS_Lib_Ctx *libCtx, const char *attrName,
const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen,
uint8_t *out, uint32_t *outLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_Encrypt(libCtx, attrName, cipher, in, inLen, out, outLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptBaseMethod.encrypt == NULL) {
return HITLS_CRYPT_ERR_ENCRYPT;
}
int32_t ret = g_cryptBaseMethod.encrypt(cipher, in, inLen, out, outLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_ENCRYPT, ret, BINLOG_ID15096, HITLS_CRYPT_ERR_ENCRYPT);
}
int32_t SAL_CRYPT_Decrypt(HITLS_Lib_Ctx *libCtx, const char *attrName,
const HITLS_CipherParameters *cipher, const uint8_t *in, uint32_t inLen,
uint8_t *out, uint32_t *outLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_Decrypt(libCtx, attrName, cipher, in, inLen, out, outLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptBaseMethod.decrypt == NULL) {
return HITLS_CRYPT_ERR_DECRYPT;
}
int32_t ret = g_cryptBaseMethod.decrypt(cipher, in, inLen, out, outLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_DECRYPT, ret, BINLOG_ID15098, HITLS_CRYPT_ERR_DECRYPT);
}
void SAL_CRYPT_CipherFree(HITLS_Cipher_Ctx *ctx)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_CipherFree(ctx);
#else
if (g_cryptBaseMethod.cipherFree != NULL) {
g_cryptBaseMethod.cipherFree(ctx);
}
#endif
}
HITLS_CRYPT_Key *SAL_CRYPT_GenEcdhKeyPair(TLS_Ctx *ctx, const HITLS_ECParameters *curveParams)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_GenerateEcdhKey(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
&ctx->config.tlsConfig, curveParams);
#else
(void) ctx;
if (g_cryptEcdhMethod.generateEcdhKeyPair == NULL) {
return NULL;
}
return g_cryptEcdhMethod.generateEcdhKeyPair(ctx, curveParams);
#endif
}
void SAL_CRYPT_FreeEcdhKey(HITLS_CRYPT_Key *key)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_FreeKey(key);
#else
if (key != NULL) {
if (g_cryptEcdhMethod.freeEcdhKey == NULL) {
return;
}
g_cryptEcdhMethod.freeEcdhKey(key);
}
#endif
return;
}
int32_t SAL_CRYPT_EncodeEcdhPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_GetPubKey(key, pubKeyBuf, bufLen, usedLen);
#else
if (g_cryptEcdhMethod.getEcdhPubKey == NULL) {
return HITLS_CRYPT_ERR_ENCODE_ECDH_KEY;
}
int32_t ret = g_cryptEcdhMethod.getEcdhPubKey(key, pubKeyBuf, bufLen, usedLen);
#endif
return CheckCallBackRetVal(
HITLS_CRYPT_CALLBACK_GET_ECDH_ENCODED_PUBKEY, ret, BINLOG_ID15102, HITLS_CRYPT_ERR_ENCODE_ECDH_KEY);
}
int32_t SAL_CRYPT_CalcEcdhSharedSecret(HITLS_Lib_Ctx *libCtx, const char *attrName,
HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen,
uint8_t *sharedSecret, uint32_t *sharedSecretLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_EcdhCalcSharedSecret(libCtx, attrName,
key, peerPubkey, pubKeyLen, sharedSecret, sharedSecretLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptEcdhMethod.calcEcdhSharedSecret == NULL) {
return HITLS_CRYPT_ERR_CALC_SHARED_KEY;
}
int32_t ret = g_cryptEcdhMethod.calcEcdhSharedSecret(key, peerPubkey, pubKeyLen, sharedSecret, sharedSecretLen);
#endif
return CheckCallBackRetVal(
HITLS_CRYPT_CALLBACK_CALC_ECDH_SHARED_SECRET, ret, BINLOG_ID15104, HITLS_CRYPT_ERR_CALC_SHARED_KEY);
}
#ifdef HITLS_TLS_PROTO_TLCP11
int32_t SAL_CRYPT_CalcSm2dhSharedSecret(HITLS_Lib_Ctx *libCtx, const char *attrName,
HITLS_Sm2GenShareKeyParameters *sm2ShareKeyParam, uint8_t *sharedSecret, uint32_t *sharedSecretLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_CalcSM2SharedSecret(libCtx, attrName,
sm2ShareKeyParam, sharedSecret, sharedSecretLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptEcdhMethod.sm2CalEcdhSharedSecret == NULL) {
return HITLS_CRYPT_ERR_CALC_SHARED_KEY;
}
int32_t ret = g_cryptEcdhMethod.sm2CalEcdhSharedSecret(sm2ShareKeyParam, sharedSecret, sharedSecretLen);
#endif
return CheckCallBackRetVal(
HITLS_CRYPT_CALLBACK_SM2_CALC_ECDH_SHARED_SECRET, ret, BINLOG_ID16212,
HITLS_CRYPT_ERR_ENCODE_ECDH_KEY);
}
#endif
HITLS_CRYPT_Key *SAL_CRYPT_GenerateDhKeyByParams(HITLS_Lib_Ctx *libCtx,
const char *attrName, uint8_t *p, uint16_t plen, uint8_t *g, uint16_t glen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_GenerateDhKeyByParameters(libCtx, attrName, p, plen, g, glen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptDhMethod.generateDhKeyByParams == NULL) {
return NULL;
}
return g_cryptDhMethod.generateDhKeyByParams(p, plen, g, glen);
#endif
}
HITLS_CRYPT_Key *SAL_CRYPT_GenerateDhKeyBySecbits(TLS_Ctx *ctx, int32_t secBits)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_GenerateDhKeyBySecbits(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
&ctx->config.tlsConfig, secBits);
#else
(void)ctx;
if (g_cryptDhMethod.generateDhKeyBySecbits == NULL) {
return NULL;
}
return g_cryptDhMethod.generateDhKeyBySecbits(secBits);
#endif
}
#ifdef HITLS_TLS_CONFIG_MANUAL_DH
HITLS_CRYPT_Key *SAL_CRYPT_DupDhKey(HITLS_CRYPT_Key *key)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_DupKey(key);
#else
if (g_cryptDhMethod.dupDhKey == NULL) {
return NULL;
}
return g_cryptDhMethod.dupDhKey(key);
#endif
}
#endif
void SAL_CRYPT_FreeDhKey(HITLS_CRYPT_Key *key)
{
if (key != NULL) {
#ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_CRYPT_FreeKey(key);
#else
if (g_cryptDhMethod.freeDhKey == NULL) {
return;
}
g_cryptDhMethod.freeDhKey(key);
#endif
}
return;
}
int32_t SAL_CRYPT_GetDhParameters(HITLS_CRYPT_Key *key, uint8_t *p, uint16_t *plen, uint8_t *g, uint16_t *glen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
return HITLS_CRYPT_GetDhParameters(key, p, plen, g, glen);
#else
if (g_cryptDhMethod.getDhParameters == NULL) {
return HITLS_CRYPT_ERR_DH;
}
return g_cryptDhMethod.getDhParameters(key, p, plen, g, glen);
#endif
}
int32_t SAL_CRYPT_EncodeDhPubKey(HITLS_CRYPT_Key *key, uint8_t *pubKeyBuf, uint32_t bufLen, uint32_t *usedLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_GetPubKey(key, pubKeyBuf, bufLen, usedLen);
#else
if (g_cryptDhMethod.getDhPubKey == NULL) {
return HITLS_CRYPT_ERR_ENCODE_DH_KEY;
}
int32_t ret = g_cryptDhMethod.getDhPubKey(key, pubKeyBuf, bufLen, usedLen);
#endif
return CheckCallBackRetVal(
HITLS_CRYPT_CALLBACK_GET_DH_ENCODED_PUBKEY, ret, BINLOG_ID15110, HITLS_CRYPT_ERR_ENCODE_DH_KEY);
}
int32_t SAL_CRYPT_CalcDhSharedSecret(HITLS_Lib_Ctx *libCtx, const char *attrName,
HITLS_CRYPT_Key *key, uint8_t *peerPubkey, uint32_t pubKeyLen, uint8_t *sharedSecret, uint32_t *sharedSecretLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_DhCalcSharedSecret(libCtx, attrName,
key, peerPubkey, pubKeyLen, sharedSecret, sharedSecretLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptDhMethod.calcDhSharedSecret == NULL) {
return HITLS_CRYPT_ERR_CALC_SHARED_KEY;
}
int32_t ret = g_cryptDhMethod.calcDhSharedSecret(key, peerPubkey, pubKeyLen, sharedSecret, sharedSecretLen);
#endif
return CheckCallBackRetVal(
HITLS_CRYPT_CALLBACK_CALC_DH_SHARED_SECRET, ret, BINLOG_ID15112, HITLS_CRYPT_ERR_CALC_SHARED_KEY);
}
#ifdef HITLS_TLS_PROTO_TLS13
int32_t SAL_CRYPT_HkdfExpand(HITLS_Lib_Ctx *libCtx,
const char *attrName, HITLS_CRYPT_HkdfExpandInput *input, uint8_t *okm, uint32_t okmLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_HkdfExpand(libCtx, attrName, input, okm, okmLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptKdfMethod.hkdfExpand == NULL) {
return HITLS_CRYPT_ERR_HKDF_EXPAND;
}
int32_t ret = g_cryptKdfMethod.hkdfExpand(input, okm, okmLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_HKDF_EXPAND, ret, BINLOG_ID15116,
HITLS_CRYPT_ERR_HKDF_EXPAND);
}
#endif
#ifdef HITLS_TLS_PROTO_TLS13
int32_t SAL_CRYPT_HkdfExtract(HITLS_Lib_Ctx *libCtx,
const char *attrName, HITLS_CRYPT_HkdfExtractInput *input, uint8_t *prk, uint32_t *prkLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_HkdfExtract(libCtx, attrName, input, prk, prkLen);
#else
(void)libCtx;
(void)attrName;
if (g_cryptKdfMethod.hkdfExtract == NULL) {
return HITLS_CRYPT_ERR_HKDF_EXTRACT;
}
int32_t ret = g_cryptKdfMethod.hkdfExtract(input, prk, prkLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_HKDF_EXTRACT, ret, BINLOG_ID15114,
HITLS_CRYPT_ERR_HKDF_EXTRACT);
}
* 2 bytes for length of derived secret + 1 byte for length of combined
* prefix and label + bytes for the label itself + 1 byte length of hash
* + bytes for the hash itself
*/
static int32_t SAL_CRYPT_EncodeHkdfLabel(HkdfLabel *hkdfLabel, uint8_t *buf, uint32_t bufLen, uint32_t *usedLen)
{
char labelPrefix[] = "tls13 ";
size_t labelPrefixLen = strlen(labelPrefix);
uint32_t offset = 0;
BSL_Uint16ToByte(hkdfLabel->length, buf);
offset += sizeof(uint16_t);
* "ext binder", "res binder", "finished", "c e traffic", "e exp master", "derived", "c hs traffic", "s hs traffic"
* "finished", "derived", "c ap traffic", "s ap traffic", "exp master", "finished", "res master",
* "TLS 1.3,serverCertificateVerify", "TLS 1.3,clientCertificateVerify".
*/
buf[offset] = (uint8_t)(hkdfLabel->labelLen + labelPrefixLen);
offset += sizeof(uint8_t);
if (labelPrefixLen > bufLen - offset ) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15117, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Encode HkdfLabel error: memcpy fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
return HITLS_MEMCPY_FAIL;
}
memcpy(&buf[offset], labelPrefix, labelPrefixLen);
offset += (uint32_t)labelPrefixLen;
if (hkdfLabel->labelLen != 0 &&
hkdfLabel->labelLen > bufLen - offset) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15118, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Encode HkdfLabel error: memcpy fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
return HITLS_MEMCPY_FAIL;
}
memcpy(&buf[offset], hkdfLabel->label, hkdfLabel->labelLen);
offset += hkdfLabel->labelLen;
buf[offset] = hkdfLabel->ctxLen;
offset += sizeof(uint8_t);
if (hkdfLabel->ctxLen != 0) {
if (hkdfLabel->ctxLen > bufLen - offset) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15119, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Encode HkdfLabel error: memcpy fail", 0, 0, 0, 0);
BSL_ERR_PUSH_ERROR(HITLS_MEMCPY_FAIL);
return HITLS_MEMCPY_FAIL;
}
memcpy(&buf[offset], hkdfLabel->ctx, hkdfLabel->ctxLen);
offset += hkdfLabel->ctxLen;
}
*usedLen = offset;
return HITLS_SUCCESS;
}
int32_t SAL_CRYPT_HkdfExpandLabel(CRYPT_KeyDeriveParameters *deriveInfo, uint8_t *outSecret, uint32_t outLen)
{
uint8_t hkdfLabel[TLS13_MAX_HKDF_LABEL_LEN] = {0};
uint32_t hkdfLabelLen = 0;
HkdfLabel info = {0};
info.length = (uint16_t)outLen;
info.labelLen = (uint8_t)deriveInfo->labelLen;
info.ctxLen = (uint8_t)deriveInfo->seedLen;
info.label = deriveInfo->label;
info.ctx = deriveInfo->seed;
int32_t ret = SAL_CRYPT_EncodeHkdfLabel(&info, hkdfLabel, TLS13_MAX_HKDF_LABEL_LEN, &hkdfLabelLen);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16626, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"EncodeHkdfLabel fail", 0, 0, 0, 0);
return ret;
}
HITLS_CRYPT_HkdfExpandInput expandInput = {0};
expandInput.hashAlgo = deriveInfo->hashAlgo;
expandInput.prk = deriveInfo->secret;
expandInput.prkLen = deriveInfo->secretLen;
expandInput.info = hkdfLabel;
expandInput.infoLen = hkdfLabelLen;
return SAL_CRYPT_HkdfExpand(deriveInfo->libCtx, deriveInfo->attrName, &expandInput, outSecret, outLen);
}
#endif
#ifdef HITLS_TLS_FEATURE_KEM
int32_t SAL_CRYPT_KemEncapsulate(TLS_Ctx *ctx, HITLS_KemEncapsulateParams *params)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_KemEncapsulate(LIBCTX_FROM_CTX(ctx), ATTRIBUTE_FROM_CTX(ctx),
&ctx->config.tlsConfig, params);
#else
(void)ctx;
(void)params;
if (g_cryptEcdhMethod.kemEncapsulate == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16627, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"kemEncapsulate callback not registered", 0, 0, 0, 0);
return HITLS_UNREGISTERED_CALLBACK;
}
int32_t ret = g_cryptEcdhMethod.kemEncapsulate(params);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_KEM_ENCAPSULATE, ret, BINLOG_ID16617,
HITLS_CRYPT_ERR_KEM_ENCAPSULATE);
}
int32_t SAL_CRYPT_KemDecapsulate(HITLS_CRYPT_Key *key, const uint8_t *ciphertext, uint32_t ciphertextLen,
uint8_t *sharedSecret, uint32_t *sharedSecretLen)
{
#ifdef HITLS_TLS_FEATURE_PROVIDER
int32_t ret = HITLS_CRYPT_KemDecapsulate(key, ciphertext, ciphertextLen, sharedSecret, sharedSecretLen);
#else
if (g_cryptEcdhMethod.kemDecapsulate == NULL) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16630, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"kemDecapsulate callback not registered", 0, 0, 0, 0);
return HITLS_UNREGISTERED_CALLBACK;
}
int32_t ret = g_cryptEcdhMethod.kemDecapsulate(key, ciphertext, ciphertextLen, sharedSecret, sharedSecretLen);
#endif
return CheckCallBackRetVal(HITLS_CRYPT_CALLBACK_KEM_DECAPSULATE, ret, BINLOG_ID16637,
HITLS_CRYPT_ERR_KEM_DECAPSULATE);
}
#endif