* 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 <string.h>
#include "hitls_build.h"
#include "tls_binlog_id.h"
#include "bsl_log_internal.h"
#include "bsl_log.h"
#include "bsl_err_internal.h"
#include "bsl_sal.h"
#include "hitls_error.h"
#include "transcript_hash.h"
int32_t VERIFY_SetHash(HITLS_Lib_Ctx *libCtx, const char *attrName, VerifyCtx *ctx, HITLS_HashAlgo hashAlgo)
{
int32_t ret;
HITLS_HashAlgo prfAlgo = (hashAlgo == HITLS_HASH_SHA1) ? HITLS_HASH_SHA_256 : hashAlgo;
SAL_CRYPT_DigestFree(ctx->hashCtx);
ctx->hashCtx = SAL_CRYPT_DigestInit(libCtx, attrName, prfAlgo);
if (ctx->hashCtx == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15716, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Verify set hash error: digest init fail.", 0, 0, 0, 0);
return HITLS_CRYPT_ERR_DIGEST;
}
HsMsgCache *dataBuf = ctx->dataBuf;
while ((dataBuf != NULL) && (dataBuf->dataSize > 0u)) {
ret = SAL_CRYPT_DigestUpdate(ctx->hashCtx, dataBuf->data, dataBuf->dataSize);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15717, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Verify set hash error: digest update fail.", 0, 0, 0, 0);
SAL_CRYPT_DigestFree(ctx->hashCtx);
ctx->hashCtx = NULL;
return ret;
}
dataBuf = dataBuf->next;
}
ctx->hashAlgo = prfAlgo;
return HITLS_SUCCESS;
}
static HsMsgCache *GetLastCache(HsMsgCache *dataBuf)
{
HsMsgCache *cacheBuf = dataBuf;
while (cacheBuf->next != NULL) {
cacheBuf = cacheBuf->next;
}
return cacheBuf;
}
static int32_t CacheMsgData(HsMsgCache *dataBuf, const uint8_t *data, uint32_t len)
{
HsMsgCache *lastCache = GetLastCache(dataBuf);
lastCache->next = BSL_SAL_Calloc(1u, sizeof(HsMsgCache));
if (lastCache->next == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15718, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"malloc HsMsgCache fail when append msg.", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
BSL_SAL_FREE(lastCache->data);
lastCache->data = BSL_SAL_Dump(data, len);
if (lastCache->data == NULL) {
BSL_SAL_FREE(lastCache->next);
BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15719, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"malloc HsMsgCache data fail when append msg.", 0, 0, 0, 0);
return HITLS_MEMALLOC_FAIL;
}
lastCache->dataSize = len;
return HITLS_SUCCESS;
}
int32_t VERIFY_Append(VerifyCtx *ctx, const uint8_t *data, uint32_t len)
{
int32_t ret;
if (ctx->hashCtx != NULL) {
ret = SAL_CRYPT_DigestUpdate(ctx->hashCtx, data, len);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15720, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Verify append error: digest update fail.", 0, 0, 0, 0);
return ret;
}
}
if (ctx->dataBuf != NULL) {
return CacheMsgData(ctx->dataBuf, data, len);
}
return HITLS_SUCCESS;
}
int32_t VERIFY_CalcSessionHash(VerifyCtx *ctx, uint8_t *digest, uint32_t *digestLen)
{
int32_t ret;
HITLS_HASH_Ctx *tmpHashCtx = SAL_CRYPT_DigestCopy(ctx->hashCtx);
if (tmpHashCtx == NULL) {
BSL_ERR_PUSH_ERROR(HITLS_CRYPT_ERR_DIGEST);
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15721, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Verify data calculate error: digest copy fail.", 0, 0, 0, 0);
return HITLS_CRYPT_ERR_DIGEST;
}
ret = SAL_CRYPT_DigestFinal(tmpHashCtx, digest, digestLen);
SAL_CRYPT_DigestFree(tmpHashCtx);
if (ret != HITLS_SUCCESS) {
BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15722, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
"Verify data calculate error: digest final fail.", 0, 0, 0, 0);
}
return ret;
}
void VERIFY_FreeMsgCache(VerifyCtx *ctx)
{
HsMsgCache *nextBuf = NULL;
HsMsgCache *dataBuf = ctx->dataBuf;
while (dataBuf != NULL) {
nextBuf = dataBuf->next;
BSL_SAL_FREE(dataBuf->data);
BSL_SAL_FREE(dataBuf);
dataBuf = nextBuf;
}
ctx->dataBuf = NULL;
}